Sign in to follow this  
Kincaid

Error 6: invalid handle (GetLastError)

Recommended Posts

Hello, I have a c++ program which starts with; int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { Identify_Error ( ); .... .... .... Identify_Error() simply calls GetLastError() and translates the error. this gives me the message "Failed; error 6, the handle is invalid" Since its the first line, i have no clue as where to start to debug. Who know what the heck this is?? something wrong with the instance?? thanx in advance

Share this post


Link to post
Share on other sites
Well, I could be wrong here but I'm pretty sure that GetLastError only returns meaningful information when a previous function call has called SetLastError for the thread, so calling GetLastError as the first function in a program would return a meaningless result.

Are you actually experiencing some kind of error that caused you to put this call in as the first line of your program? If so, the only place SetLastError could have been called previously would be in the mysterious sequence of functions that get called before WinMain, in which case something is very badly wrong indeed somewhere.

What is the problem that prompted you to check for an error here? What happens if you just comment this line out?

Share this post


Link to post
Share on other sites
Well, nothing specific that makes me put the call there, just debugging curiosity
I always just put the call from beginning to end in the program to make sure everything's error free.

But is is a large program, and many stuff is declared.
So could the error come from something that's just defined ??

I do have #includes of my own in there (class definitions etc)

oh, and the program runs just fine, except for some bugs of my own :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Kincaid
So could the error come from something that's just defined ??
Globals are initialised before main is called, so yes it could. Code in the constructor of a global object (or possibly in a static object) is run before main.
An error could be happening there.
Try putting breakpoints at the start of main and at the start of your constructors and then see which ones are called before main is called. Step through those ones and see where they might be going wrong.

Share this post


Link to post
Share on other sites
Ok, that explaines a lot

Ive added debug calls in all constructors which notify me of where we are in the program and what the last error is.

Ther error changes in error 1813: specified resource type cannot be found in image


Ive checked all my resource symbols, and that they are in use. I've checked that only used dialogs are present in the resource editor.
What else could it be??

the weird thing is though. If i call GetLastError in all constructors, the error stays 1813, also in the call in WinMain (1st line)
But if that call is the only one ( so just a call at the start of WinMain ) the error becomes error 6: invalid handle again

I'll post my Identify_Error here, maybe that explain this

void Identify_Error (bool close)
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();

FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );

lpDisplayBuf = LocalAlloc(LMEM_ZEROINIT,
(sizeof(lpMsgBuf)+40)*sizeof(TCHAR));
wsprintf((char*)lpDisplayBuf,
TEXT(" failed with error %d: %s"),
dw, lpMsgBuf);
MessageBox(NULL, (LPTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);

LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
if(close)
ExitProcess(dw);
}


Thanx

Share this post


Link to post
Share on other sites
I can't imagine there is any problem with your Identify_Error code since a check here confirms you have the correct error message for the code.

Can you use the debugger to identify exactly when the error code gets set to this value?

Another thing to try would be to compile a skeletal Windows app that does nothing except call GetLastError and output in a message box to see if it is "normal" for there to be an error code when a windows app starts. It may be (and this is just guessing) that in the set up process, windows does something like:

if(GetApplicationHandleThisWay()==true) // ...
else GetApplicationHandleAnotherWay();

which causes the error to be set, although as I say I am speculating wildly there. What I mean is that it could be normal for a Windows app to start with a non-zero value in the error code, depending on what Windows does prior to calling WinMain.

If a skeletal app starts with an error code of zero, then at least you can gradually add in the other code your app contains that would cause constructors to be called prior to WinMain and look to see when the code changes.

Then again, if it isn't actually causing any visible errors in your apps behaviour, you could just not worry about it [smile]. This is an interesting topic though.

[EDIT] Out of curiosity, I just compiled this:


#include <windows.h>
#include <stdio.h>

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
DWORD D=GetLastError();

char b[1024]; sprintf(b,"%d",int(D));

MessageBox(NULL,b,"",MB_OK);

return 0;
}



and it output "0", so I guess that confirms that something in your pre-WinMain code is causing the error.

[Edited by - EasilyConfused on September 8, 2006 7:04:12 AM]

Share this post


Link to post
Share on other sites
hmmm, that will take al lot of debugging, which im not gonna do now :)
I'll just ignore it, since everything runs perfectly.
But I would like to know a little more about which errors are okay to ignore and which are not.
Who sensitive is GetLastError() anyway??

Thanx for you help

Share this post


Link to post
Share on other sites
Just so you know, getlasterror could also return non-error informational messages.

Perhaps an internal call accessing the second HINSTANCE in the WinMain parameters is zero, so for informational purposes it says that the handle is invalid. I mean, that could be from any call.

Share this post


Link to post
Share on other sites
As EasilyConfused mentioned, the return value of GetLastError is undefined except immediately after calling an API that is documented as setting the last error, and even then only under certain conditions (usually failure). In a way, the fact that you are calling GetLastError at essentially a random time is itself a bug.

There is a ton of stuff that happens before WinMain gets called. Globals must be initialized as was mentioned. The C/C++ runtime also has to initialize itself. There are also more fundamental things such as locating and loading any DLL's that you have linked to (including system DLL's that essentially all apps use). These DLL's in turn may link to other DLL's and the whole lot of them have to initialize.

Your error 6 could be caused anywhere in the mess, or it could even be a garbage value left over from some bookkeeping early in the loading process that is entirely unrelated to last errors. It doesn't really matter.

Share this post


Link to post
Share on other sites
Dont check GetLastError() unless you are certain that a Win32 call has failed. And if you are certain of that then check GetLastError() then. This function has only a limited scope of use. For example, consider the following


BitBlt(...write to memory DC...);
BitBlt(...write memory DC to window...);


If the first BitBlt() call fails then it will set GetLastError() to the appropriate message. A success in the next call to BitBlt() might overwrite that error causing GetLastError() to return success.

If no Win32 functions have been called when you call GetLastError(), then the function's result is undefined.

In short, only check get last error when and where you know something has failed.

Share this post


Link to post
Share on other sites
One reason I've seen invalid handle is when you or the system is trying to write debugger messages and a debugger is not attached. Some libraries and tools (such as profiling tools) will call API functions before and after a function is called.


You really should be using it differently. After an API function fails, immediately call GetLastError() and store the result, then only use the stored value. You can pass the stored value to your Identify_Error() function. Alternatively, you might use Identify_Error( GetLastError() );

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this