Cara secara terprogram menyebabkan dump inti di C / C ++

93

Saya ingin memaksa core dump di lokasi tertentu dalam aplikasi C ++ saya.

Saya tahu saya bisa melakukannya dengan melakukan sesuatu seperti:

int * crash = NULL;
*crash = 1;

Tapi saya ingin tahu apakah ada cara yang lebih bersih?

Saya menggunakan Linux.

hhafez.dll
sumber
18
Cara yang "lebih bersih" untuk membuang inti? .... bagus;)
OJ.
5
Ini lucu. Lebih baik lagi gunakan boolean (enum di c?) ... if ( crash = TRUE) {/ OH SHI ... * /}
Ape-inago
3
BTW, metode itu tidak berfungsi di semua UNIX. HPUX, misalnya, memungkinkan Anda untuk membaca dan menulis NULL tanpa hukuman (untungnya, ini dapat dikonfigurasi).
paxdiablo
1
Saya baru saja belajar menyukai 3 atau 4 hal baru yang hebat. Terima kasih.
Trevor Boyd Smith
@pax itu lebih dari alasan untuk menemukan cara umum;) Terima kasih
hhafez

Jawaban:

77

Menaikkan sinyal nomor 6 ( SIGABRTdi Linux) adalah salah satu cara untuk melakukannya (meskipun perlu diingat bahwa SIGABRT tidak diharuskan menjadi 6 dalam semua implementasi POSIX jadi Anda mungkin ingin menggunakan SIGABRTnilainya sendiri jika ini adalah selain quick'n 'kode debug kotor).

#include <signal.h>
: : :
raise (SIGABRT);

Memanggil abort()juga akan menyebabkan dump inti, dan Anda bahkan dapat melakukan ini tanpa menghentikan proses Anda dengan memanggil fork()diikuti oleh hanya abort()pada anak - lihat jawaban ini untuk detailnya.

paxdiablo
sumber
7
SIGABRT tidak diharuskan menjadi sinyal nomor 6 (meskipun sering - dan, secara khusus, di Linux).
Jonathan Leffler
4
Tidak, Anda benar, tidak, tetapi saya cenderung tidak terlalu khawatir tentang kebenaran kode debug. Jika itu lolos ke alam liar, kebersihan kode saya adalah yang paling tidak saya khawatirkan :-)
paxdiablo
2
Memanggil abort () mungkin tidak berguna pada beberapa arsitektur dengan beberapa kompiler dan beberapa perpustakaan C (seperti gcc dan glibc atau uClibc pada ARM) karena fungsi abort () dideklarasikan dengan atribut noreturn dan kompilator sepenuhnya mengoptimalkan semua informasi yang dikembalikan, yang membuat file inti tidak dapat digunakan. Anda tidak dapat melacaknya melewati panggilan ke raise () atau abort () itu sendiri. Jadi, jauh lebih baik untuk memanggil raise (SIGABRT) secara langsung atau kill (getpid (), SIGABRT), yang hampir sama.
Alexander Amelkin
3
Maaf, di ARM hal yang sama terjadi bahkan dengan kenaikan gaji (SIGABRT). Jadi satu-satunya cara untuk menghasilkan file inti yang dapat dilacak adalah kill (getpid (), SIGABRT)
Alexander Amelkin
Petunjuk ulimit -c unlimiteddari jawaban Suvesh Pratapa, banyak membantu saya untuk jawaban ini.
Boris Däppen
74

Beberapa tahun yang lalu, Google merilis pustaka coredumper .

Gambaran

Pustaka coredumper dapat dikompilasi ke dalam aplikasi untuk membuat dump inti dari program yang sedang berjalan - tanpa menghentikannya. Ini mendukung core dump tunggal dan multi-threaded, bahkan jika kernel secara native tidak mendukung file inti multi-threaded.

Coredumper didistribusikan di bawah persyaratan Lisensi BSD.

Contoh

Ini sama sekali bukan contoh lengkap; itu hanya memberi Anda gambaran tentang seperti apa API coredumper itu.

#include <google/coredumper.h>
...
WriteCoreDump('core.myprogram');
/* Keep going, we generated a core file,
 * but we didn't crash.
 */

Bukan itu yang Anda minta, tapi mungkin lebih baik :)

efemient
sumber
3
Saya awalnya sangat bersemangat ketika menemukan jawaban ini. Tapi inti dumper terlihat cukup tua dan jompo hari ini. Bahkan ada indikasi bahwa itu tidak berfungsi lagi pada kernel Linux kontemporer: stackoverflow.com/questions/38314020/…
jefe2000
37

Seperti yang tercantum di halaman manual sinyal , sinyal apa pun dengan tindakan yang terdaftar sebagai 'inti' akan memaksa pembuangan inti. Beberapa contohnya adalah:

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

Pastikan Anda mengaktifkan dump inti:

ulimit -c unlimited
Suvesh Pratapa
sumber
Terima kasih, komentar Anda tentang mengaktifkan core dumps dengan bantuan ulimit -c unlimited.
Bagaimana Anda mengatur ulimit dari dalam kode? @ ks1322
Karan Joisher
@KaranJoisher Itu mungkin layak untuk pertanyaan lain, tapi singkatnya Anda bisa menggunakan setrlimit(RLIMIT_CORE, &core_limits);tersedia melalui #include <sys/resource.h>. Anda membuat sebuah struct tipe rlimitdan kemudian mengatur rlim_curdan rlim_maxanggota.
Brent Menulis Kode
31
#include <stdlib.h>   // C
//#include <cstdlib>  // C++

void core_dump(void)
{
    abort();
}
Jonathan Leffler
sumber
3
Mengapa tidak menelepon abort()langsung saja?
DepressedDaniel
6

Cara lain untuk menghasilkan core dump:

$ bash
$ kill -s SIGSEGV $$

Buat saja contoh baru dari bash dan matikan dengan sinyal yang ditentukan. Itu $$adalah PID dari shell. Jika tidak, Anda menghentikan pesta Anda saat ini dan akan keluar, terminal ditutup atau diputuskan.

$ bash 
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$
Zonk
sumber
Sangat sederhana dan bermanfaat!
firo
1
Saya suka yang itu juga. Bahkan dapat disederhanakan menjadi bash -c 'kill -SIGSEGV $$'.
Christian Krause
4

Anda dapat menggunakan kill (2) untuk mengirim sinyal.

#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);

Begitu,

kill(getpid(), SIGSEGV);
Eugene Yokota
sumber
Ya. Menambahkan itu ke jawabannya.
Eugene Yokota
2

Kadang-kadang mungkin tepat untuk melakukan sesuatu seperti ini:

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

Satu masalah dengan pendekatan sederhana ini adalah hanya satu thread yang akan di-coredump.

rka444
sumber
1
 #include <stdio.h>
 #include <stdlib.h>
 int main()
 {
   printf("\n");
   printf("Process is aborting\n");
   abort();
   printf("Control not reaching here\n");
   return 0;
 }

gunakan pendekatan ini di mana pun Anda mau :)

karthik339
sumber
0
#include <assert.h>
.
.
.
     assert(!"this should not happen");
sigjuice.dll
sumber
Mungkin perlu disingkirkan dengan NDEBUG sehingga pernyataan khusus ini aktif meskipun pernyataan lain tidak.
Rhys Ulerich