LibGit2 初始化的内存问题
Memory problems with LibGit2 initialization
当我初始化并关闭 LibGit2 时,我留下了可访问内存 and/or 错误。
我的测试系统是 Ubuntu 18.04,libgit2 0.26,其中 g++ -v
给我 gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
和一个 FreeBSD 11.3 VM,libgit 0.28.3,不幸的是,我无法复制& 粘贴自。这里 g++ -v
给出 gcc version 9.2.0 (FreeBSD Ports Collection
.
这是一个最小的例子:
#include <git2.h>
int main () {
git_libgit2_init();
git_libgit2_shutdown();
return 0;
}
关于 Ubuntu 我 运行 以下内容:
➜ libelektra git:(libgit_test) ✗ g++ minimal.c -lgit2 && valgrind ./a.out
==1174== Memcheck, a memory error detector
==1174== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1174== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==1174== Command: ./a.out
==1174==
==1174==
==1174== HEAP SUMMARY:
==1174== in use at exit: 192 bytes in 12 blocks
==1174== total heap usage: 1,354 allocs, 1,342 frees, 107,044 bytes allocated
==1174==
==1174== LEAK SUMMARY:
==1174== definitely lost: 0 bytes in 0 blocks
==1174== indirectly lost: 0 bytes in 0 blocks
==1174== possibly lost: 0 bytes in 0 blocks
==1174== still reachable: 192 bytes in 12 blocks
==1174== suppressed: 0 bytes in 0 blocks
==1174== Rerun with --leak-check=full to see details of leaked memory
==1174==
==1174== For counts of detected and suppressed errors, rerun with: -v
==1174== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
当 very first example from the documentation 说 git_libgit2_shutdown();
应该清理所有内容时,为什么我有可用的内存?
虽然 Valgrind 文档说 some reachable memory might be ok,但在 FreeBSD 上事情变得非常疯狂。我有一些虚拟机的截图
One Two Three。
我怎样才能避免这种情况?
关于不同内存处理的补充说明。我的目标是使用 git_merge_file
函数 in this project。它应该看起来像这样:
#include <git2.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
int main () {
git_libgit2_init();
sleep (1);
git_merge_file_result out = { 0 }; // out.ptr will not receive a terminating null character
git_merge_file_input libgit_base;
git_merge_file_input libgit_our;
git_merge_file_input libgit_their;
git_merge_file_init_input(&libgit_base, GIT_MERGE_FILE_INPUT_VERSION);
git_merge_file_init_input(&libgit_our, GIT_MERGE_FILE_INPUT_VERSION);
git_merge_file_init_input(&libgit_their, GIT_MERGE_FILE_INPUT_VERSION);
libgit_base.ptr = "A";
libgit_base.size = strlen("A");
libgit_our.ptr = "A";
libgit_our.size = strlen("A");
libgit_their.ptr = "A";
libgit_their.size = strlen("A");
int exitCode = git_merge_file (&out, &libgit_base, &libgit_our, &libgit_their, 0);
printf("Code is %d\n", exitCode);
git_merge_file_result_free (&out);
git_libgit2_shutdown();
sleep (1);
return 0;
}
当我删除初始化 and/or 关闭时,我有时会在 Ubuntu 上获得 0 个仍可访问的内存,但在 FreeBSD 上会出现分段错误。是否值得仔细研究一下,或者忽略 that LibGit must be initialized?
时这种行为差异是否正常?
在 BSD VM 的屏幕截图中,__pthread_once
是问题的根源。这和 __pthread_once_slow
似乎与所有错误有关:开头的 Ubuntu 上的 192 个字节,BSD 和 Ubuntu 底部的更高级示例以及我的实际应用程序。
据我所知,您的代码或 Valgrind 报告本身没有任何问题,正如您 pointed out:
"still reachable" means your program is probably ok -- it didn't free some memory it could have. This is quite common and often reasonable. Don't use --show-reachable=yes if you don't want to see these reports.
因此,这 192 个字节很可能并没有真正泄漏,您只是在 OS 决定夺回该内存块之前设法退出程序 — 即。它将该块保留在进程的权限范围内,作为对下一次分配的优化。在这种情况下,进程刚刚退出,因此必须在进程终止时回收内存,我认为这就是 "still reachable" 的意思——内存很好,将被正常回收。希望.
FreeBSD 上的 Valgrind 错误不是分配问题,而是使用未初始化的内存区域。在解析证书(?)时,它们看起来不在 libgit2 内部,而是 OpenSSL 本身。您可以找到从 here.
开始的底层 OpenSSL 初始化
Is it worth giving this a closer look or is such a difference in behavior normal when ignoring the that LibGit must be initialized?
我很想说不,是的。代码现在正在生成包含 随机垃圾 而不是堆栈分配的 pthread_something
的内存位置。段错误必然会随机发生。
HTH!
当我初始化并关闭 LibGit2 时,我留下了可访问内存 and/or 错误。
我的测试系统是 Ubuntu 18.04,libgit2 0.26,其中 g++ -v
给我 gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
和一个 FreeBSD 11.3 VM,libgit 0.28.3,不幸的是,我无法复制& 粘贴自。这里 g++ -v
给出 gcc version 9.2.0 (FreeBSD Ports Collection
.
这是一个最小的例子:
#include <git2.h>
int main () {
git_libgit2_init();
git_libgit2_shutdown();
return 0;
}
关于 Ubuntu 我 运行 以下内容:
➜ libelektra git:(libgit_test) ✗ g++ minimal.c -lgit2 && valgrind ./a.out
==1174== Memcheck, a memory error detector
==1174== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1174== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==1174== Command: ./a.out
==1174==
==1174==
==1174== HEAP SUMMARY:
==1174== in use at exit: 192 bytes in 12 blocks
==1174== total heap usage: 1,354 allocs, 1,342 frees, 107,044 bytes allocated
==1174==
==1174== LEAK SUMMARY:
==1174== definitely lost: 0 bytes in 0 blocks
==1174== indirectly lost: 0 bytes in 0 blocks
==1174== possibly lost: 0 bytes in 0 blocks
==1174== still reachable: 192 bytes in 12 blocks
==1174== suppressed: 0 bytes in 0 blocks
==1174== Rerun with --leak-check=full to see details of leaked memory
==1174==
==1174== For counts of detected and suppressed errors, rerun with: -v
==1174== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
当 very first example from the documentation 说 git_libgit2_shutdown();
应该清理所有内容时,为什么我有可用的内存?
虽然 Valgrind 文档说 some reachable memory might be ok,但在 FreeBSD 上事情变得非常疯狂。我有一些虚拟机的截图 One Two Three。 我怎样才能避免这种情况?
关于不同内存处理的补充说明。我的目标是使用 git_merge_file
函数 in this project。它应该看起来像这样:
#include <git2.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
int main () {
git_libgit2_init();
sleep (1);
git_merge_file_result out = { 0 }; // out.ptr will not receive a terminating null character
git_merge_file_input libgit_base;
git_merge_file_input libgit_our;
git_merge_file_input libgit_their;
git_merge_file_init_input(&libgit_base, GIT_MERGE_FILE_INPUT_VERSION);
git_merge_file_init_input(&libgit_our, GIT_MERGE_FILE_INPUT_VERSION);
git_merge_file_init_input(&libgit_their, GIT_MERGE_FILE_INPUT_VERSION);
libgit_base.ptr = "A";
libgit_base.size = strlen("A");
libgit_our.ptr = "A";
libgit_our.size = strlen("A");
libgit_their.ptr = "A";
libgit_their.size = strlen("A");
int exitCode = git_merge_file (&out, &libgit_base, &libgit_our, &libgit_their, 0);
printf("Code is %d\n", exitCode);
git_merge_file_result_free (&out);
git_libgit2_shutdown();
sleep (1);
return 0;
}
当我删除初始化 and/or 关闭时,我有时会在 Ubuntu 上获得 0 个仍可访问的内存,但在 FreeBSD 上会出现分段错误。是否值得仔细研究一下,或者忽略 that LibGit must be initialized?
时这种行为差异是否正常?在 BSD VM 的屏幕截图中,__pthread_once
是问题的根源。这和 __pthread_once_slow
似乎与所有错误有关:开头的 Ubuntu 上的 192 个字节,BSD 和 Ubuntu 底部的更高级示例以及我的实际应用程序。
据我所知,您的代码或 Valgrind 报告本身没有任何问题,正如您 pointed out:
"still reachable" means your program is probably ok -- it didn't free some memory it could have. This is quite common and often reasonable. Don't use --show-reachable=yes if you don't want to see these reports.
因此,这 192 个字节很可能并没有真正泄漏,您只是在 OS 决定夺回该内存块之前设法退出程序 — 即。它将该块保留在进程的权限范围内,作为对下一次分配的优化。在这种情况下,进程刚刚退出,因此必须在进程终止时回收内存,我认为这就是 "still reachable" 的意思——内存很好,将被正常回收。希望.
FreeBSD 上的 Valgrind 错误不是分配问题,而是使用未初始化的内存区域。在解析证书(?)时,它们看起来不在 libgit2 内部,而是 OpenSSL 本身。您可以找到从 here.
开始的底层 OpenSSL 初始化Is it worth giving this a closer look or is such a difference in behavior normal when ignoring the that LibGit must be initialized?
我很想说不,是的。代码现在正在生成包含 随机垃圾 而不是堆栈分配的 pthread_something
的内存位置。段错误必然会随机发生。
HTH!