But I can not produce this phenomenon intentionally.
Try rebuilding your project with all optimizations and inlining turned off... see if it still happens.
See if it still happens when the code includes debugging symbols.
If you can't isolate it and reproduce it, it might be that something is not exiting normally... which can cause Windows to skip the cleanup steps... which is where Structured Exception Handling comes in very handy...
Here's an example of code using SEH to guarantee a cleanup if things go wrong... It works with the Error-X library I suggested earlier, take a close look at the try{}finally{} construct. This forces a cleanup if there's an error. The Exception() function is from Error-X and forces an exception to occur.
/ open and translate file
BOOL M3ULaunch(PWCHAR FileName)
{ PBYTE rf; // raw file data
DWORD br; // bytes read
// load the raw file
{ HANDLE pl; // playlist file handle
DWORD fs; // file size
// get path to file
wcsncpy(FilePath,FileName,MAX_PATH);
PathRemoveFileSpec(FilePath);
wcscat(FilePath,L"\\");
// open the file
pl = CreateFile(FileName,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (pl == INVALID_HANDLE_VALUE)
Exception(GetLastError());
fs = GetFileSize(pl,NULL);
rf = calloc(fs + 2, sizeof(BYTE));
if (! ReadFile(pl, rf, fs, &br, NULL))
Exception(GetLastError());
CloseHandle(pl);
if (br != fs)
Exception(0xE00640007); }
try
{ DWORD bom = *(DWORD*)rf;
if ((bom == 0x0000FEFF) || (bom == 0xFFFE0000)) // utf32le bom
Exception(0xE0640002); // utf32be bom
else if ((bom & 0xFFFF) == 0xFFFE) // utf16be bom
{ FlipEndian(rf,br);
CopyWChar((PWCHAR) rf + 1); }
else if ((bom & 0xFFFF) == 0xFEFF) // utf16le bom
CopyWChar((PWCHAR) rf + 1);
else if ((bom & 0xFFFFFF) == 0xBFBBEF) // utf8 bom
CopyMByte(rf + 3, br - 3);
else // no known bom, probe the file
{ if (! memchr(rf, 0x00, br)) // 8 bit text has no nulls
CopyMByte(rf,br); // ansi / utf8 no bom
else
{ PBYTE lf = memchr(rf,0x0A,br); // lf is always present as 1 byte.
if (!lf)
Exception(0xE0640003);
if ((!(*(DWORD*)(lf - 3) & 0x00FFFFFF)) || //utf32be no bom
(!(*(DWORD*)lf & 0xFFFFFF00))) //utf32le no bom
Exception(0xE0640002);
if ((lf - rf) & 1) // big endian? (lf at odd offset)
FlipEndian(rf,br); // utf16be no bom
CopyWChar((PWCHAR) rf); } } } // utf16le no bom
finally
{ free(rf); }
return 1; }
Although it's much simpler for comports, the principle is the same... If an error occurs while sending/receving data, force an exception which forces the finally{} block to execute, guarnteeing your cleanup is performed. If there is no error the finally{} block is executed as it is encountered, once again ensuring your cleanup happens as planned.
(note: Error-X is not required to use SEH... it just makes it a lot easier.)
Meanwhile I have found a tool with name 'handle' from sysinternals. If I am faced with a similar problem in the futur, I will try this. PortMon seems to be usefull to me too.
timovjl: And you are right. Process Explorer would also be helpfull in this situation.
czerny
Since you are now have XP you also have some expanded capability in Task Manager...
Right click the taskbar... select "start task manager" ---> look in the menus. You will find that you can add columns in the process tab for memory usage, handle count, thread count with View -> Add Columns. The window is also resizeable so you can see all of it at once.
These will be very handy in tracking most leaks. That is, your program's handle count should not be constantly increasing as it runs... it should reach a certain count and stay there, even when idling in the message dispatcher. The memory usage count is rather granular but it will help you find big leaks or accumulating leaks over multiple function calls. For example: If you are working on a program, you should see the handle count and memory usage increase as it opens files and launches threads but when the task completes it should go right back down to the original idle-state counts.
From Sysinternals, ProcMon is probably what you will use the most...
http://technet.microsoft.com/en-us/sysinternals/bb896653 ... but there's no harm in taking the entire thing, I've used most of them from time to time.