【发布时间】:2011-04-30 19:23:08
【问题描述】:
我有以下 C 应用程序:
#include <stdio.h>
void smash()
{
int i;
char buffer[16];
for(i = 0; i < 17; i++) // <-- exceeds the limit of the buffer
{
buffer[i] = i;
}
}
int main()
{
printf("Starting\n");
smash();
return 0;
}
我使用以下版本的 gcc 进行了交叉编译:
armv5l-linux-gnueabi-gcc -v
Using built-in specs.
Target: armv5l-linux-gnueabi
Configured with: /home/tarjeif/svn/builder/build_armv5l-linux-gnueabi/gcc-4.4.1/gcc-4.4.1/configure --target=armv5l-linux-gnueabi --host=i486-linux-gnu --build=i486-linux-gnu --prefix=/home/tarjeif/svn/builder/build_armv5l-linux-gnueabi/toolchain --with-sysroot=/home/tarjeif/svn/builder/build_armv5l-linux-gnueabi/toolchain --with-headers=/home/tarjeif/svn/builder/build_armv5l-linux-gnueabi/toolchain/include --enable-languages=c,c++ --with-gmp=/home/tarjeif/svn/builder/build_armv5l-linux-gnueabi/gmp-5.0.0/gmp-host-install --with-mpfr=/home/tarjeif/svn/builder/build_armv5l-linux-gnueabi/mpfr-2.4.2/mpfr-host-install --disable-nls --disable-libgcj --disable-libmudflap --disable-libssp --disable-libgomp --enable-checking=release --with-system-zlib --with-arch=armv5t --with-gnu-as --with-gnu-ld --enable-shared --enable-symvers=gnu --enable-__cxa_atexit --disable-nls --without-fp --enable-threads
Thread model: posix
gcc version 4.4.1 (GCC)
这样调用:
armv5l-linux-gnueabi-gcc -ggdb3 -fstack-protector-all -O0 test.c
在目标上运行时,它会输出:
Starting
*** stack smashing detected ***: ./a.out terminated
Aborted (core dumped)
我在 gdb 中加载生成的核心转储,产生以下回溯:
GNU gdb (GDB) 7.0.1
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i486-linux-gnu --target=armv5l-linux-gnueabi".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/andersn/workspace/stacktest/a.out...done.
Reading symbols from /home/andersn/workspace/stacktest/linux/toolchain/lib/libc.so.6...done.
Loaded symbols for /home/andersn/workspace/stacktest/linux/toolchain/lib/libc.so.6
Reading symbols from /home/andersn/workspace/stacktest/linux/toolchain/lib/ld-linux.so.3...done.
Loaded symbols for /home/andersn/workspace/stacktest/linux/toolchain/lib/ld-linux.so.3
Reading symbols from /home/andersn/workspace/stacktest/linux/toolchain /lib/libgcc_s.so.1...done.
Loaded symbols for /home/andersn/workspace/stacktest/linux/toolchain/lib/libgcc_s.so.1
Core was generated by `./a.out'.
Program terminated with signal 6, Aborted.
#0 0x40052d4c in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:67
67 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
in ../nptl/sysdeps/unix/sysv/linux/raise.c
(gdb) bt
#0 0x40052d4c in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:67
#1 0x40054244 in *__GI_abort () at abort.c:92
#2 0x40054244 in *__GI_abort () at abort.c:92
#3 0x40054244 in *__GI_abort () at abort.c:92
#4 0x40054244 in *__GI_abort () at abort.c:92
#5 0x40054244 in *__GI_abort () at abort.c:92
#6 0x40054244 in *__GI_abort () at abort.c:92
... and so on ...
现在,问题来了: 我完全无法从 GDB 中找到导致堆栈粉碎的函数,即使smash() 函数不会覆盖堆栈的任何结构数据,只会覆盖堆栈保护器本身。我该怎么办?
【问题讨论】:
-
我认为您的“等等”可能遗漏了一些重要信息。 __GI_abort 真的是栈底吗?
-
我尝试继续 GDB 输出并在我放弃之前达到了 #11087.... 所有相同的帧。
-
你明确地破坏了堆栈——不要指望核心文件有整齐的链接调用帧:)
-
我认为堆栈应该是完全有效的,因为我只超出了合法范围的 1 个字节,这就是堆栈保护器的位置
-
@Nikolai N Fetissov:在 gcc (x86_64 4.4.5) 上按照上述配方在 Linux AMD64 (2.6.35) 上进行测试(循环上升到 31 和 ulimit -c 无限制)给出了一个带有 gdb (7.2) 正确解析的堆栈帧的核心转储。