Обнаружено разбиение стека

Я выполняю мой файл a.out. После выполнения программа запускается некоторое время, а затем выходит с сообщением:

**** stack smashing detected ***: ./a.out terminated*
*======= Backtrace: =========*
*/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)Aborted*

Какими могут быть возможные причины для этого и как его исправить?

145
28 авг. '09 в 11:17
источник поделиться
5 ответов

Stack Smashing здесь фактически вызван механизмом защиты, используемым gcc для обнаружения ошибок переполнения буфера. Например, в следующем фрагменте:

#include <stdio.h>

void func()
{
    char array[10];
    gets(array);
}

int main(int argc, char **argv)
{
    func();
}

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

Чтобы получить некоторое представление, вы можете попробовать отключить эту защиту gcc, используя параметр -fno-stack-protector во время компиляции. В этом случае вы получите другую ошибку, скорее всего, ошибку сегментации, поскольку вы пытаетесь получить доступ к нелегальной ячейке памяти. Обратите внимание, что -fstack-protector всегда должен быть включен для релизов, так как это функция безопасности.

Вы можете получить некоторую информацию о точке переполнения, запустив программу с помощью отладчика. Valgrind не работает с ошибками, связанными с стеком, но, как и отладчик, он может помочь вам определить местоположение и причину сбоя.

217
28 авг. '09 в 17:44
источник

Связанные вопросы


Похожие вопросы

Посмотрите на следующую ситуацию:

ab@cd-x:$ cat test_overflow.c 
#include <stdio.h>
#include <string.h>

int check_password(char *password){
    int flag = 0;
    char buffer[20];
    strcpy(buffer, password);

    if(strcmp(buffer, "mypass") == 0){
        flag = 1;
    }
    if(strcmp(buffer, "yourpass") == 0){
        flag = 1;
    }
    return flag;
}

int main(int argc, char *argv[]){
    if(argc >= 2){
        if(check_password(argv[1])){
            printf("%s", "Access granted\n");
        }else{
            printf("%s", "Access denied\n");
        }
    }else{
        printf("%s", "Please enter password!\n");
    }
}
ab@cd-x:$ gcc -g -fno-stack-protector test_overflow.c 
ab@cd-x:$ ./a.out mypass
Access granted
ab@cd-x:$ ./a.out yourpass
Access granted
ab@cd-x:$ ./a.out wepass
Access denied
ab@cd-x:$ ./a.out wepassssssssssssssssss
Access granted

ab@cd-x:$ gcc -g -fstack-protector test_overflow.c 
ab@cd-x:$ ./a.out wepass
Access denied
ab@cd-x:$ ./a.out mypass
Access granted
ab@cd-x:$ ./a.out yourpass
Access granted
ab@cd-x:$ ./a.out wepassssssssssssssssss
*** stack smashing detected ***: ./a.out terminated
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)[0xce0ed8]
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x0)[0xce0e90]
./a.out[0x8048524]
./a.out[0x8048545]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xc16b56]
./a.out[0x8048411]
======= Memory map: ========
007d9000-007f5000 r-xp 00000000 08:06 5776       /lib/libgcc_s.so.1
007f5000-007f6000 r--p 0001b000 08:06 5776       /lib/libgcc_s.so.1
007f6000-007f7000 rw-p 0001c000 08:06 5776       /lib/libgcc_s.so.1
0090a000-0090b000 r-xp 00000000 00:00 0          [vdso]
00c00000-00d3e000 r-xp 00000000 08:06 1183       /lib/tls/i686/cmov/libc-2.10.1.so
00d3e000-00d3f000 ---p 0013e000 08:06 1183       /lib/tls/i686/cmov/libc-2.10.1.so
00d3f000-00d41000 r--p 0013e000 08:06 1183       /lib/tls/i686/cmov/libc-2.10.1.so
00d41000-00d42000 rw-p 00140000 08:06 1183       /lib/tls/i686/cmov/libc-2.10.1.so
00d42000-00d45000 rw-p 00000000 00:00 0 
00e0c000-00e27000 r-xp 00000000 08:06 4213       /lib/ld-2.10.1.so
00e27000-00e28000 r--p 0001a000 08:06 4213       /lib/ld-2.10.1.so
00e28000-00e29000 rw-p 0001b000 08:06 4213       /lib/ld-2.10.1.so
08048000-08049000 r-xp 00000000 08:05 1056811    /dos/hacking/test/a.out
08049000-0804a000 r--p 00000000 08:05 1056811    /dos/hacking/test/a.out
0804a000-0804b000 rw-p 00001000 08:05 1056811    /dos/hacking/test/a.out
08675000-08696000 rw-p 00000000 00:00 0          [heap]
b76fe000-b76ff000 rw-p 00000000 00:00 0 
b7717000-b7719000 rw-p 00000000 00:00 0 
bfc1c000-bfc31000 rw-p 00000000 00:00 0          [stack]
Aborted
ab@cd-x:$ 

Когда я отключил защитник стека, никаких ошибок не обнаружено, что должно было произойти, когда я использовал "./a.out wepassssssssssssssssssss"

Таким образом, чтобы ответить на ваш вопрос выше, было показано сообщение "** обнаружение разбитого стека: xxx", потому что ваш защитник стека был активным и обнаружил, что в вашей программе есть переполнение стека.

Просто узнайте, где это происходит, и исправьте его.

12
06 марта '10 в 9:45
источник

Вы можете попробовать отладить проблему, используя valgrind:

Распределение Valgrind в настоящее время включает шесть инструментов качества производства: детектор ошибок памяти, два потока детекторы ошибок, кеш и профилировщик прогноза ветвления, call-graph, генерирующий кеширующий профилировщик, и профилировщик кучи. Он также включает два экспериментальных инструмента: переполнение кучи/стека/глобального массива детектор и базовый блок SimPoint векторный генератор. Он работает на следующие платформы: X86/Linux, AMD64/Linux, PPC32/Linux, PPC64/Linux, и X86/Darwin (Mac OS X).

7
28 авг. '09 в 11:24
источник

Это означает, что вы написали некоторые переменные в стеке незаконным способом, скорее всего, в результате переполнение буфера.

3
28 авг. '09 в 12:05
источник

Я получил эту ошибку, используя malloc(), чтобы выделить некоторую память для структуры *, потратив некоторую эту отладку кода, я, наконец, использовал функцию free() для освобождения выделенной памяти, а затем сообщение об ошибке исчезло:)

0
03 сент. '17 в 20:16
источник

Посмотрите другие вопросы по меткам или Задайте вопрос