A VC2005 bug report

P

PLS

I don't know where else to report bugs, so maybe someone from Microsoft
is reading this group

Application crashed on a library thread. The stack is below (most recent
at top).

I think is a *REALLY* bad idea for the function that is used to report
memory allocation errors to allocate memory.

++PLS

msvcr80d.dll!__malloc_dbg() + 0x1f bytes
msvcr80d.dll!__calloc_dbg() + 0x96 bytes
msvcr80d.dll!__getptd_noexit() + 0x3d bytes
msvcr80d.dll!__errno() + 0x9 bytes
msvcr80d.dll!__VCrtDbgReportA() + 0x1bb bytes
msvcr80d.dll!__CrtDbgReportV() + 0x20 bytes
msvcr80d.dll!__CrtDbgReport() + 0x29 bytes
msvcr80d.dll!__CrtCheckMemory() + 0x2bb bytes
msvcr80d.dll!__heap_alloc_dbg() + 0x6d bytes
msvcr80d.dll!__nh_malloc_dbg() + 0x19 bytes
msvcr80d.dll!__malloc_dbg() + 0x1f bytes
msvcr80d.dll!__calloc_dbg() + 0x96 bytes
msvcr80d.dll!__getptd_noexit() + 0x3d bytes
msvcr80d.dll!__errno() + 0x9 bytes
msvcr80d.dll!__VCrtDbgReportA() + 0x1bb bytes
msvcr80d.dll!__CrtDbgReportV() + 0x20 bytes
msvcr80d.dll!__CrtDbgReport() + 0x29 bytes
msvcr80d.dll!__CrtCheckMemory() + 0x2bb bytes
msvcr80d.dll!__heap_alloc_dbg() + 0x6d bytes
msvcr80d.dll!__nh_malloc_dbg() + 0x19 bytes
msvcr80d.dll!__malloc_dbg() + 0x1f bytes
msvcr80d.dll!__calloc_dbg() + 0x96 bytes
msvcr80d.dll!__getptd_noexit() + 0x3d bytes
msvcr80d.dll!__errno() + 0x9 bytes
msvcr80d.dll!__VCrtDbgReportA() + 0x1bb bytes
msvcr80d.dll!__CrtDbgReportV() + 0x20 bytes
msvcr80d.dll!__CrtDbgReport() + 0x29 bytes
msvcr80d.dll!__CrtCheckMemory() + 0x2bb bytes
msvcr80d.dll!__heap_alloc_dbg() + 0x6d bytes
msvcr80d.dll!__nh_malloc_dbg() + 0x19 bytes
msvcr80d.dll!__malloc_dbg() + 0x1f bytes
msvcr80d.dll!__calloc_dbg() + 0x96 bytes
msvcr80d.dll!__getptd_noexit() + 0x3d bytes
msvcr80d.dll!__errno() + 0x9 bytes
msvcr80d.dll!__VCrtDbgReportA() + 0x1bb bytes
msvcr80d.dll!__CrtDbgReportV() + 0x20 bytes
msvcr80d.dll!__CrtDbgReport() + 0x29 bytes
msvcr80d.dll!__CrtCheckMemory() + 0x2bb bytes
msvcr80d.dll!__heap_alloc_dbg() + 0x6d bytes
msvcr80d.dll!__nh_malloc_dbg() + 0x19 bytes
msvcr80d.dll!__malloc_dbg() + 0x1f bytes
msvcr80d.dll!__calloc_dbg() + 0x96 bytes
msvcr80d.dll!__getptd_noexit() + 0x3d bytes
msvcr80d.dll!__errno() + 0x9 bytes
msvcr80d.dll!__VCrtDbgReportA() + 0x1bb bytes
msvcr80d.dll!__CrtDbgReportV() + 0x20 bytes
msvcr80d.dll!__CrtDbgReport() + 0x29 bytes
msvcr80d.dll!__CrtCheckMemory() + 0x2bb bytes
msvcr80d.dll!__heap_alloc_dbg() + 0x6d bytes
msvcr80d.dll!__nh_malloc_dbg() + 0x19 bytes
msvcr80d.dll!__malloc_dbg() + 0x1f bytes
msvcr80d.dll!__calloc_dbg() + 0x96 bytes
msvcr80d.dll!__getptd_noexit() + 0x3d bytes
msvcr80d.dll!__errno() + 0x9 bytes
msvcr80d.dll!__VCrtDbgReportA() + 0x1bb bytes
msvcr80d.dll!__CrtDbgReportV() + 0x20 bytes
msvcr80d.dll!__CrtDbgReport() + 0x29 bytes
msvcr80d.dll!__CrtCheckMemory() + 0x2bb bytes
msvcr80d.dll!__heap_alloc_dbg() + 0x6d bytes
msvcr80d.dll!__nh_malloc_dbg() + 0x19 bytes
msvcr80d.dll!__malloc_dbg() + 0x1f bytes
msvcr80d.dll!__calloc_dbg() + 0x96 bytes
msvcr80d.dll!__getptd_noexit() + 0x3d bytes
msvcr80d.dll!__errno() + 0x9 bytes
msvcr80d.dll!__VCrtDbgReportA() + 0x1bb bytes
msvcr80d.dll!__CrtDbgReportV() + 0x20 bytes
msvcr80d.dll!__CrtDbgReport() + 0x29 bytes
msvcr80d.dll!__CrtCheckMemory() + 0x2bb bytes
msvcr80d.dll!__heap_alloc_dbg() + 0x6d bytes
msvcr80d.dll!__nh_malloc_dbg() + 0x19 bytes
msvcr80d.dll!__malloc_dbg() + 0x1f bytes
msvcr80d.dll!__calloc_dbg() + 0x96 bytes
msvcr80d.dll!__getptd_noexit() + 0x3d bytes
msvcr80d.dll!__errno() + 0x9 bytes
msvcr80d.dll!__VCrtDbgReportA() + 0x1bb bytes
msvcr80d.dll!__CrtDbgReportV() + 0x20 bytes
msvcr80d.dll!__CrtDbgReport() + 0x29 bytes
msvcr80d.dll!__CrtCheckMemory() + 0x2bb bytes
msvcr80d.dll!__heap_alloc_dbg() + 0x6d bytes
msvcr80d.dll!__nh_malloc_dbg() + 0x19 bytes
msvcr80d.dll!__malloc_dbg() + 0x1f bytes
msvcr80d.dll!__calloc_dbg() + 0x96 bytes
msvcr80d.dll!__getptd_noexit() + 0x3d bytes
msvcr80d.dll!__errno() + 0x9 bytes
msvcr80d.dll!__VCrtDbgReportA() + 0x1bb bytes
msvcr80d.dll!__CrtDbgReportV() + 0x20 bytes
msvcr80d.dll!__CrtDbgReport() + 0x29 bytes
msvcr80d.dll!__CrtCheckMemory() + 0x2bb bytes
msvcr80d.dll!__free_dbg_nolock() + 0x22 bytes
msvcr80d.dll!__free_dbg() + 0x4e bytes
msvcr80d.dll!__freefls@4() + 0x1cf bytes
msvcr80d.dll!__freeptd() + 0x5d bytes
msvcr80d.dll!__CRTDLL_INIT@12() + 0x3c9 bytes
msvcr80d.dll!__CRTDLL_INIT@12() + 0x1f bytes
ntdll.dll!_LdrpCallInitRoutine@16() + 0x14 bytes
ntdll.dll!_LdrShutdownThread@0() + 0xed bytes
kernel32.dll!_ExitThread@4() + 0x3e bytes
kernel32.dll!_FreeLibraryAndExitThread@8() + 0x1d bytes
ole32.dll!CRpcThreadCache::RpcWorkerThreadEntry() + 0x34 bytes
kernel32.dll!_BaseThreadStart@8() + 0x37 bytes
 
C

Carl Daniel [VC++ MVP]

PLS said:
I don't know where else to report bugs, so maybe someone from Microsoft
is reading this group
http://connect.microsoft.com/feedback?SiteID=210


Application crashed on a library thread. The stack is below (most recent
at top).

I think is a *REALLY* bad idea for the function that is used to report
memory allocation errors to allocate memory.

That is annoying (and then some), isn't it?

It's odd that __getptd_noexit is allocating memory. To me, that suggests
that it's running in a thread that wasn't created with _beginthread{ex}.

Are you linking with the static runtime library, by chance? (If you're
linking with the DLL runtime library, you don't need to worrk about using
_beginthread, but using the static runtime, you do).

-cd
 
J

Jochen Kalmbach [MVP]

Hi Carl!
It's odd that __getptd_noexit is allocating memory. To me, that suggests
that it's running in a thread that wasn't created with _beginthread{ex}.

From the callstack it lloks like a thread has exited and the DLL-CRT
now tries to free the thread-local-memory (__freeptd).
This is fine...

Now the problem is that the CRT wants to output the memory-leaks with
"__CrtDbgReport".
And now some of those functions tries to set the "errno" which is stored
in TLS, which was previously freed ;-)
And now it allocated again memory for this TLS... therefor it calls
__getptd_noexit.

;-)))

Nice Bug!

Greetings
Jochen
 
C

Carl Daniel [VC++ MVP]

Jochen Kalmbach said:
Hi Carl!


From the callstack it lloks like a thread has exited and the DLL-CRT now
tries to free the thread-local-memory (__freeptd).
This is fine...

Ah yes - I didn't look far enough down the stack!
Now the problem is that the CRT wants to output the memory-leaks with
"__CrtDbgReport".
And now some of those functions tries to set the "errno" which is stored
in TLS, which was previously freed ;-)
And now it allocated again memory for this TLS... therefor it calls
__getptd_noexit.

;-)))

Nice Bug!

Indeed!

-cd
 
P

PLS

No, linking with the DLLs. My setting is /MDd. I have set flags to check
memory on each alloc/free and to report leaks on exit.

The thread this error occurs on is not from my program. Mine is single
threaded. It is, however, a COM server and I know from experience that
COM creates extra threads.

++PLS
 
B

Ben Voigt

PLS said:
No, linking with the DLLs. My setting is /MDd. I have set flags to check
memory on each alloc/free and to report leaks on exit.

The thread this error occurs on is not from my program. Mine is single
threaded. It is, however, a COM server and I know from experience that
COM creates extra threads.

Well the CRT got loaded on that thread somehow, probably by DllMain, but
possibly by some of your code calling CRT functions. COM doesn't link to
the CRT, doesn't use CRT allocators, and definitely not the debug version.
 
J

Jochen Kalmbach [MVP]

Ben said:
Well the CRT got loaded on that thread somehow, probably by DllMain, but
possibly by some of your code calling CRT functions. COM doesn't link to
the CRT, doesn't use CRT allocators, and definitely not the debug version.


--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
 
J

Jochen Kalmbach [MVP]

Hi Ben!
Well the CRT got loaded on that thread somehow, probably by DllMain, but
possibly by some of your code calling CRT functions. COM doesn't link to
the CRT, doesn't use CRT allocators, and definitely not the debug version.

The CRT always initialises the TLS for *each* thread which was created
and calling DllMain with THREAD_ATTACH.

So every COM thread will trigger the CRT and allocate the TLS for this
thread (even if it is not used). Therefor every COM thread uses the CRT
if the app (or any DLL in the app) are using the DLL version of the DLL.
And if you use severay different CRT DLLs, every single CRT version will
be triggered and will allocate TLS storage.
(For example your app uses msvcrt80, one dll uses msvcrt71 an other
msvcrt70 and an other msvcrt; now you have 4 different CRTs and each
will allocate TLS for each COM thread which never uses the CRT ;) )

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
 
B

Ben Voigt

So every COM thread will trigger the CRT and allocate the TLS for this
thread (even if it is not used). Therefor every COM thread uses the CRT if
the app (or any DLL in the app) are using the DLL version of the DLL.
And if you use severay different CRT DLLs, every single CRT version will
be triggered and will allocate TLS storage.
(For example your app uses msvcrt80, one dll uses msvcrt71 an other
msvcrt70 and an other msvcrt; now you have 4 different CRTs and each will
allocate TLS for each COM thread which never uses the CRT ;) )

That's certainly true when linking the CRT dynamically, it has a chance to
initialize on every thread in the process.
 
P

PLS

I enter this bug on Microsoft Connect. The response from Micrsoft is
that it isn't worth fixing.

++PLS
 
C

Carl Daniel [VC++ MVP]

PLS said:
I enter this bug on Microsoft Connect. The response from Micrsoft is
that it isn't worth fixing.

If you could post a link to the bug report on Connect, other people can vote
on it.

If your bug was closed as "won't fix", that means that it won't be fixed in
Orcas (the next release of VS), but that doesn't mean that it won't be fixed
ever- especially if more people validate it/vote on it.

-cd
 
Top