tags:

views:

108

answers:

3

It reports An invalid handle was specified. for the code below:

 if(hPipe)
  CloseHandle(hPipe);

What can I do?

+1  A: 

This implies that either hPipe is not initialized to a valid pipe handle, or it was valid but has already been closed. Double check your logic related to this variable.

Steve Townsend
But how to check?
COMer
@COMer: You can't. Just keep track of whether the handle has been initialized to a valid value or not.
Billy ONeal
Can you post it as an answer with some clarifying code?
COMer
+3  A: 
 if (hPipe != INVALID_HANDLE_VALUE && hPipe != 0)
     CloseHandle(hPipe);

INVALID_HANDLE_VALUE is -1, not 0, so you can't just do if(hPipe). 0 is also an invalid handle value, so you can't just check against INVALID_HANDLE_VALUE and be done. Don't you love win32?

Zack
COMer
@Zack: Actually, any handle which has not be generated by something that generates handles is an invalid handle. Those two values are common return values from functions, but that doesn't mean they have magical special treatment by Win32.
Billy ONeal
+3  A: 

I suspect you have something like this:

class SmartPipe
{
    HANDLE hPipe;
public:
    //Functions which do something to hPipe
    ~SmartPipe()
    {
        if (hPipe)
            CloseHandle(hPipe);
    }
};

The problem is that when SmartPipe is created, hPipe is initialized to random garbage. You have to initialize it yourself. Add hPipe to an initializer list in your class:

class SmartPipe
{
    HANDLE hPipe;
public:
    SmartPipe() : hPipe(0)
    {
    }
    //Functions which do something to hPipe
    ~SmartPipe()
    {
        if (hPipe)
            CloseHandle(hPipe);
    }
};

If this is not your scenario, at least check that hPipe is getting initialized somewhere, even if the value it is being set to is 0.

EDIT: This is a double free scenario:

class SmartPipe
{
//As above
};

void SomeFunc(SmartPipe input) //Note pass by value
{  //At this point, the pipe object was copied
   //2 SmartPipes are alive with the same handle value here.
   //Do something with `input`
}

int main()
{
    SmartPipe input;
    //setup input somehow
    SomeFunc(input);
    //Note that at this point the pipe passed by value has already been
    //destroyed, and the handle held by `input` has already been closed.
} //`input` destroyed here, resulting in a double free.

Solve that by making SmartPipe noncopyable, or writing copy constructors and copy assignment operators for it which copy the handle (Using something like DuplicateHandle), or reference counting.

Billy ONeal
I've already initialized `hPipe` to `NULL` in my code.BTW,what is a "First-chance" exception in the first place?
COMer
@Billy ONeal: +1. I have also checked with the OP about if there is a possibility of 'double Close'
Chubsdad
@Chubsdad (Possible double free scenario) @COMer: Is `hPipe` part of a class that gets copied using the compiler supplied copy constructor? If so, the destructor would run on the same handle value twice.... Perhaps you should write the copy constructor and copy assignment operator, or make your class noncopyable.
Billy ONeal
Refer http://support.microsoft.com/kb/105675. Basically under debugger, the debugger gets the first chance to handle any run time exception for which it is configured to handle an exception before allowing the application being debugged to handle the exception.
Chubsdad
`hPipe` is created in the constructor of a COM device, and closed in the destructor .I've no idea how 3rd party programs use it.
COMer
@COMer: See my edit.
Billy ONeal
Somehow it doesn't happen now though I didn't change anything ,but I think it's not a bad idea to mark it as accepted.
COMer