Я хотів би примусити дамп ядра в певному місці в моєму додатку C ++.
Я знаю, що можу це зробити, виконавши щось на зразок:
int * crash = NULL;
*crash = 1;
Але я хотів би знати, чи існує чистіший спосіб?
Я, до речі, використовую Linux.
Я хотів би примусити дамп ядра в певному місці в моєму додатку C ++.
Я знаю, що можу це зробити, виконавши щось на зразок:
int * crash = NULL;
*crash = 1;
Але я хотів би знати, чи існує чистіший спосіб?
Я, до речі, використовую Linux.
Відповіді:
Підвищення сигналу № 6 ( SIGABRT
в Linux) - це один із способів (хоча майте на увазі, що SIGABRT не повинен бути 6 у всіх реалізаціях POSIX, тому ви можете використовувати саме SIGABRT
значення, якщо це не що інше, як quick'n 'брудний код налагодження).
#include <signal.h>
: : :
raise (SIGABRT);
Виклик abort()
також спричинить основний дамп, і ви навіть можете це зробити, не припиняючи процес, зателефонувавши fork()
за ним лише abort()
в дитині - детальну інформацію див. У цій відповіді .
ulimit -c unlimited
відповідь Сувеша Пратапи мені дуже допоміг для цієї відповіді.
Кілька років тому Google випустив бібліотеку coredumper .
Огляд
Бібліотеку coredumper можна компілювати в програми для створення основних дампів запущеної програми - без завершення. Він підтримує однопотокові та багатопотокові дампи ядра, навіть якщо ядро не підтримує багатопотокові файли ядра.
Coredumper поширюється на умовах ліцензії BSD.
Приклад
Це далеко не повний приклад; це просто дає вам відчути, як виглядає coredumper API.
#include <google/coredumper.h> ... WriteCoreDump('core.myprogram'); /* Keep going, we generated a core file, * but we didn't crash. */
Це не те, про що ви просили, але, можливо, це навіть краще :)
Як зазначено в керівництві сигналу , будь-який сигнал із дією, перерахованою як «ядро», змусить дамп ядра. Деякі приклади:
SIGQUIT 3 Core Quit from keyboard
SIGILL 4 Core Illegal Instruction
SIGABRT 6 Core Abort signal from abort(3)
SIGFPE 8 Core Floating point exception
SIGSEGV 11 Core Invalid memory reference
Переконайтеся, що ви ввімкнули дампи ядра:
ulimit -c unlimited
setrlimit(RLIMIT_CORE, &core_limits);
доступне через #include <sys/resource.h>
. Ви створюєте структуру типу, rlimit
а потім встановлюєте членів rlim_cur
і rlim_max
.
#include <stdlib.h> // C
//#include <cstdlib> // C++
void core_dump(void)
{
abort();
}
abort()
безпосередньо?
Закликати
abort();
Пов’язане, іноді ви хочете отримати зворотну трасування без фактичного дампа ядра і дозволити програмі продовжувати працювати: перевірте функції glibc backtrace () та backtrace_symbols (): http://www.gnu.org/s/libc/ manual / html_node / Backtraces.html
Інший спосіб генерування дампів ядра:
$ bash
$ kill -s SIGSEGV $$
Просто створіть новий екземпляр bash і вбийте його за вказаним сигналом. Це $$
PID оболонки. В іншому випадку ви вбиваєте ваш поточний bash і вийдете з системи, термінал закритий або відключений.
$ bash
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$
bash -c 'kill -SIGSEGV $$'
.
Ви можете використовувати kill (2) для передачі сигналу.
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
Так,
kill(getpid(), SIGSEGV);
Іноді може бути доречно зробити щось подібне:
int st = 0;
pid_t p = fork();
if (!p) {
signal(SIGABRT, SIG_DFL);
abort(); // having the coredump of the exact copy of the calling thread
} else {
waitpid(p, &st, 0); // rip the zombie
}
// here the original process continues to live
Одна з проблем цього простого підходу полягає в тому, що тільки одна нитка буде coredumped.
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("\n");
printf("Process is aborting\n");
abort();
printf("Control not reaching here\n");
return 0;
}
використовуйте цей підхід куди завгодно :)
#include <assert.h>
.
.
.
assert(!"this should not happen");