c 中的简单 shell - valgrind 显示排序命令的内存泄漏
simple shell in c - valgrind shows memorry leaks for sort command
我正在用 C 编写一个简单的 shell,它应该支持最多 2 个管道(我知道 n 个管道的实现更短,但出于某种原因这是特定要求)。
当使用 valgrind 检查内存泄漏时,我没有遇到任何问题,除非我使用 sort 命令,例如对于“ls | sort”输出以下消息:
==4903== HEAP SUMMARY:
==4903== in use at exit: 760 bytes in 17 blocks
==4903== total heap usage: 65 allocs, 48 frees, 8,533,744 bytes allocated
==4903==
==4903== 8 bytes in 1 blocks are definitely lost in loss record 1 of 6
==4903== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903== by 0x11ACFC: ??? (in /usr/bin/sort)
==4903== by 0x10D72A: ??? (in /usr/bin/sort)
==4903== by 0x48AE0B2: (below main) (libc-start.c:308)
==4903==
==4903== 32 bytes in 1 blocks are indirectly lost in loss record 2 of 6
==4903== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903== by 0x11ACFC: ??? (in /usr/bin/sort)
==4903== by 0x1166F6: ??? (in /usr/bin/sort)
==4903== by 0x10D860: ??? (in /usr/bin/sort)
==4903== by 0x48AE0B2: (below main) (libc-start.c:308)
==4903==
==4903== 48 bytes in 12 blocks are still reachable in loss record 3 of 6
==4903== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903== by 0x11ACFC: ??? (in /usr/bin/sort)
==4903== by 0x10C122: ??? (in /usr/bin/sort)
==4903== by 0x48AE0B2: (below main) (libc-start.c:308)
==4903==
==4903== 128 bytes in 1 blocks are still reachable in loss record 4 of 6
==4903== at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903== by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903== by 0x11AD69: ??? (in /usr/bin/sort)
==4903== by 0x10F0F2: ??? (in /usr/bin/sort)
==4903== by 0x10DA99: ??? (in /usr/bin/sort)
==4903== by 0x48AE0B2: (below main) (libc-start.c:308)
==4903==
==4903== 512 bytes in 1 blocks are indirectly lost in loss record 5 of 6
==4903== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903== by 0x11ACFC: ??? (in /usr/bin/sort)
==4903== by 0x10D89D: ??? (in /usr/bin/sort)
==4903== by 0x48AE0B2: (below main) (libc-start.c:308)
==4903==
==4903== 576 (32 direct, 544 indirect) bytes in 1 blocks are definitely lost in loss record 6 of 6
==4903== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903== by 0x11ACFC: ??? (in /usr/bin/sort)
==4903== by 0x1166C7: ??? (in /usr/bin/sort)
==4903== by 0x10D860: ??? (in /usr/bin/sort)
==4903== by 0x48AE0B2: (below main) (libc-start.c:308)
==4903==
==4903== LEAK SUMMARY:
==4903== definitely lost: 40 bytes in 2 blocks
==4903== indirectly lost: 544 bytes in 2 blocks
==4903== possibly lost: 0 bytes in 0 blocks
==4903== still reachable: 176 bytes in 13 blocks
==4903== suppressed: 0 bytes in 0 blocks
==4903==
==4903== For lists of detected and suppressed errors, rerun with: -s
==4903== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
以上是 valgrind 运行 sort
后的输出,在 valgrind 运行 ls
后泄漏摘要是:
==4904== LEAK SUMMARY:
==4904== definitely lost: 0 bytes in 0 blocks
==4904== indirectly lost: 0 bytes in 0 blocks
==4904== possibly lost: 0 bytes in 0 blocks
==4904== still reachable: 20,381 bytes in 9 blocks
==4904== suppressed: 0 bytes in 0 blocks
==4904==
==4904== For lists of detected and suppressed errors, rerun with: -s
==4904== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
我可以忍受。
我尝试了几个不同的命令,有或没有管道 - 同样,sort
是唯一导致泄漏的命令。
当我退出程序时,valgrind 输出没有错误也没有内存泄漏,但这可能是由于最后的 exit(0)
调用。
我的问题是
- 这可能是
sort
的 valgrind 问题吗?
- 如何进一步调试它?
我仔细检查了我程序中的每个 free
调用,并在网上寻找类似的问题,但没有找到任何问题。
(代码会根据需要更新)
更新
感谢 Bodo 的回答,我发现我的系统(Linux VMware 16 下的 Mint 20)sort
确实导致内存泄漏,或者至少在 valgrind 中存在内存泄漏.我使用了 ls | valgrind sort
建议来解决这个问题。
valgrind 输出:
==2966== HEAP SUMMARY:
==2966== in use at exit: 760 bytes in 17 blocks
==2966== total heap usage: 65 allocs, 48 frees, 8,533,744 bytes allocated
==2966==
==2966== LEAK SUMMARY:
==2966== definitely lost: 40 bytes in 2 blocks
==2966== indirectly lost: 544 bytes in 2 blocks
==2966== possibly lost: 0 bytes in 0 blocks
==2966== still reachable: 176 bytes in 13 blocks
==2966== suppressed: 0 bytes in 0 blocks
是的,valgrind
可以报告 /usr/bin/sort
程序中的问题。
你的 shell 可能使用 fork
为要执行的命令创建一个(或多个)进程,然后调用一些 exec..
函数来执行指定的程序.当 exec
函数成功时,进程不再是 运行 你的 shell 的代码,而是另一个程序的代码。
如果您指示valgrind
检查子进程,它会继续跟踪您的shell执行的程序,因此它也会报告这些程序中可能存在的错误。当然这些错误与你的shell.
无关
要确认这一点,您可以比较类似命令行的结果,例如ls | sort
与 ls | cat
.
确认这一点的另一种方法是 运行 sort
与 valgrind
独立于您的简单 shell。你可以试试
ls | valgrind sort
如果 valgrind
和您要检查的程序的混合输出令人困惑,您可以使用 valgrind
的选项 --log-file=<filename>
选项将其输出重定向到一个文件。
如 Jabberwocky 的评论所述,为避免检查任何不相关的程序,您可以创建自己的(假)程序,这些程序没有内存泄漏和内存访问错误。要检查 shell 实现中的错误,您对 sort
的替换没有必要实际对行进行排序。唯一重要的是它不会从 valgrind
产生任何 errors/warnings 并且它的行为可能与 sort
相似,从 stdin
读取数据并将数据写入到stdout
,可选择延迟。
我正在用 C 编写一个简单的 shell,它应该支持最多 2 个管道(我知道 n 个管道的实现更短,但出于某种原因这是特定要求)。
当使用 valgrind 检查内存泄漏时,我没有遇到任何问题,除非我使用 sort 命令,例如对于“ls | sort”输出以下消息:
==4903== HEAP SUMMARY:
==4903== in use at exit: 760 bytes in 17 blocks
==4903== total heap usage: 65 allocs, 48 frees, 8,533,744 bytes allocated
==4903==
==4903== 8 bytes in 1 blocks are definitely lost in loss record 1 of 6
==4903== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903== by 0x11ACFC: ??? (in /usr/bin/sort)
==4903== by 0x10D72A: ??? (in /usr/bin/sort)
==4903== by 0x48AE0B2: (below main) (libc-start.c:308)
==4903==
==4903== 32 bytes in 1 blocks are indirectly lost in loss record 2 of 6
==4903== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903== by 0x11ACFC: ??? (in /usr/bin/sort)
==4903== by 0x1166F6: ??? (in /usr/bin/sort)
==4903== by 0x10D860: ??? (in /usr/bin/sort)
==4903== by 0x48AE0B2: (below main) (libc-start.c:308)
==4903==
==4903== 48 bytes in 12 blocks are still reachable in loss record 3 of 6
==4903== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903== by 0x11ACFC: ??? (in /usr/bin/sort)
==4903== by 0x10C122: ??? (in /usr/bin/sort)
==4903== by 0x48AE0B2: (below main) (libc-start.c:308)
==4903==
==4903== 128 bytes in 1 blocks are still reachable in loss record 4 of 6
==4903== at 0x483B723: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903== by 0x483E017: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903== by 0x11AD69: ??? (in /usr/bin/sort)
==4903== by 0x10F0F2: ??? (in /usr/bin/sort)
==4903== by 0x10DA99: ??? (in /usr/bin/sort)
==4903== by 0x48AE0B2: (below main) (libc-start.c:308)
==4903==
==4903== 512 bytes in 1 blocks are indirectly lost in loss record 5 of 6
==4903== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903== by 0x11ACFC: ??? (in /usr/bin/sort)
==4903== by 0x10D89D: ??? (in /usr/bin/sort)
==4903== by 0x48AE0B2: (below main) (libc-start.c:308)
==4903==
==4903== 576 (32 direct, 544 indirect) bytes in 1 blocks are definitely lost in loss record 6 of 6
==4903== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4903== by 0x11ACFC: ??? (in /usr/bin/sort)
==4903== by 0x1166C7: ??? (in /usr/bin/sort)
==4903== by 0x10D860: ??? (in /usr/bin/sort)
==4903== by 0x48AE0B2: (below main) (libc-start.c:308)
==4903==
==4903== LEAK SUMMARY:
==4903== definitely lost: 40 bytes in 2 blocks
==4903== indirectly lost: 544 bytes in 2 blocks
==4903== possibly lost: 0 bytes in 0 blocks
==4903== still reachable: 176 bytes in 13 blocks
==4903== suppressed: 0 bytes in 0 blocks
==4903==
==4903== For lists of detected and suppressed errors, rerun with: -s
==4903== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
以上是 valgrind 运行 sort
后的输出,在 valgrind 运行 ls
后泄漏摘要是:
==4904== LEAK SUMMARY:
==4904== definitely lost: 0 bytes in 0 blocks
==4904== indirectly lost: 0 bytes in 0 blocks
==4904== possibly lost: 0 bytes in 0 blocks
==4904== still reachable: 20,381 bytes in 9 blocks
==4904== suppressed: 0 bytes in 0 blocks
==4904==
==4904== For lists of detected and suppressed errors, rerun with: -s
==4904== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
我可以忍受。
我尝试了几个不同的命令,有或没有管道 - 同样,sort
是唯一导致泄漏的命令。
当我退出程序时,valgrind 输出没有错误也没有内存泄漏,但这可能是由于最后的 exit(0)
调用。
我的问题是
- 这可能是
sort
的 valgrind 问题吗? - 如何进一步调试它?
我仔细检查了我程序中的每个 free
调用,并在网上寻找类似的问题,但没有找到任何问题。
(代码会根据需要更新)
更新
感谢 Bodo 的回答,我发现我的系统(Linux VMware 16 下的 Mint 20)sort
确实导致内存泄漏,或者至少在 valgrind 中存在内存泄漏.我使用了 ls | valgrind sort
建议来解决这个问题。
valgrind 输出:
==2966== HEAP SUMMARY:
==2966== in use at exit: 760 bytes in 17 blocks
==2966== total heap usage: 65 allocs, 48 frees, 8,533,744 bytes allocated
==2966==
==2966== LEAK SUMMARY:
==2966== definitely lost: 40 bytes in 2 blocks
==2966== indirectly lost: 544 bytes in 2 blocks
==2966== possibly lost: 0 bytes in 0 blocks
==2966== still reachable: 176 bytes in 13 blocks
==2966== suppressed: 0 bytes in 0 blocks
是的,valgrind
可以报告 /usr/bin/sort
程序中的问题。
你的 shell 可能使用 fork
为要执行的命令创建一个(或多个)进程,然后调用一些 exec..
函数来执行指定的程序.当 exec
函数成功时,进程不再是 运行 你的 shell 的代码,而是另一个程序的代码。
如果您指示valgrind
检查子进程,它会继续跟踪您的shell执行的程序,因此它也会报告这些程序中可能存在的错误。当然这些错误与你的shell.
要确认这一点,您可以比较类似命令行的结果,例如ls | sort
与 ls | cat
.
确认这一点的另一种方法是 运行 sort
与 valgrind
独立于您的简单 shell。你可以试试
ls | valgrind sort
如果 valgrind
和您要检查的程序的混合输出令人困惑,您可以使用 valgrind
的选项 --log-file=<filename>
选项将其输出重定向到一个文件。
如 Jabberwocky 的评论所述,为避免检查任何不相关的程序,您可以创建自己的(假)程序,这些程序没有内存泄漏和内存访问错误。要检查 shell 实现中的错误,您对 sort
的替换没有必要实际对行进行排序。唯一重要的是它不会从 valgrind
产生任何 errors/warnings 并且它的行为可能与 sort
相似,从 stdin
读取数据并将数据写入到stdout
,可选择延迟。