Подтвердить что ты не робот

Почему я не могу вызвать ошибку seg?

ОК по какой-то причине у меня возникли проблемы с вызвавшей ошибку seg. Я хочу создать его так, чтобы я мог использовать gdb, чтобы узнать, как его отлаживать. Я пробовал оба примера из статьи в Википедии, но не работает.

Первый:

char *s = "Hello World!";
*s = 'H';

И второй пример:

int main(void) 
{
    main();
}

EDIT: Я использую Ubutnu 9.10 и g++ как мой компилятор. Может ли кто-нибудь показать мне код, гарантированный segfault?

4b9b3361

Ответ 1

Невозможно попытаться и надежно сделать это, указав разыменование.
Это связано с тем, что, как приложение обрабатывает память, может варьироваться от компилятора к компилятору и к одному и тому же компилятору с различными параметрами (режим отладки/выпуска по-разному).

Что вы можете сделать, это явно повысить segfault с помощью сигнала:

#include <signal.h>

int main()
{
    raise(SIGSEGV);
}

Ответ 2

Мой однострочный аромат:

*(char *)0 = 0;

Ответ 3

Обе вещи, которые вы делаете, будут генерировать "поведение undefined" в С++ (ну, вызов main() на самом деле явно запрещен). Нет никакой гарантии, что они вызовут seg faults - это будет зависеть от многих вещей, но в основном от платформы, на которой вы работаете, что вы не указали.

Фактически, любой предлагаемый способ причинения ошибки seg может работать или не работать. Это связано с тем, что ошибка seg почти всегда связана с концепцией поведения undefined С++.

Ответ 4

Самый короткий segfault когда-либо:

*(int*)0=0;

Ответ 5

int *hello = NULL;
printf(*hello);

или вы можете определить структуру (например, структуру HelloWorld)

HelloWorld *myWorld = NULL;
myWorld->world = "hello";

Ответ 6

Множество способов генерации segfault.

Подобно разыменованию плохого указателя:

char *s = (char *)0xDEADBEEF;
*s = 'a';

Ответ 7

В первом примере компилятор, вероятно, поместил строку в перезаписываемую память, поэтому при попытке изменить ее не возникает ошибка seg.

Во втором случае компилятор может оптимизировать вызов или может оптимизировать сам вызов до просто прыжка (поскольку это tail call), что означает, что стек фактически не растет с обратными адресами для каждого вызова, поэтому вы можете рекурсивно откладывать.

Но, как упоминал Нил в своем сообщении, любая из этих вещей приводит к "поведению undefined", поэтому код не требуется во время выполнения для генерации ошибки seg.

Ответ 8

char * ptr = 0;
*ptr = 1;

Segmentation fault

Ответ 9

В статье Википедии фактически перечислены три метода (один из которых - разыменование нулевого указателя); почему вы не попробовали этот?

Что касается того, почему два примера, которые вы пробовали, не соответствовали правильному ответу, как отмечали другие, это поведение undefined, поэтому может произойти что-то (в том числе не segfault). Но можно предположить, что причина, по которой первая форма не сработала для вас, заключается в том, что ваш компилятор или система слабо относятся к защите памяти. Что касается второго случая, то компилятор с хвостовым рекурсивным пониманием мог бы оптимизировать бесконечно рекурсивный цикл main и не переполнять стек.

Ответ 10

Если вы попытаетесь объединить две константы... вы получите один... по крайней мере, это простой способ...

strcat ( "a", "b" );

=)