【问题标题】:Segfault in shared library. How to debug?共享库中的段错误。如何调试?
【发布时间】:2012-05-07 08:29:33
【问题描述】:

我在我的程序中使用了一个库 (libnids)。我从继续运行的库中调用函数 nids_run,直到我明确调用 nids_exit。

我的程序处理 SIGINT 并调用 nids_exit。中断处理程序正常返回,但有时在库将控制权返回给我的程序之前,我收到一个段错误。这是 GDB 给我的回溯:

#0  0x00007ffff6498b2a in ?? () from /usr/lib/libpcap.so.1
#1  0x00007ffff649bee1 in pcap_loop () from /usr/lib/libpcap.so.1
#2  0x00007ffff77bae66 in nids_run () from /usr/lib/libnids.so.1.24
#3  0x0000000000401e92 in main (argc=3, argv=0x7fffffffebf8) at eve.c:139

找出问题的最佳策略是什么?我应该以某种方式调试 libpcap 吗?

更新: 正如 ArjunShankar 所建议的那样,我在 Valgrind 下运行我的程序。这是输出的一部分:

==7504== Invalid read of size 4
==7504==    at 0x654EDC1: ??? (in /usr/lib/libpcap.so.1.2.1)
==7504==    by 0x6551EE0: pcap_loop (in /usr/lib/libpcap.so.1.2.1)
==7504==    by 0x5250E65: nids_run (in /usr/lib/libnids.so.1.24)
==7504==    by 0x401E91: main (eve.c:139)
==7504==  Address 0x70eece8 is 40 bytes inside a block of size 768 free'd
==7504==    at 0x4C29A9E: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7504==    by 0x5250DEB: nids_exit (in /usr/lib/libnids.so.1.24)
==7504==    by 0x4026D0: signal_handler (signalhandling.c:17)
==7504==    by 0x5B6313F: ??? (in /lib/libpthread-2.15.so)
==7504==    by 0x5B5FC60: pthread_cond_timedwait@@GLIBC_2.3.2 (in /lib/libpthread-2.15.so)
==7504==    by 0x58E37D4: g_cond_wait_until (in /usr/lib/libglib-2.0.so.0.3200.1)
==7504==    by 0x587E2C0: ??? (in /usr/lib/libglib-2.0.so.0.3200.1)
==7504==    by 0x587E909: g_async_queue_timeout_pop (in /usr/lib/libglib-2.0.so.0.3200.1)
==7504==    by 0x4022D2: analyzer_thread_func (analyzers.c:93)
==7504==    by 0x58CA0C4: ??? (in /usr/lib/libglib-2.0.so.0.3200.1)
==7504==    by 0x5B5BE0D: start_thread (in /lib/libpthread-2.15.so)

更多输出可以在以下位置找到:http://pastebin.com/93gkSScS

【问题讨论】:

  • 试试valgrind
  • 该错误不必在 libpcap 中(可能不是 -- select 没有损坏等等)。如果您的程序碰巧占用了库使用的内存,这可能是结果。
  • 我从来没有真正怀疑过 libpcap 本身。问题是,我如何找出导致问题的我做错了什么。 @ArjunShankar 我以前从未使用过 valgrind,但这部分输出可能是相关的:pastebin.com/93gkSScS
  • @Homayoon - 我认为您应该将一些 valgrind 输出粘贴到您的问题中。似乎很中肯。并且无法保证 pastebin.com 将永远运行。

标签: c debugging gdb segmentation-fault shared-libraries


【解决方案1】:

Valgrind 输出显示libpcap(从内部nids_run)尝试在nids_exitfrees 之后读取内存位置:

例如:

==7504== Invalid read of size 4
==7504==    at 0x654EDC1: ??? (in /usr/lib/libpcap.so.1.2.1)
==7504==    by 0x6551EE0: pcap_loop (in /usr/lib/libpcap.so.1.2.1)
==7504==    by 0x5250E65: nids_run (in /usr/lib/libnids.so.1.24)

Address 0x70eece8 is 40 bytes inside a block of size 768 free'd
==7504==    at 0x4C29A9E: free
==7504==    by 0x5250DEB: nids_exit (in /usr/lib/libnids.so.1.24)

所以这是一个 768 大小的块,即nids_exit 中的freed,随后在nids_run 中读取(显然还没有停止)。

所有其他错误都类似(nids_exitfrees 一个块,nids_run 继续尝试使用它。

这意味着:您要么没有正确使用 libnids (nids_run/nids_exit),要么libnids 中存在错误。

【讨论】:

  • 这似乎是 libnids 中的一个错误。我创建了一个似乎可以解决问题的补丁。在将其标记为答案之前,我正在等待作者发表评论,尽管我很确定无论如何这都是正确的答案(除非有人想出更完整的东西)。谢谢。
  • @Homayoon - 出于好奇,您能分享一个补丁链接吗?我下载了libnids的源码,还没看。
  • 当然。这是:pastebin.com/GVrUbRmh。我不太确定这是否是正确的做法,尽管它似乎可以解决我的问题。即使它是正确的,也可能需要做更多的工作才能使事情完全正确,但我会把它留给作者。我已经使用 libnids 一两个月了,忽略这个问题,它似乎是一段很好的代码。
猜你喜欢
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 2010-11-13
  • 2014-12-25
  • 2014-04-15
  • 2010-10-22
相关资源
最近更新 更多