Який найпростіший спосіб зробити збій програми C ++?


318

Я намагаюся зробити програму Python, яка взаємодіє з різними аварійними процесами (це не в моїх руках). На жаль, програма, з якою я взаємодію, навіть не дає краху надійно! Тому я хочу зробити швидку програму C ++, яка спеціально виходить з ладу, але я насправді не знаю найкращого та найкоротшого способу зробити це, хтось знає, що між моїм:

int main() {
    crashyCodeGoesHere();
}

щоб надійно вийти з ладу моя програма C ++


4
Ви можете використовувати вбудовану збірку для спроби виконання прихованих інструкцій:asm { cli; };
Нейт Коппенгавер

@aitchnyu Я думаю, що в застосуванні відповідей на кожне питання є різниця. (FYI: Я не проголосував за жодне питання)
Ендрю Барбер

будь-який коментар про викид винятку, тоді як один вже пропонує ?? plz chk моя відповідь нижче anc коментар
Abhinav

4
Redis використовує наступний *((char*)-1) = 'x';код, щоб викликати збій, щоб налагодити читати докладніше у моїй відповіді тут
Шафік Ягмур

Я знайшов це питання під час пошуку тестового випадку для системи звітування про аварії. Мені потрібно було змусити збій під час звичайного виконання, щоб викликати репортера аварії та надсилання дампів стека. Дякую!
Корі Трез

Відповіді:


264

Ця abort()функція, мабуть, найкраща для вас. Він є частиною стандартної бібліотеки С і визначається як "спричинення ненормального припинення програми" (наприклад, фатальна помилка або збій).


14
Зауважте, що аварія abort()не викликає деструкторів чи atexitфункцій, хоча це, ймовірно, тут не має значення.
Xeo

139
@Xeo: Якби він викликав деструктори і atexits, це не буде аварією, чи не так?
стипендіати доналу

Оскільки abort()правильна відповідь, то чи повинен бути "вихід (-1);` прийнятним?
asir6

9
Ні, оскільки це не спричиняє аварії, просто повідомляє про те, що щось неможливо зробити.
boatcoder

Windows. GCC-5.4.0. Вихідний код: 3. Немає вікна повідомлення про помилку. Повідомлення консолі: "Ця програма вимагає, щоб час виконання програми було скасовано незвичним способом. Для отримання додаткової інформації зв'яжіться зі службою підтримки програми."
Вадим

113

Спробуйте:

raise(SIGSEGV);  // simulates a standard crash when access invalid memory
                 // ie anything that can go wrong with pointers.

Знайдено в:

#include <signal.h>

3
Це більше, ніж просто визначено реалізацією - сигнал можна вловлювати signal(). Більшість розумних програм, однак, не мають.
duskwuff -inactive-

12
Він вийде з ладу точно так само, як і звичайний SIGSEGV всередині програми (саме так відбувається збій більшості програм). Це добре визначено, що він робить (за замовчуванням він закриває додаток і створює основний файл). Так, ви можете встановити обробник, але якщо у вас є, ви не хочете перевірити це аналогічно !!
Мартін Йорк

1
+1 для raise(). Це дозволяє вам перевірити на тону різних винятків, просто змінивши аргумент.

3
улюблене рішення, однак це залежить від платформи.
Надім Фархат

@NadimFarhat: Яким способом. Сигнал - це сигнал на всіх платформах.
Мартін Йорк

74

Поділ на нуль призведе до краху програми:

int main()
{
    return 1 / 0;
}

29
Залежно від того, наскільки розумний ваш компілятор, це буде спіймано під час компіляції. Я знаю, що візуальна студія 2008 не збиратиме це для c ++ або c #.
АйданО

2
Я скомпілював і запустив його, чи хочете ви, щоб я наклав вам .exe?
Roee Gavirel

1
У конфігурації релізів у останніх версіях Visual Studio, як-от 2010 року, вона працюватиме без проблем. Я думаю, це деяка оптимізація.
tedyyu

2
iirc це не врізається на руку
шерпя

2
Це невизначена поведінка і не гарантується крахом. Часто компілятори вважають, що невизначена поведінка недосяжна. Це може призвести до того, що тіло mainповністю видалено, включаючи retінструкцію. Виконання може просто потрапити в наступну функцію.
usr

64
*((unsigned int*)0) = 0xDEAD;

54
Це не гарантовано вийде з ладу.
програміст Windows

8
@Windowsprogrammer: ні, це не гарантується . Але яка розумна ОС не зупиняє програму, яка намагається отримати доступ до пам'яті за адресою 0?
Йоахім Зауер

29
"Але яка розумна ОС не зупиняє програму, яка намагається отримати доступ до пам'яті за адресою 0?" - Це насправді не те, що ви хочете запитати, але я все одно відповім. У деяких комп’ютерах є оперативна пам’ять за адресою 0, і програмі цілком важливо зберігати там значення. Більш значимим питанням було б "Яка ОС не зупиняє програму, що отримує доступ до пам'яті за адресою, що реалізація C ++ зарезервована для нульового вказівника?" У такому випадку я не знаю жодного. Але в оригінальній програмі мова йде про мову C ++, а не про ОС.
програміст Windows

6
Його невизначена поведінка. Цілком нормально для цього нічого не робити. Машина, яка не вийде з ладу: все, що працює з процесором серії Z80 (я припускаю (мій Z80a нічого не робить)).
Мартін Йорк

28
Незважаючи на те, що цей збій не гарантовано , це один з найпоширеніших видів збоїв у C ++. Тож якщо ви хочете імітувати аварію, це "автентичний" спосіб зробити це :)
Кріс Берт-Браун

53

Що ж, ми перебуваємо в переповненні стека , чи ні?

for (long long int i = 0; ++i; (&i)[i] = i);

(Не гарантується збій за будь-якими стандартами, але жоден із запропонованих відповідей, включаючи прийнятий, оскільки SIGABRTміг би бути спійманий у будь-якому випадку. На практиці це буде повсюдно.)


4
Я бачу, що це смішно в системі з незахищеними кодовими сторінками, і ви перезаписуєте свою програму деяким кодом, який випадково є нескінченним циклом, який нічого не робить. Високо вкрай дуже вкрай малоймовірно, але потенційно можливо.
Мартін Йорк

@Loki: Що робити, якщо він просто читається з кожного 4000-го байта? Чи буде це менше шансів на збій? Однозначно менш небезпечно.
Mooing Duck

70
Цей алгоритм збоїв не є O (1)!
Антон Барковський

@MooingDuck: Я просто роблю смішний коментар. Не сприймайте це серйозно :-) Але було б цікаво, якби хтось знайшов послідовність інструкцій, які робили щось смішне.
Мартін Йорк

1
@LokiAstari: ти абсолютно правий. Я (&i)[i] += !iзамість цього думав , але побоювався, що компілятор може бути досить розумним і хочу оптимізувати це. :-)
sam hocevar

35
 throw 42;

Просто відповідь ... :)


1
Windows. GCC-5.4.0. Вихідний код: 3. Немає вікна повідомлення про помилку. Повідомлення консолі: "Завершити виклик після викидання екземпляра" int "Ця програма вимагає, щоб час виконання нею припинив її незвичним способом. Для отримання додаткової інформації зв'яжіться зі службою підтримки програми."
Вадим

15

assert(false); дуже добре теж.

Відповідно до ISO / IEC 9899: 1999 гарантується збій, коли NDEBUG не визначено:

Якщо NDEBUG визначений [...], макрос затвердження визначається просто як

#define assert(ignore) ((void)0)

Макрос затвердження перевизначається відповідно до поточного стану NDEBUG кожного разу, коли він включається.

[...]

Макрос затвердження встановлює діагностичні тести в програми; [...] якщо вираз (який має скалярний тип) є хибним [...]. Потім він викликає функцію переривання.


Я неясно пам'ятаю, як VC 2005 поводився по-різному між налагодженням та релізами з твердженнями?
Том Керр

8
@Tom assertприрівнюється до ((void)0)режиму випуску.
Сет Карнегі

2
@SethCarnegie Ви не бачите, що з цим не так - лише якщо визначений NDEBUG не буде збій? Відповідь Данса була досить справедливою IMHO.
Адріан Корніш

@AdrianCornish Я відповідав лише на запитання Тома Керра, не кажучи, що ця відповідь була неправильною. Я не спростував цієї відповіді.
Сет Карнегі

3
Я не знаю, чому він зробив би "реліз" складання цього тестового коду.
Джоель Б

11

Оскільки збій є симптомом виклику невизначеної поведінки, а оскільки виклик невизначеної поведінки може призвести до чого завгодно, в тому числі до збоїв, я не думаю, що ви дійсно хочете зірвати вашу програму, а просто впадете в налагоджувач. Напевно, найбільш портативний спосіб зробити це abort().

Хоча raise(SIGABRT)має той же ефект, писати, безумовно, більше. Однак обидва способи можуть бути перехоплені, встановивши обробник сигналу для SIGABRT. Отже, залежно від вашої ситуації, вам може знадобитися підняти ще один сигнал. SIGFPE, SIGILL, SIGINT, SIGTERMАбо SIGSEGVможе бути шлях, але всі вони можуть бути перехоплені.

Коли ви можете бути невідповідними, ваш вибір може бути ще ширшим, як, наприклад, використання SIGBUSв Linux.


1
Я дуже сумніваюся, що він хоче, щоб налагоджений налагоджувач. Він, схоже, хоче перевірити, що відбувається, коли абонент програми, що виходить з ладу, отримує збій, відправлений на його шляху. Що дуже розумно.
Дональні стипендіати

9

Єдиний спалах, який я мав, - це функція abort () :

Він припиняє процес з ненормальним завершенням програми. Він генерує сигнал SIGABRT , який за замовчуванням змушує програму припиняти повернення невдалого коду помилки припинення в середовище хоста. Програма припиняється без виконання деструкторів для об'єктів автоматичної або статичної тривалості зберігання. , і не викликаючи жодної функції atexit (яка викликається випуском () до завершення програми). Він ніколи не повертається до свого абонента.


9

Відповідь конкретна для платформи і залежить від ваших цілей. Але ось функція збоїв у Mozilla Javascript, яка, на мою думку, ілюструє безліч труднощів у виконанні цієї роботи:

static JS_NEVER_INLINE void
CrashInJS()
{
    /*
     * We write 123 here so that the machine code for this function is
     * unique. Otherwise the linker, trying to be smart, might use the
     * same code for CrashInJS and for some other function. That
     * messes up the signature in minidumps.
     */

#if defined(WIN32)
    /*
     * We used to call DebugBreak() on Windows, but amazingly, it causes
     * the MSVS 2010 debugger not to be able to recover a call stack.
     */
    *((int *) NULL) = 123;
    exit(3);
#elif defined(__APPLE__)
    /*
     * On Mac OS X, Breakpad ignores signals. Only real Mach exceptions are
     * trapped.
     */
    *((int *) NULL) = 123;  /* To continue from here in GDB: "return" then "continue". */
    raise(SIGABRT);  /* In case above statement gets nixed by the optimizer. */
#else
    raise(SIGABRT);  /* To continue from here in GDB: "signal 0". */
#endif
}

2
Ви повинні повністю відмовитися від цього і використовувати натомість jQuery.
Томас Веллер

1
Це невизначена поведінка і не гарантується крахом. Часто компілятори вважають, що невизначена поведінка є недосяжною. У такому випадку принаймні рядок збоїв буде видалений, а також може бути інший код.
usr

8

Я бачу, що тут розміщено багато відповідей, які потраплять у щасливі випадки, коли можна виконати роботу, але жоден з них не на 100% детермінований для краху. Деякі вийдуть з ладу на одному апаратному забезпеченні та ОС, інші не будуть. Однак існує стандартний спосіб, згідно з офіційним стандартом C ++, щоб зробити його крахом.

Цитуючи з C ++ стандарту ISO / IEC 14882 §15.1-7 :

Якщо механізм обробки винятків, після завершення ініціалізації об'єкта винятку, але до активації обробника для винятку, викликає функцію, яка виходить через виняток, викликається std :: термінація (15.5.1).

struct C {
    C() { }
    C(const C&) {
        if (std::uncaught_exceptions()) {
            throw 0; // throw during copy to handler’s exception-declaration object (15.3)
        }
    }
};
int main() {
    try {
    throw C(); // calls std::terminate() if construction of the handler’s
    // exception-declaration object is not elided (12.8)
    } catch(C) { }
}

Я написав невеликий код, щоб продемонструвати це, і його можна знайти та спробувати на Ideone тут .

class MyClass{
    public:
    ~MyClass() throw(int) { throw 0;}
};

int main() {
  try {
    MyClass myobj; // its destructor will cause an exception

    // This is another exception along with exception due to destructor of myobj and will cause app to terminate
     throw 1;      // It could be some function call which can result in exception.
  }
  catch(...)
  {
    std::cout<<"Exception catched"<<endl;
  }
  return 0;
}

ISO / IEC 14882 §15.1 / 9 згадує кидок без спроб блоку, що призводить до неявного виклику перервати:

Якщо зараз не обходиться жоден виняток, виконуючи вираз викиду без викликів операнда std :: terminate ()

До інших належать: кидок із руйнівника: ISO / IEC 14882 §15.2 / 3


7
*( ( char* ) NULL ) = 0;

Це призведе до помилки сегментації.


10
Це не гарантовано вийде з ладу.
програміст Windows

23
"Що буде натомість?" - Натомість все може статися. Поведінка не визначена, тому реалізація може призначити 0 одній зі змінних вашої програми, або вона може призначити 42 одній зі змінних вашої програми, або вона може відформатувати ваш жорсткий диск і продовжити виконання вашої програми.
програміст Windows

7
(продовження настрою "Програміст Windows") Це може змусити комп'ютер вибухнути, або може призвести до того, що він оживе і захопить людство. або ... він зазнає краху на 99,9% і визначається як "невизначена поведінка", оскільки ніхто не хоче брати на себе відповідальність за це.
Roee Gavirel

1
Насправді, це не гарантує навіть не визначену поведінку - це може повністю визначитись і працювати належним чином. Розглянемо цей код: pastebin.com/WXCtTiDD (Випробувано на Linux як root, ви можете це зробити і як некорінний користувач, якщо зробите деякі зміни конфігурації wiki.debian.org/mmap_min_addr )
cha0site

2
@ cha0site: Стандартом гарантується невизначене поведінку, оскільки це відкликає нульовий покажчик. Яка б поведінка, яку ви спостерігали в Linux, допустима під парасолькою "невизначена поведінка"
Бен Войгт

6

Цього немає:

int main = 42;

1
Так; але це робить щось вражаюче, коли ви запускаєте його.
Джошуа

5

Що з переповненням стека викликом методу рекурсивного методу?

#include <windows.h>
#include <stdio.h>

void main()
{
    StackOverflow(0);
}

void StackOverflow(int depth)
{
    char blockdata[10000];
    printf("Overflow: %d\n", depth);
    StackOverflow(depth+1);
}

Дивіться оригінальний приклад в Microsoft KB


4
Що заважає достатньо розумному компілятору оптимізувати як невикористаний розподіл стека, так і хвостовий виклик?
JB.

@JB: на жаль, поняття не маю, бо не знайомий з існуючою логікою оптимізації компіляторів
sll

8
Ну, складений тут з gcc 4.6.0 на рівнях оптимізації -O2 і вище, він оптимізує просто чудово. Потрібно -O1 або нижче до segfault.
JB.

@Abhinav: Просто опублікуйте свою відповідь усіма цими способами, висловленими як приклади в C ++ :)
sll

5

Це виходить з ладу в моїй системі Linux, тому що рядкові літерали зберігаються в пам'яті лише для читання:

0[""]--;

До речі, g ++ відмовляється компілювати це. Компілятори стають розумнішими та розумнішими :)


4
int i = 1 / 0;

Ваш компілятор, ймовірно, попередить вас про це, але він компілюється чудово під GCC 4.4.3 Це, ймовірно, спричинить SIGFPE (виняток з плаваючою комою), що, можливо, не є таким імовірним у реальній програмі, як SIGSEGV (порушення сегментації пам'яті), як інші відповіді викликають, але це все-таки крах. На мою думку, це набагато читабельніше.

Ще один спосіб, якщо ми збираємося обманювати і використовувати signal.h, це:

#include <signal.h>
int main() {
    raise(SIGKILL);
}

Це гарантовано знищить підпроцес, на відміну від SIGSEGV.


2
Це не гарантовано вийде з ладу.
Програміст Windows

11
Мова C ++ не гарантує, що 1/0 спричинить SIGFPE. Поведінка не визначена. Реалізація може сказати, що результат - 42.
Програміст Windows

1
Коли поведінка не визначена, реалізація може робити все, що завгодно. Мова C ++ ні перешкоджає, ні вимагає реалізації, щоб написати дамп аварійного завершення, мова C ++ ні заважає, ні вимагає, щоб програма призначила 42 і т.д.
Програміст Windows

2
@Giorgio, якщо обладнання не має певного способу вловлювати його автоматично, ви все ж змушуєте компіляторів видавати щонайменше дві інструкції, одна з яких також буде галуззю. Це приблизно вдвічі збільшує вартість поділу. Усі платять такі витрати. Якщо це необов’язково, і ви хочете, ви завжди можете використовувати функцію бібліотеки для нього. Якщо це необов’язково, і ви цього не хочете, ви все-таки сплатите витрати.
Flexo

2
@ Джорджо: У мене є додаток, який робить 100 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 Я знаю на факт, що 0 з них буде діленням на нуль, хоча компілятор не може це знати. Я точно не хочу, щоб компілятор посадив чек на поділ на нуль.
Мартін Йорк

4

Це більш гарантована версія переривання, представлена ​​у вищезазначених відповідях. Вона піклується про ситуацію, коли сигабрт заблокований. Ви можете замість перерви застосувати будь-який сигнал замість переривання, який має за замовчуванням збій програми.

#include<stdio.h>
#include<signal.h>
#include<unistd.h> 
#include<stdlib.h>
int main()
{
    sigset_t act;
    sigemptyset(&act);
    sigfillset(&act);
    sigprocmask(SIG_UNBLOCK,&act,NULL);
    abort();
}

3
int* p=0;
*p=0;

Це також повинно бути аварійним. У Windows він виходить з ладу з AccessViolation, і він повинен робити те саме на всіх ОС, я думаю.


5
on all OS-esНі, він не виходить з ладу в незахищеній ОС (наприклад, MS-DOS.) Насправді іноді в адресі 0 є щось! Для x86 режимі реального часу, вектор переривання Таблиця на адресу 0.
IKH

Він не врізався в Irix. Я сумно зрозумів, коли ми перенесли цей код в Linux (куди ми навіть не дійшли main().
Scheff

3

Це фрагмент, наданий Google в Breakpad.

  volatile int* a = reinterpret_cast<volatile int*>(NULL);
  *a = 1;

1
Оскільки я тестую Breakpad, це саме те, що я хотів! Я виявив, що деякі міні-накази Breakpad не створюють сліду стека, який вказує на рядок у моєму коді, що викликає збій. Це так, і я можу використовувати його як хороший пок-тест.
BuvinJ


2

Хоча на це питання вже є прийнята відповідь ...

void main(){
    throw 1;
}

Або ... void main(){throw 1;}


2

Запис у пам'ять, доступну лише для читання, спричинить помилку сегментації, якщо ваша система не підтримує блоки пам'яті лише для читання.

int main() {
    (int&)main = 0;
}

Я протестував його з MingGW 5.3.0 на Windows 7 і GCC на Linux Mint. Я припускаю, що інші компілятори та системи дадуть подібний ефект.


1

Або іншим способом, оскільки ми перебуваємо на фургоні.

Прекрасний шматок нескінченної рекурсії. Гарантовано підірвати ваш стек.

int main(int argv, char* argc)
{
   return main(argv, argc)
}

Друкує:

Помилка сегментації (ядро скинуто)


13
Викликати mainсебе - це насправді невизначена поведінка, якщо ви цього не знали :) Крім того, рецидиви хвоста не гарантовано підірвуть ваш стек. Якщо ви хочете отримати гарантію, вам потрібно щось зробити після рекурсивного виклику, інакше компілятор може оптимізувати рекурсію в нескінченний цикл.
fredoverflow

0

Той, про який ще не було сказано:

((void(*)())0)();

Це буде розглядати нульовий покажчик як покажчик функції, а потім викликати його. Як і більшість методів, це не гарантує збій програми, але шанси ОС, що дозволяють це не перевірити, і програма, що повертається, незначні.


3
Я знаю кілька машин, що це призведе до повторного завантаження, оскільки код запуску ОС ефективно відображається на адресу 0. Не припускайте, що все буде працювати як ваш ПК. Ви можете сказати, що стався збій, але це не дуже корисно, оскільки ви не можете його налагодити, оскільки всі стани стираються при запуску.
Мартін Йорк

@Loki Astari: Я все-таки не скажу, що це збій - якщо це може спричинити, то програма налагодження може також, що означає, що це настільки ж хороший тест, як і будь-який. З іншого боку, мені цікаво, хто з цих машин може запускати Python.
Антон Голов

Я думаю, ти пропустив справу. Я бачив код ОС на 0. Це не означає, що не існує систем з нормальним хорошим кодом для запуску, які працюватимуть чудово при 0. Або байти в 0 можуть так само легко стати опкодом для повернення.
Мартін Йорк

Мені відомо про код ОС у 0; це одна з причин, що я сильно сумніваюся, що байти в 0 будуть опкодом для повернення. Програма явно більше не виконується і не виходить звичайним способом, тобто розбилася - якщо це недостатньо добре для запитувача, я очікую, що він сам це прокоментує.
Антон Голов

2
Вам відомий код ОС лише для вашої машини. Що я намагаюся сказати, це те, що для вас це може бути невдалим. Але це нічого не означає. Там багато систем. Я впевнений, що деякі з них можуть спрацювати (тобто, як не в аварії). Покладатися на специфічну поведінку машини / ОС - погана ідея і спричиняє проблеми з технічним обслуговуванням з часом. Ідея сайту полягає у просуванні хорошого коду (не просто коду, який працює).
Мартін Йорк

0
void main()
{

  int *aNumber = (int*) malloc(sizeof(int));
  int j = 10;
  for(int i = 2; i <= j; ++i)
  {
      aNumber = (int*) realloc(aNumber, sizeof(int) * i);
      j += 10;
  }

}

Сподіваюсь, що це зазнає краху. Ура.


0
int main()
{
    int *p=3;
    int s;
    while(1) {
        s=*p;
        p++;
    }
}

2
Було б чудово уточнити :)
olyv

1
p покажчик вийде за межі адресного простору програми, що буде помилкою пам'яті, оскільки процес не може отримати доступ до пам'яті іншого процесу. Це призведе до краху програми. покажчик p вказує на випадкове місце у своєму адресному просторі, якщо він збільшується та відмежується нескінченно в якийсь момент, він вказуватиме на адресний простір (процес) іншої програми (процес). значить, через деякий час воно вийде з ладу.
sc_cs

Або, гіпотетично, це могло б досягти цілого переповнення і обернутись, працює нескінченно. Я б спробував скористатися long longабо size_tпочати з pвідповідного максимального значення, або близько до нього, щоб швидше вийти з ладу. Хоча в цьому випадку все одно не гарантується аварія.
Патрік Робертс

0

Стильний спосіб зробити це чистий віртуальний виклик функції:

class Base;

void func(Base*);

class Base
{
public:
   virtual void f() = 0;
   Base() 
   {
       func(this);
   }
};

class Derived : Base
{
   virtual void f()
   {
   }
};

void func(Base* p)
{
   p->f();
}


int main()
{
    Derived  d;
}

Складений з gcc, цей принт:

чистий віртуальний метод називається

завершити виклик без активного винятку

Аборт (ядро скинуто)


0

Ви можете використовувати збірку у вашому c ++, code але INT 3 тільки для систем x86, інші системи можуть мати інші інструкції щодо захоплення / перерви.

int main()
{
    __asm int 3;

    return 0;
}

INT 3 викликає переривання і викликає вектор переривання, встановлений ОС.


0

Використовуйте __builtin_trap () у GCC чи clang, або __debugbreak () у MSVC. Якщо не працювати з цими точками переривання / пастки, це призведе до невпорядкованого виключення / аварії. Інші пропозиції, які використовують abort () або exit (): вони можуть оброблятися іншими потоками, що ускладнює бачення стека потоку, який поширює збій.


-2
char*freeThis;
free(freeThis);

Звільнення неініціалізованого покажчика - це невизначена поведінка. На багатьох платформах / компіляторах freeThisбуде мати випадкове значення (що б там не було в цій пам'яті раніше). При звільненні він попросить систему звільнити пам'ять за цією адресою, що, як правило, призведе до помилки сегментації та призведе до збою програми.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.