Why am I getting a crash using QTextStream on an open FILE * - c++

I'm on windows, qt 4.7. part of my code takes a FILE* from a file which is open for reading by another part of the system (legacy, C). I open a QTextStream as follows:
// file currently opened (readonly), and partially read
FILE *infile = function_to_get_file_pointer();
QTextStream is(infile, QIODevice::ReadOnly);
The second line crashes when built in release mode but is fine in debug. I can step through the debug version and see the QFile that is opened internally by QTextStream.
The most I've managed to get out of the windows call stack in release mode at the time of the crash is below:
ntdll.dll!77450226()
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
ntdll.dll!77450142()
msvcr80.dll!_lock_file(_iobuf * pf=0x71962148) Line 241 + 0xa bytes C
msvcr80.dll!_ftelli64(_iobuf * stream=0x71962148) Line 51 + 0x8 bytes C
QtCore4.dll!6708b87d()
QtCore4.dll!67099294()
QtCore4.dll!6713d491()
which could be a red herring but look like something's gone wrong trying to lock the file. Prior to this, I have enabled debug output for my code so I know that it is the QTextStream creation that is causing the problem.
I welcome any suggestions!
After some further digging, I have found that the file, although ASCII, is originally fopened with "rb" in order to stop the win32 CRT converting line endings from \r\n to \n.
I assumed this would be confusing Qt so modified the fopen to use "r" only. Then a comment below linked to here which shows that the FILE* should be opened in binary mode, e.g. "rb", so this is not a problem.
Trying tezrigs suggestion below, freopen on the FILE* gives the following:
msvcr100.dll!_crt_debugger_hook(int _Reserved=8633404) Line 65 C
msvcr100.dll!_call_reportfault(int nDbgHookCode=2, unsigned long dwExceptionCode=3221226519, unsigned long dwExceptionFlags=1) Line 167 + 0x6 bytes C++
msvcr100.dll!_invoke_watson(const wchar_t * pszExpression=0x00000000, const wchar_t * pszFunction=0x00000000, const wchar_t * pszFile=0x00000000, unsigned int nLine=0, unsigned int pReserved=8633376) Line 155 + 0xf bytes C++
msvcr100.dll!_invalid_parameter(const wchar_t * pszExpression=0x00000000, const wchar_t * pszFunction=0x00000000, const wchar_t * pszFile=0x00000000, unsigned int nLine=0, unsigned int pReserved=0) Line 110 + 0x14 bytes C++
msvcr100.dll!_invalid_parameter_noinfo() Line 121 + 0xc bytes C++
msvcr100.dll!_freopen_helper(_iobuf * * pfile=0x0083bc3c, const char * filename=0x00000000, const char * mode=0x013ee350, _iobuf * str=0x71962148, int shflag=64) Line 31 + 0x1f bytes C
msvcr100.dll!freopen(const char * filename=0x00000000, const char * mode=0x013ee350, _iobuf * str=0x71962148) Line 111 C
The exception code passed to _call_report_fault is 0x0000417 - Fatal Error: Unknown Software Exception, which isn't much help..
OK: more detail, and some self contained, replicable code (myfile.txt must be over 1000 chars long):
#include <QtCore/QCoreApplication>
#include "qtextstream.h"
#include <iostream>
int main(int argc, char *argv[])
{
// QCoreApplication a(argc, argv);
std::cin.get();
FILE *myfile = fopen("myfile.txt", "rb");
int c;
for(int i=0; i < 1000; i++)
c = getc(myfile);
fflush(myfile);
long pos = ftell(myfile);
QTextStream is(myfile, QIODevice::ReadOnly);
while(!is.atEnd())
{
QString in_line = is.readLine();
std::cout << in_line.toStdString();
}
fseek(myfile, pos, SEEK_SET);
fclose(myfile);
return 0;
}
All the following in release mode:
This lets me attach a debugger if I run outside visual studio. If I run in outside visual studio, it crashes.
If I attach to it once it has started from outside visual studio, it crashes on construction of QTextStream.
If I start it from inside visual studio with shift-F5 (i.e. running outside the debugger) it writes the contents of the file to the display.
likewise, when running under the debugger, it works as expected.
It is down to the dlls. I have a locally compiled set of dlls (created with MSVC2010) and using them to replace those in the main product solves the problem. Ditto with the test code. The release code was using Qt compiled with 2005, using msvcr80.

All credit to #KarstenKoop - feel free to post your answer here. The problem was due to Qt dlls that were using msvcr80.dll while the rest of the application was compiled using visual studio 2010 and thus using msvcr100.dll
This link explains the perils of mixing visual studio versions quite nicely

Related

C++ code is running in Windows 7 but not in windows 10

I have a c++ code running in windows 7 but not works in windows10. It is working in MAC/LINUX.
I am trying to parse a large hex file. My code loads in to array and then applies the business logic to generate the csv.
The size of the file is 2.38GB.
Below is the code.
bool readFile (string filename, char ** buffer ,unsigned int & sizeOfFile )
{
ifstream inFile (filename.c_str (), ios::in | ios::binary);
if (!inFile)
return false;
inFile.seekg (0, ios::end);
size_t size = inFile.tellg ();
inFile.seekg (0, ios::beg);
*buffer = new char[size];
cout<<"\n Length of the ARRAY= "<<size;
inFile.read (*buffer, size);
inFile.close ();
sizeOfFile = size;
cout<<"File successfully read Press Any Key to Continue.. "<<endl;
//getch();
return true;
}
It is failing to load the file into array when I execute it in windows 10 under visual studio 2015 as well as under dev c++. It works perfectly in windows 7.
Wouldn't it be easier to use file mapping?
https://msdn.microsoft.com/en-us/library/windows/desktop/aa366556(v=vs.85).aspx
EDIT:
You mention below that you are using the same code on macOS and Linux. I'm more familiar with these platforms, where I would use mmap(). Effectively this automates the loading of data from the file to memory.
Otherwise, as mentioned above, you need to provide more information on the nature of the problem (32 or 64bit build, type of failure).
size_t size = inFile.tellg ();
...
*buffer = new char[size];
Looks like you're not creating a large enough space for the whole file to be read in. If the file were 10 bytes in size, you'd need to allocate 11 bytes as the null-terminated string needs an extra character at the end to store the '\0' character to terminate it. The fact that it works on some systems, but not others is pure luck as it means that on those systems there happened to be a NUL character at the right point in memory to properly terminate the string.

Multithread Access violation reading location C++

I have an C++ application that has a main thread and a Poco::Timer to trigger a callback which writes to a file using Poco::FileOutputStream:
FileOutputStream file("test.txt", ios::binary); <-- *Access violation reading location here*
file.write(reinterpret_cast<char *>(&data), sizeof(data));
file.close();
The code always failed at the first line, here is the call stack:
testProject.exe!std::ctype::widen(char _Byte=' ') Line 1716 + 0xf bytes C++
testProject.exe!std::basic_ios >::widen(char _Byte=' ') Line 126 C++
testProject.exe!std::basic_ios >::init(std::basic_streambuf > * _Strbuf=0x038ef700, bool _Isstd=false) Line 135 + 0xa bytes C++
testProject.exe!std::basic_ostream >::basic_ostream >(std::basic_streambuf > * _Strbuf=0x038ef700, bool _Isstd=false) Line 54 C++
testProject.exe!Poco::FileOutputStream::FileOutputStream(const std::basic_string,std::allocator > & path="c:\Projects\TestProject\test.txt", int mode=32) Line 93 + 0xa3 bytes C++
testProject.exe!OPC_Server::OnTimer(Poco::Timer & timer={...}) Line 3656 + 0x13 bytes C++
testProject.exe!Poco::TimerCallback::invoke(Poco::Timer & timer={...}) Line 212 + 0x14 bytes C++
testProject.exe!Poco::Timer::run() Line 197 + 0x19 bytes C++
testProject.exe!Poco::PooledThread::run() Line 200 + 0x15 bytes C++
testProject.exe!Poco::`anonymous namespace'::RunnableHolder::run() Line 57 + 0x17 bytes C++
testProject.exe!Poco::ThreadImpl::runnableEntry(void * pThread=0x00db6afc) Line 207 + 0x20 bytes C++
testProject.exe!_callthreadstartex() Line 348 + 0xf bytes C
testProject.exe!_threadstartex(void * ptd=0x00db6d00) Line 331 C
Tracing into the stack, the timer thread seemed having problem reading the initialization _Byte at the top of the call stack in xlocale internal header:
_Elem __CLR_OR_THIS_CALL widen(char _Byte) const
{ // widen char
return (do_widen(_Byte)); <-- failed: Access violation reading location
}
Second entry in the stack in ios standard header:
_Elem __CLR_OR_THIS_CALL widen(char _Byte) const
{ // convert _Byte to character using imbued locale
const _Ctype& _Ctype_fac = _USE(getloc(), _Ctype);
return (_Ctype_fac.widen(_Byte)); <-- call the top of the stack
}
Third entry in the stack in ios standard header:
protected:
void __CLR_OR_THIS_CALL init(_Mysb *_Strbuf = 0,
bool _Isstd = false)
{ // initialize with stream buffer pointer
_Init(); // initialize ios_base
_Mystrbuf = _Strbuf;
_Tiestr = 0;
_Fillch = widen(' '); <-- call the second entry
But very strangely, the same code runs fine without any error when being used on the main thread.
Is there any permission settings that I need to set for the Poco::Timer to be able to function properly? Or am I missing something very obvious? Thanks for any help.
EDIT: ----------------------
Poco version: 1.7.3
Platform: windows
It turns out that the application exits immediately after the timer is created, but the exit is not cleanly done so it appears that the app is still running and the timer is still ticking, when actually some of the resource has already been released, which causes the error.
MS's _tmain() does something extra than main() apparently.
Sorry it is not _tmain(), but _tmainCRTStartup that is calling _tmain(). When _tmain() exits, other clean up code is run, my project isn't terminated somehow and the application appears still "running".

Libtiff's TIFFOpenW throws exception

I'm using LibTiff v4.0.3.
I had it working perfectly in multibyte, but when i try to work with Unicode, I get a runtime exception.
I can render the problem down to a single line:
#include "tiffio.h"
int _tmain(int argc, _TCHAR* argv[])
{
TIFF* tif = TIFFOpenW(L"D:\\Myfile", "r");
}
And this will work perfectly: TIFF* tif = TIFFOpen("D:\\Myfile", "r");
I can't get the exact exception code, but the code stack looks like this:
msvcr110.dll!__crt_debugger_hook(int _Reserved) Line 60 C
msvcr110.dll!_call_reportfault(int nDbgHookCode, unsigned long dwExceptionCode, unsigned long dwExceptionFlags) Line 155 C++
msvcr110.dll!_invoke_watson(const wchar_t * pszExpression, const wchar_t * pszFunction, const wchar_t * pszFile, unsigned int nLine, unsigned __int64 pReserved) Line 139 C++
msvcr110.dll!_invalid_parameter(const wchar_t * pszExpression, const wchar_t * pszFunction, const wchar_t * pszFile, unsigned int nLine, unsigned __int64 pReserved) Line 85 C++
msvcr110.dll!_invalid_parameter_noinfo() Line 97 C++
msvcr110.dll!_read(int fh, void * buf, unsigned int cnt) Line 84 C
ConsoleApplication1.exe!TIFFFdOpen() C
ConsoleApplication1.exe!TIFFClientOpen() C
ConsoleApplication1.exe!TIFFFdOpen() C
ConsoleApplication1.exe!TIFFOpenW() C
ConsoleApplication1.exe!wmain(int argc, wchar_t * * argv) Line 21 C++
ConsoleApplication1.exe!__tmainCRTStartup() Line 533 C
ConsoleApplication1.exe!wmainCRTStartup() Line 377 C
kernel32.dll!BaseThreadInitThunk() Unknown
ntdll.dll!RtlUserThreadStart() Unknown
I've tried using #err and #err,hr , but they show that there was no error.
How can I get the Unicode version to work ? Do I need to compile the library differently?
(I've checked and there's no check for the preprocessor variable UNICODE in libtiff....)
Turns out you need to compile the library a bit differently when linking to debug mode project in Unicode.
Go to your libtiff folder, and open nmake.opt for editing.
Change the compilation flags to use debug CRT dlls (/MDd):
OPTFLAGS = /Ox /MDd /EHsc /W3 /D_CRT_SECURE_NO_DEPRECATE
instead of just /MD
Now rebuild the library.
"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\vcvars32.bat" x86
nmake /f makefile.vc [clean]
or for x64:
"C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\amd64\vcvars64.bat" amd64
nmake /f makefile.vc [clean]
Make sure your project links to that file when you're in the debug configuration

Where to put my files for ifstream and fstream

My application returns 0x3 and crashes. I found that it maybe that fstream cannot open the file. Where it should be? I mean, same folder as the application.exe or elsewhere? I am using Code::Blocks
EDIT
Code::Blocks is setting the working directory with the cb runner
GLuint sh;
int meret;
char * s;
std::ifstream fa1 ("vertex.vert",std::ios_base::binary);
fa1.seekg(0, fa1.end);
meret = fa1.tellg();
fa1.seekg(0, fa1.beg);
fa1.read(s,meret);
fa1.close();
//sh = glCreateShader(st);
const char * s1[1] = {s};
std::cout << s;
I think your problem is this line:
fa1.read(s,meret);
Since you've not allocated any space for the array s, attempting to write to it will be bad.
s = new char[ meret ];
Just before the read might fix your issue, as long as the file isn't too big...
NB: you don't need to manually close the ifstream object - it will close when it goes out of scope.

How to get the bytes of a file?

Simple question I know, what I want to do is be able to get the bytes of a file to use to add those bytes to an bit array, which I can then use to write to a file named bytes.exe and launch it. I know how to read the bytes of an existing file at runtime. But I don't know how to get the bytes of a file to copy and paste into my bitarray[] at design time.
The goal is to be able to write the bites of bitarray[] to myfile.exe at runtime, and then launch said file. There are many bitarray[]'s I'll be using, based on many different file types, so I'm looking for an easy method.
Is there some kind of decompiler that should be used? I just looked into resource scripts, but I don't want to attach any dependencies to my main .exe.
If you are targeting Windows, the easiest way to do this is to embed myfile.exe as a resource, then load the resource at runtime and create a file and write the contents of the resource to your new file.
If you can't use resources, then you'll need to create a source file (.c or .h) that initializes a byte array with the contents of myfile.exe and include that as part of your build. Check out this answer for one possible approach:
https://stackoverflow.com/a/73653/333127
EDIT: After further review, I don't think the source code in the link I referenced above will work for binary input files. Here's a quick alternative I just threw together:
#include <stdio.h>
#include <stdlib.h>
#define BYTES_PER_LINE 70
int main(int argc, char* argv[])
{
FILE* fp;
int ch;
int numBytes = 0;
if (argc < 2) {
printf("Usage: tobytes <file>\n");
exit(1);
}
fp = fopen(argv[1], "rb");
if (fp == NULL) {
printf("Cannot open file %s\n", argv[1]);
exit(1);
}
printf("char fileContents[] = {\n");
while ((ch = fgetc(fp)) != EOF) {
if (numBytes > 0)
printf(",");
++numBytes;
if (numBytes % BYTES_PER_LINE == 0)
printf("\n");
printf("0x%x", ch);
}
printf("\n};\n");
fclose(fp);
return 0;
}
It's not 100% clear what you want to do, but why not write a small program that reads a file and translates it into a C array.
That is if the file data is:
01 02 03 04 (binary)
The program will generate a file that is:
char data[] = {0x01, 0x02, 0x03, 0x04};
and then run this program as a prebuild step of your application (in your Makefile or whatever build system you are using), and generate the output into your source tree.
In that way the data would be compiled into your application and be available statically.
As I said, I'm not clear if this is the problem you are trying to solve.