【问题标题】:What to do with error information after stack smashing堆栈粉碎后如何处理错误信息
【发布时间】:2010-02-21 19:53:47
【问题描述】:

我在 Linux 上的 C 程序遇到了一些问题。它在 Windows 上编译和运行得很好。 Linux 终端返回此信息:

*** stack smashing detected ***: ./student terminated       
======= Backtrace: =========                                
/lib/libc.so.6(__fortify_fail+0x4b)[0xb7e908ab]             
/lib/libc.so.6(__fortify_fail+0x0)[0xb7e90860]              
./student[0x8048c09]                                        
./student[0x80486dd]                                        
/lib/libc.so.6(__libc_start_main+0xe5)[0xb7dc0775]
./student[0x80485e1]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 00:11 11222      /mnt/win/POT03/Eclipse/student
0804a000-0804b000 r--p 00001000 00:11 11222      /mnt/win/POT03/Eclipse/student
0804b000-0804c000 rw-p 00002000 00:11 11222      /mnt/win/POT03/Eclipse/student
0804c000-0821a000 rw-p 0804c000 00:00 0          [heap]
b7da9000-b7daa000 rw-p b7da9000 00:00 0
b7daa000-b7eeb000 r-xp 00000000 75:00 116292     /lib/libc-2.9.so
b7eeb000-b7eed000 r--p 00141000 75:00 116292     /lib/libc-2.9.so
b7eed000-b7eee000 rw-p 00143000 75:00 116292     /lib/libc-2.9.so
b7eee000-b7ef1000 rw-p b7eee000 00:00 0
b7ef4000-b7f01000 r-xp 00000000 75:00 116275     /lib/libgcc_s.so.1
b7f01000-b7f02000 r--p 0000c000 75:00 116275     /lib/libgcc_s.so.1
b7f02000-b7f03000 rw-p 0000d000 75:00 116275     /lib/libgcc_s.so.1
b7f03000-b7f06000 rw-p b7f03000 00:00 0
b7f06000-b7f22000 r-xp 00000000 75:00 116288     /lib/ld-2.9.so
b7f22000-b7f23000 r--p 0001b000 75:00 116288     /lib/ld-2.9.so
b7f23000-b7f24000 rw-p 0001c000 75:00 116288     /lib/ld-2.9.so
bf8eb000-bf900000 rw-p bf8eb000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
Aborted

我可以用这些信息做什么来追踪问题?

【问题讨论】:

    标签: c linux memory stack-overflow


    【解决方案1】:

    使用调试信息编译您的程序,然后使用 valgrind 运行。

    gcc -g student.cpp -o student
    valgrind ./student
    

    尝试调试器:

    gcc -g student.cpp -o student
    gdb ./student
    run
         // wait for it to crash
    backtrace
    help // to figure out what else you can do
    

    【讨论】:

    • +1 for valgrind -- 在这里它可能比 gdb 有用得多。
    • 使用 GDB bt 的主要问题(我认为)是,粉碎的堆栈只会在返回时被注意到(块/函数的结尾)。所以你在回溯中看到的那一行输出将是右大括号,并在内部某处写入堆栈分配的缓冲区/数组。
    • 在这种情况下,这里的建议不太可能对其他人有那么大的帮助。首先,Valgrind 不太可能帮助您发现问题,因为问题是堆栈粉碎溢出——Valgrind 在处理堆栈分配的缓冲区方面不是很有效。其次,调试器将在您从分配缓冲区的函数返回的点为您提供堆栈跟踪,而不是在您写入缓冲区末尾的点处的堆栈跟踪。关闭堆栈保护器是一个糟糕的主意;如果您收到此消息,则说明您存在严重的安全漏洞。
    【解决方案2】:

    首先你需要一个地图文件。从映射文件中,您可以查找内存地址 (0x8048c09)。该函数实际上将从堆栈中地址之前的地址开始。从这里你知道你在哪个函数中崩溃了,并且对生成的汇编程序有一点了解,你可以弄清楚它在函数中崩溃了多远。然后您查看代码并尝试找出您做错了什么。

    失败了...使用调试器。然后,您将能够看到它坠毁的下落。从那里您甚至可以(如果您正在运行优化的构建,您将能够)查看您正在调用的确切内容以及参数是什么。然后,您可以查看导致问题的原因并阻止它发生。

    【讨论】:

    • 呸,汇编程序……相对较小的程序不值得那么努力。我将尝试使用调试器找出程序崩溃的位置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    • 2015-01-12
    • 1970-01-01
    相关资源
    最近更新 更多