Невозможно найти функцию разрушения стека с помощью GDB - PullRequest
5 голосов
/ 26 октября 2010

У меня есть следующее приложение 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 () не перезаписывает какие-либо структурные данные стека, а только сам защитник стека. Что мне делать?

Ответы [ 3 ]

8 голосов
/ 27 октября 2010

Проблема в том, что версия GCC, скомпилировавшая вашу целевую библиотеку libc.so.6, содержит ошибки и не выдает правильные дескрипторы размотки для __GI_raise.При неправильных дескрипторах разматывания GDB попадает в цикл при разматывании стека.

Вы можете проверить дескрипторы разматывания с помощью

readelf -wf /home/andersn/workspace/stacktest/linux/toolchain/lib/libc.so.6

Я ожидаю, что вы получите точно такой же результат в GDB от любоговызов программы прерывается, например,

#include <stdlib.h>
void foo() { abort(); }
int main() { foo(); return 0; }

К сожалению, вы ничего не можете сделать, кроме как попытаться создать более новую версию GCC, а затем восстановить с ней весь «мир».

2 голосов
/ 27 октября 2010

Это не тот случай, когда GDB всегда может решить, что случилось с разбитым стеком, даже с -fstack-protector-all (и даже с -Wstack-protector, чтобы предупредить о функциях с кадрами, которые не были защищены). Пример .

В этих случаях защитник стека выполнил свою работу (убил некорректно работающее приложение), но не оказал отладчику никакой пользы.(Классическим примером является разбивка стека, когда запись произошла с достаточно большим шагом, чтобы он перепрыгнул через канарейку.) В этих случаях может возникнуть необходимость двоичного поиска по коду через точки останова, чтобы сузить область кода, вызывающуюразбить, затем один шаг через разбить, чтобы увидеть, как это произошло.

0 голосов
/ 26 октября 2010

Вы пытались разрешить эту жалобу: "../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.", чтобы посмотреть, поможет ли на самом деле разрешение символов?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...