Why i get segmentation fault in the following code ?
-
My Code:
void EyeCare::on_startcaringButton_clicked() { QErrorMessage *errorMessage = new QErrorMessage ; errorMessage->showMessage(GetLastErrorString ()); } QString EyeCare::GetLastErrorString() { DWORD error = GetLastError(); if (error) { LPTSTR errorMessage; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER,NULL, error,0,(LPWSTR) &errorMessage,0, NULL ); return QString :: fromWCharArray(errorMessage) ; } }
-
You should post the stack trace from the crash.
-
is errorMessage null or invalid when you pass it to fromWCharArray?
LPTSTR errorMessage =NULL; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER,NULL, error,0,(LPWSTR) &errorMessage,0, NULL ); Q_ASSERT(errorMessage); return QString :: fromWCharArray(errorMessage) ;
-
Hi
running your GetLastErrorString()
in win 10, mingw compiler, Qt5.7, it does not crash. -
@mrjj i have windows 7 32bit Qt5.7 MinGW
did you checked it ?? and GetLastErrorString is not an inbuilt function i created on my own for the purpose of getting the details of the error message with the help of error code returned by GetLastError ( which infact an inbuilt function ). -
Not sure if this is a problem but the variable 'errorMessage' is type LPTSTR but cast to LPWSTR in the function FormatMessage(...).
If 'DWORD error' is null then nothing is returned from this function; it should return a QString in any case. Not returning an expected return type will probably crash the program (and should generate a warning message during compilation).
-
@Rondog said:
the variable 'errorMessage' is type LPTSTR but cast to LPWSTR in the function FormatMessage(...)
The cast is necessary, because he's using
FORMAT_MESSAGE_ALLOCATE_BUFFER
, in which case thelpBuffer
parameter (errorMessage
in this case) is interpreted not as anLP...
, but a pointer to anLP...
(ie that flags causes the function to interpret the parameter as something other than what the function signature says... love win32).Having said that, the cast is wrong (probably benign though)... it should be a cast to
LPTSTR
, notLPWSTR
- but whether that matters or not depends on whether the Microsoft headers are set to Unicode verses non-Unicode mode. Assuming the compiler isn't complaining about the cast, and well as the use ofQString::fromWCharArray
without a cast, he's probably using Unicode mode, in which case the Microsoft headers defineLPTSTR
asLPWSTR
anyway, but still not good practice.So, just adding what's already been said:
EyeCare::GetLastErrorString
should always return a value (not sure that would cause a crash though - I would have thought a default-constructedQString
would be returned instead, but always better to be explicit);- you should check the result of the
FormatMessage
(if its0
, thenerrorMessage
is likely to be an invalid random dangling pointer); - you should definitely initialise
errorMessage
toNULL
, otherwise there's no way to distinguish betweenFormatMessage
failing pre-allocating versus failing post-allocating. - (for later) you should be creating the return
QString
, then freeingerrorMessage
, then returning; otherwise you have a memory leak.
I'd do something like:
QString EyeCare::GetLastErrorString() { QString message = QString::fromLatin1("no error"); // Or empty string if you prefer. const DWORD error = GetLastError(); if (error != ERROR_SUCCESS) // I just like to be explicit. { // Fetch the error message. LPTSTR errorMessage = NULL; const DWORD size = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER,NULL, error,0,(LPTSTR) &errorMessage,0, NULL ); // Copy the error message to a QString object. if (size > 0) { #ifdef UNICODE message = QString::fromWCharArray(errorMessage, size); #else message = QString::fromLocal8Bit(errorMessage, size); #endif } // Free the error message buffer. if (errorMessage != NULL) { HeapFree(GetProcessHeap(), errorMessage); } } return message; }
Cheers.
-
Just use qt_error_string() function instead.
-
Getting the following error now: :
-
its an image it seems
0_1472284308498_sending.JPG
(/uploads/files/1472284318241-sending-resized.jpg)
Might be forum bug. An update is coming afaik, so lets see.