跨dll边界的资源泄漏

时间:2017-11-29 14:52:06

标签: c++ c windows dll memory-leaks

我有一个用C语言编写的第三方(开源)dll,我们称之为library_c_style_0.2.dll。在我的C ++应用程序中,我必须从这个dll调用方法。我将从dll中调用这些方法,比如library0.1.dll加载application.exe。使用dll library_c_style_0.2.dll(我在运行时使用LoadLibrary加载)后,我调用了FreeLibrary。我可以看到App Verifier抱怨A heap allocation was leaked.我忽略了这一点并继续,我看到我的应用程序的某些无关部分的失败开始失败,HeapAlloc

因此,为了验证这一点,我使用了crtdbg,并编写了如下情景的迷你模拟。 library_c_style_0.2.dll的导出就是这样,

int hello_from_c_style_library(const char* string_to_print)
{
    _CrtMemState s1, s2, s3;
    _CrtMemCheckpoint(&s1); //create on checkpoint

    int length = strlen(string_to_print);
    char * c = malloc(length+1); //allocate memory for the sting
    StringCchCopyA(c, length + 1, string_to_print);
    printf("%s", c);

    //comment the folling lines if you pretend that you will foget to free
    //free(c);

    _CrtMemCheckpoint(&s3); //one more after resource allocation
    if (_CrtMemDifference(&s2, &s3, &s1))//find the difference now
    {
        //returns 1 if memory is leaked; 0 otherwise
        OutputDebugString(L"Memory Leaked!!!");
        _CrtDumpMemoryLeaks();
    }
    return 0;
}

和我在运行时加载它的library0.1.dll就是这样,

HINSTANCE hinstLib = LoadLibrary(TEXT("library_c_style_0.2.dll"));
if (hinstLib != NULL)
{
    //GetProcAddress of hello_from_c_style_library
    //call the funtion
    //we are now done with the third party dll, free it

    FreeLibrary(hinstLib);
}

但是,如果我取消注释free(c)一切都很好。 (当我使用运算符library_c_style_0.2.dll在C ++中编写示例new时,没有问题,尽管它已泄露了)

我们可以看到library_c_style_0.2.dll泄漏了为c分配的内存,我看到对FreeLibrary(hinstLib)的调用在AppVerifier上失败并显示错误A heap allocation was leaked.

CRT的输出窗口转储如下,

Memory Leaked!!!Detected memory leaks!
Dumping objects ->
library_c_style_0.2.c(23) : {69} normal block at 0x08B31FF0, 6 bytes long.
 Data: <hello > 68 65 6C 6C 6F 00 
Object dump complete.

我们可以看到hello的6个字节被泄露。

这只是一个模拟,实际的第三方dll(这里的library_c_style_0.2.dll是占位符)正在泄漏一些资源并导致我的应用程序崩溃。

我该怎么办?有没有办法我可以处理这个问题,而无需查看泄漏资源的第三方C dll?如果我忽略这一点,它会在HeapAlloc上崩溃我的C ++应用程序中一些不相关的部分。

为什么会这样?任何指针都会有所帮助。我是Windows环境的新手。每个dll都有自己的堆吗?是否抛出错误,因为我试图在存放资源时释放库?

是否有解决方法以避免查看library_c_style_0.2.dll的代码?我链接到运行时的方式有问题吗?我现在静态链接到它。在生产中我使用Multi-threaded (/MT),我可以看到漏洞的dll(这是一个非常庞大的代码库)也使用相同的。

我想了解基础知识。为什么资源泄漏导致失败?请解释一下内部情况,这里究竟发生了什么。

0 个答案:

没有答案