如何找到堆栈粉碎的原因

时间:2011-01-04 18:15:00

标签: c debugging stack

我想弄清楚为什么我在使用FFMPEG库时会破坏堆栈。 我已经使用调试信息重新编译了FFMPEG,并且从回溯中,有问题的行是libavformat/mpegtsenc.c:800。但是,该行只是函数}的结束mpegts_write_pes大括号。

  • 到目前为止,我尝试了valgrind,但在使用memptr工具时崩溃了。
  • 尝试过efence但它似乎不适用于ffmpeg,因为它们使用自己的malloc / free例程来获取内存对齐的块
  • 在`mpegts_write_pes`声明的开头和结尾放置两个大数组

我相信函数返回地址被覆盖(因此gdb指向大括号)。

以下是源http://git.ffmpeg.org/?p=ffmpeg;a=blob;f=libavformat/mpegtsenc.c;hb=1a50ca867a57d7dc74d414b5adb9a0264c9a6c6c

的链接

那条线路将是814。

感谢

*** stack smashing detected ***: /home/victor/workspace/segmenter/segmenter terminated
======= Backtrace: =========
/lib/libc.so.6(__fortify_fail+0x50)[0x419970]
/lib/libc.so.6(+0xe591a)[0x41991a]
/home/victor/workspace/segmenter/segmenter[0x80be004]
======= Memory map: ========
00110000-0012c000 r-xp 00000000 08:01 158181     /lib/ld-2.12.1.so
0012c000-0012d000 r--p 0001b000 08:01 158181     /lib/ld-2.12.1.so
0012d000-0012e000 rw-p 0001c000 08:01 158181     /lib/ld-2.12.1.so
0012e000-0012f000 r-xp 00000000 00:00 0          [vdso]
0012f000-0013f000 r-xp 00000000 08:01 130866     /lib/libbz2.so.1.0.4
0013f000-00140000 r--p 0000f000 08:01 130866     /lib/libbz2.so.1.0.4
00140000-00141000 rw-p 00010000 08:01 130866     /lib/libbz2.so.1.0.4
00141000-00180000 r-xp 00000000 08:01 277294     /usr/lib/libmp3lame.so.0.0.0
00180000-00181000 r--p 0003e000 08:01 277294     /usr/lib/libmp3lame.so.0.0.0
00181000-00182000 rw-p 0003f000 08:01 277294     /usr/lib/libmp3lame.so.0.0.0
00182000-001b6000 rw-p 00000000 00:00 0
001b6000-001cb000 r-xp 00000000 08:01 158998     /lib/libpthread-2.12.1.so
001cb000-001cc000 ---p 00015000 08:01 158998     /lib/libpthread-2.12.1.so
001cc000-001cd000 r--p 00015000 08:01 158998     /lib/libpthread-2.12.1.so
001cd000-001ce000 rw-p 00016000 08:01 158998     /lib/libpthread-2.12.1.so
001ce000-001d0000 rw-p 00000000 00:00 0
001d0000-001d7000 r-xp 00000000 08:01 158382     /lib/librt-2.12.1.so
001d7000-001d8000 r--p 00006000 08:01 158382     /lib/librt-2.12.1.so
001d8000-001d9000 rw-p 00007000 08:01 158382     /lib/librt-2.12.1.so
001d9000-001ec000 r-xp 00000000 08:01 131016     /lib/libz.so.1.2.3.4
001ec000-001ed000 r--p 00012000 08:01 131016     /lib/libz.so.1.2.3.4
001ed000-001ee000 rw-p 00013000 08:01 131016     /lib/libz.so.1.2.3.4
001ee000-001fc000 r-xp 00000000 08:01 277205     /usr/lib/libfaac.so.0.0.0
001fc000-001fd000 r--p 0000d000 08:01 277205     /usr/lib/libfaac.so.0.0.0
001fd000-00200000 rw-p 0000e000 08:01 277205     /usr/lib/libfaac.so.0.0.0
00200000-00224000 r-xp 00000000 08:01 158974     /lib/libm-2.12.1.so
00224000-00225000 r--p 00023000 08:01 158974     /lib/libm-2.12.1.so
00225000-00226000 rw-p 00024000 08:01 158974     /lib/libm-2.12.1.so
00226000-002bf000 r-xp 00000000 08:01 277352     /usr/lib/libxvidcore.so.4.2
002bf000-002c0000 r--p 00098000 08:01 277352     /usr/lib/libxvidcore.so.4.2
002c0000-002ca000 rw-p 00099000 08:01 277352     /usr/lib/libxvidcore.so.4.2
002ca000-00334000 rw-p 00000000 00:00 0
00334000-0048b000 r-xp 00000000 08:01 158997     /lib/libc-2.12.1.so
0048b000-0048d000 r--p 00157000 08:01 158997     /lib/libc-2.12.1.so
0048d000-0048e000 rw-p 00159000 08:01 158997     /lib/libc-2.12.1.so
0048e000-00491000 rw-p 00000000 00:00 0
00491000-004ab000 r-xp 00000000 08:01 130901     /lib/libgcc_s.so.1
004ab000-004ac000 r--p 00019000 08:01 130901     /lib/libgcc_s.so.1
004ac000-004ad000 rw-p 0001a000 08:01 130901     /lib/libgcc_s.so.1
08048000-086b1000 r-xp 00000000 08:01 276922     /home/victor/workspace/segmenter/segmenter
086b1000-086b2000 r--p 00668000 08:01 276922     /home/victor/workspace/segmenter/segmenter
086b2000-086c3000 rw-p 00669000 08:01 276922     /home/victor/workspace/segmenter/segmenter
086c3000-08c99000 rw-p 00000000 00:00 0          [heap]
b7fec000-b7fef000 rw-p 00000000 00:00 0
b7ffd000-b8000000 rw-p 00000000 00:00 0
bffdf000-c0000000 rw-p 00000000 00:00 0          [stack]

Program received signal SIGABRT, Aborted.
0x0012e416 in __kernel_vsyscall ()
(gdb) where
#0  0x0012e416 in __kernel_vsyscall ()
#1  0x0035e941 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#2  0x00361e42 in abort () at abort.c:92
#3  0x00396305 in __libc_message (do_abort=2, fmt=0x46c36a "*** %s ***: %s terminated\n") at ../sysdeps/unix/sysv/linux/libc_fatal.c:189
#4  0x00419970 in __fortify_fail (msg=<value optimized out>) at fortify_fail.c:32
#5  0x0041991a in __stack_chk_fail () at stack_chk_fail.c:29
#6  0x080be004 in mpegts_write_pes (s=<value optimized out>, st=<value optimized out>, payload=<value optimized out>, payload_size=0, pts=147149074, dts=17992800) at libavformat/mpegtsenc.c:800
#7  0x080be2ed in mpegts_write_packet (s=0x8bcf3d0, pkt=0xbffff1c0) at libavformat/mpegtsenc.c:883
#8  0x080ff9aa in av_interleaved_write_frame (s=0x8bcf3d0, pkt=0xbffff26c) at libavformat/utils.c:2917
#9  0x080704d1 in main (argc=6, argv=0xbffff414) at segmenter.c:662
(gdb) 

`

1 个答案:

答案 0 :(得分:6)

如果查看调试器中的堆栈,覆盖返回地址的数据是否可识别?如果是(例如字符串),那可以帮助您缩小犯罪作者的范围。

另一个尝试的好方法是在调试器中使用观察点。如果崩溃是可重现的,则可以获取被覆盖的堆栈值的地址。假设它是一致的,您可以在该地址设置观察点并跟踪该位置的所有写入。在任何时候,你都会找到不应该写的代码。