C ++ uygulamamda belirli bir konumda çekirdek dökümünü zorlamak istiyorum.
Bunu şöyle bir şey yaparak yapabileceğimi biliyorum:
int * crash = NULL;
*crash = 1;
Ama daha temiz bir yol olup olmadığını bilmek isterim?
Bu arada Linux kullanıyorum.
C ++ uygulamamda belirli bir konumda çekirdek dökümünü zorlamak istiyorum.
Bunu şöyle bir şey yaparak yapabileceğimi biliyorum:
int * crash = NULL;
*crash = 1;
Ama daha temiz bir yol olup olmadığını bilmek isterim?
Bu arada Linux kullanıyorum.
Yanıtlar:
Sinyal numarası 6'nın yükseltilmesi ( SIGABRTLinux'ta) bunu yapmanın bir yoludur (bununla birlikte, SIGABRT'nin tüm POSIX uygulamalarında 6 olması gerekmediğini unutmayın, bu nedenle SIGABRTbu, quick'n'den başka bir şeyse , değerin kendisini kullanmak isteyebilirsiniz. kirli hata ayıklama kodu).
#include <signal.h>
: : :
raise (SIGABRT);
Arayan abort()da bir çekirdek dökümü neden olur ve hatta bunu yapabilirsiniz olmadan arayarak işlem sonlandırılıyor fork()ardından abort()çocuk sadece - bakınız bu cevabı detayları için.
ulimit -c unlimitedSuvesh Pratapa cevabından gelen ipucu , bu cevap için bana çok yardımcı oldu.
Birkaç yıl önce Google, coredumper kitaplığını yayınladı .
Genel Bakış
Coreumper kitaplığı, çalışan programın temel dökümlerini sonlandırmadan oluşturmak için uygulamalara derlenebilir. Çekirdek çok iş parçacıklı çekirdek dosyaları yerel olarak desteklemese bile, hem tek hem de çok iş parçacıklı çekirdek dökümlerini destekler.
Coredumper, BSD Lisansı koşulları altında dağıtılmaktadır.
Misal
Bu hiçbir şekilde tam bir örnek değildir; size coredumper API'sinin neye benzediğine dair bir fikir verir.
#include <google/coredumper.h> ... WriteCoreDump('core.myprogram'); /* Keep going, we generated a core file, * but we didn't crash. */
İstediğin bu değil, ama belki daha da iyi :)
'De gösterildiği gibi sinyal man , 'çekirdek' olarak belirtilen hareket ile herhangi bir sinyal bellek dökümü zorlar. Bazı örnekler:
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
Temel dökümleri etkinleştirdiğinizden emin olun:
ulimit -c unlimited
setrlimit(RLIMIT_CORE, &core_limits);aracılığıyla ulaşılabilir kullanabilirsiniz #include <sys/resource.h>. Bir yapı türü oluşturursunuz rlimitve ardından rlim_curve rlim_maxüyelerini ayarlarsınız .
#include <stdlib.h> // C
//#include <cstdlib> // C++
void core_dump(void)
{
abort();
}
abort()doğrudan aramıyorsunuz ?
Çağırmak
abort();
Bununla ilgili olarak, bazen gerçek bir çekirdek dökümü olmadan bir geriye dönük izleme istersiniz ve programın çalışmaya devam etmesine izin verin: glibc backtrace () ve backtrace_symbols () işlevlerine bakın: http://www.gnu.org/s/libc/ manual / html_node / Backtraces.html
Bir çekirdek dökümü oluşturmanın başka bir yolu:
$ bash
$ kill -s SIGSEGV $$
Sadece bash'ın yeni bir örneğini oluşturun ve onu belirtilen sinyalle kapatın. $$Kabuğun PID. Aksi takdirde, mevcut bashınızı öldürürsünüz ve oturumunuz kapatılır, terminal kapatılır veya bağlantısı kesilir.
$ bash
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$
bash -c 'kill -SIGSEGV $$'.
Sinyal göndermek için kill (2) kullanabilirsiniz.
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
Yani,
kill(getpid(), SIGSEGV);
Bazen böyle bir şey yapmak uygun olabilir:
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
Bu basit yaklaşımla ilgili bir sorun, yalnızca bir iş parçacığının ortak dökümlenmesidir.
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("\n");
printf("Process is aborting\n");
abort();
printf("Control not reaching here\n");
return 0;
}
bu yaklaşımı istediğiniz yerde kullanın :)
#include <assert.h>
.
.
.
assert(!"this should not happen");