“多线程调试”(/ MTd)导致内存泄漏,而“多线程调试DLL”(/ MDd)则没有泄漏]

问题描述 投票:2回答:2

我在一个解决方案中有很多库和项目,我改成了使用/ MTd而不是/ MDd。我正在使用VS2008。

我突然收到一堆/ MDd开关不存在的内存泄漏。

使用Visual Leak Detector,我注意到所有泄漏都是各种库内部的,包括CRT,VS库和boost。

例如,这里前三个泄漏的调用堆栈(该项目是Boost :: Test项目):

---------- Block 1 at 0x02211EA0: 568 bytes ----------
  Call Stack:
    f:\dd\vctools\crt_bld\self_x86\crt\src\tidtable.c (395): FrameworkUnitTests.exe!_mtinit + 0x18 bytes
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (215): FrameworkUnitTests.exe!__tmainCRTStartup + 0x5 bytes
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (182): FrameworkUnitTests.exe!mainCRTStartup
    0x7C817077 (File and line number not available): kernel32.dll!RegisterWaitForInputIdle + 0x49 bytes
  Data:
    00 00 00 00    F0 20 21 02    0C 9D B8 00    8A 01 00 00     ......!. ........
    14 02 00 00    02 00 00 00    01 00 00 00    FD FD FD FD     ........ ........
    84 1B 00 00    FF FF FF FF    22 00 00 00    02 00 00 00     ........ ".......
    00 00 00 00    C5 03 8A E6    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    B0 80 8C 03    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    E8 C9 B8 00     ........ ........
    00 00 00 00    00 00 00 00    B0 4A 21 02    F8 DB C4 00     ........ .J!.....
    01 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    D0 57 99 00    00 00 00 00    00 00 00 00    00 00 00 00     .W...... ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    43 00 00 00    00 00 00 00     ........ C.......
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........


---------- Block 2 at 0x022120F0: 2084 bytes ----------
  Call Stack:
    f:\dd\vctools\crt_bld\self_x86\crt\src\ioinit.c (137): FrameworkUnitTests.exe!_ioinit + 0x15 bytes
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (235): FrameworkUnitTests.exe!__tmainCRTStartup + 0x5 bytes
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (182): FrameworkUnitTests.exe!mainCRTStartup
    0x7C817077 (File and line number not available): kernel32.dll!RegisterWaitForInputIdle + 0x49 bytes
  Data:
    A0 1E 21 02    90 4A 21 02    A4 C4 B8 00    88 00 00 00     ..!..J!. ........
    00 08 00 00    02 00 00 00    02 00 00 00    FD FD FD FD     ........ ........
    03 00 00 00    C1 0A 00 00    01 00 00 00    00 F8 15 00     ........ ........
    FF FF FF FF    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    A0 0F 00 00    00 0A 0A 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    07 00 00 00    C1 0A 00 00    01 00 00 00    38 F8 15 00     ........ ....8...
    FF FF FF FF    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    A0 0F 00 00    00 0A 0A 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    0B 00 00 00    C1 0A 00 00    01 00 00 00    70 F8 15 00     ........ ....p...
    FF FF FF FF    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    A0 0F 00 00    00 0A 0A 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    FF FF FF FF    00 0A 00 00    01 00 00 00    D8 FF 15 00     ........ ........
    FF FF FF FF    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........


---------- Block 118 at 0x02212FC0: 60 bytes ----------
  Call Stack:
    f:\dd\vctools\crt_bld\self_x86\crt\src\mlock.c (279): FrameworkUnitTests.exe!_mtinitlocknum + 0x13 bytes
    f:\dd\vctools\langapi\undname\undname.cxx (649): FrameworkUnitTests.exe!__unDName + 0x7 bytes
    f:\dd\vctools\crt_bld\self_x86\crt\prebuild\eh\typname.cpp (124): FrameworkUnitTests.exe!type_info::_Name_base + 0x1F bytes
    f:\dd\vctools\crt_bld\self_x86\crt\prebuild\eh\typinfo.cpp (45): FrameworkUnitTests.exe!type_info::name + 0xD bytes
    c:\...\3rdpartylibs\boost_1_49_0\boost\test\unit_test_suite_impl.hpp (377): FrameworkUnitTests.exe!boost::unit_test::ut_detail::generate_test_case_4_type<boost::unit_test::ut_detail::template_test_case_gen<Bitset_b85_Serialization_Tests::deserialize_from_empty_string_should_fail_invoker,boost::mpl::vector_c<int,5,59,519,1021,1024,1025,1026,3021,7024,11 + 0xF bytes
    c:\...\3rdpartylibs\boost_1_49_0\boost\mpl\for_each.hpp (79): FrameworkUnitTests.exe!boost::mpl::aux::for_each_impl<0>::execute<boost::mpl::v_iter<boost::mpl::vector11<boost::mpl::integral_c<int,5>,boost::mpl::integral_c<int,59>,boost::mpl::integral_c<int,519>,boost::mpl::integral_c<int,1021>,boost::mpl::integral_c<int,1024>,boost::mpl::i
    c:\...\3rdpartylibs\boost_1_49_0\boost\mpl\for_each.hpp (101): FrameworkUnitTests.exe!boost::mpl::for_each<boost::mpl::vector_c<int,5,59,519,1021,1024,1025,1026,3021,7024,11025,22026,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647,2147483647>,boost::mpl::make_identity<boost::mpl::arg<-1> >,boost::uni + 0x21 bytes
    c:...\3rdpartylibs\boost_1_49_0\boost\test\unit_test_suite_impl.hpp (405): FrameworkUnitTests.exe!boost::unit_test::ut_detail::template_test_case_gen<Bitset_b85_Serialization_Tests::deserialize_from_empty_string_should_fail_invoker,boost::mpl::vector_c<int,5,59,519,1021,1024,1025,1026,3021,7024,11025,22026,2147483647,2147483647,2147483647,2147483647,2 + 0x35 bytes
    c:\...\src\bitset_serialization_test.cpp (31): FrameworkUnitTests.exe!Bitset_b85_Serialization_Tests::`dynamic initializer for 'deserialize_from_empty_string_should_fail_registrar31'' + 0x5D bytes
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0dat.c (903): FrameworkUnitTests.exe!_initterm
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0dat.c (307): FrameworkUnitTests.exe!_cinit + 0xF bytes
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (249): FrameworkUnitTests.exe!__tmainCRTStartup + 0x7 bytes
    f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c (182): FrameworkUnitTests.exe!mainCRTStartup
    0x7C817077 (File and line number not available): kernel32.dll!RegisterWaitForInputIdle + 0x49 bytes
  Data:
    90 4A 21 02    78 40 21 02    5C 9B B8 00    17 01 00 00     .J!.x@!. \.......
    18 00 00 00    02 00 00 00    76 00 00 00    FD FD FD FD     ........ v.......
    F8 F9 15 00    FF FF FF FF    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    A0 0F 00 00    FD FD FD FD                    ........ ........

有人知道发生了什么吗?

编辑:据我了解,这两个开关/模式之间的区别在于两个链接的DLL是否共享相同的CRT(例如内存管理)还是每个都有自己的CRT。当每个使用自己的(/ MT [d])时,一个不能释放另一个分配的资源。但是,我静态地链接了所有内容,因此没有涉及DLL,至少在我的代码中没有。

visual-studio-2008 memory-leaks
2个回答
0
投票

我看到类似的事情,我认为这可能只是一次性初始化事情:

---------- Block 119 at 0x007B6AF8: 60 bytes ----------
Call Stack:
f:\dd\vctools\crt\crtw32\startup\mlock.c (276): _mtinitlocknum
f:\dd\vctools\crt\crtw32\stdio\stream.c (72): _getstream
f:\dd\vctools\crt\crtw32\stdio\fopen.c (61): _fsopen
f:\dd\vctools\crt\crtw32\stdio\fopen.c (125): fopen

如果_mtinitlocknum()分配了随后使用的缓冲区,则可能为假肯定。换句话说,此后它会重新使用缓冲区。


0
投票

我看到的是同一件事。以下代码段说明了这一点。如果您观看Visual Studio的内存使用情况,则MTd会稳定增长,而MDd会保持稳定。好像fclose()没有做任何事情。我已经证明,通过assert语句,返回值都是好的。

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

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);

while (1) 
{
    FILE* fh = fopen("c:\\temp\\1.txt", "a");
    if (fh != NULL)
    {
        int fc = fclose(fh);
    }
}
return (0);

} // WinMain
© www.soinside.com 2019 - 2024. All rights reserved.