C / C ++でプログラムによってコアダンプを発生させる方法


93

C ++アプリケーションの特定の場所にコアダンプを強制したいのですが。

私は次のようなことでそれを行うことができることを知っています:

int * crash = NULL;
*crash = 1;

しかし、よりクリーンな方法があるかどうか知りたいですか?

ちなみにLinuxを使っています。


18
コアダンプへの「よりクリーンな」方法?....良いもの;)
OJ。

5
かわいいです。ブール値(cの列挙型)を使用した方がよい... if(crash = TRUE){/ OH SHI ... * /}
Ape-in​​ago

3
ところで、その方法はすべてのUNIXで機能するわけではありません。たとえばHPUXでは、NULLをそのまま読み書きできます(ありがたいことに、これは構成可能です)。
paxdiablo 2009年

1
私はちょうど3つか4つの素晴らしい新しいことを学びました。ありがとう。
Trevor Boyd Smith、

@paxそれは一般的な方法を見つける理由のより多くです;)ありがとう
hhafez 09年

回答:


76

シグナル番号6の発生(SIGABRTLinuxの場合)はそれを行う1つの方法です(ただし、すべてのPOSIX実装でSIGABRTが6である必要はないのでSIGABRT、quick'n以外の場合は値自体を使用することもできます'ダーティデバッグコード)。

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

呼び出すabort()とコアダンプも発生します。これ行うには、子だけで呼び出し、fork()その後に続けてabort()、プロセス終了する必要はありません。詳細については、この回答を参照してください。


7
SIGABRTは、シグナル番号6である必要はありません(ただし、多くの場合、Linux上にあります)。
ジョナサンレフラー

4
いいえ、そうです、そうではありませんが、デバッグコードの正確さについてあまり気にしない傾向があります。それが自然に脱出する場合、私のコードの清潔さは私の心配の中で最小です:-)
paxdiablo

2
一部のコンパイラと一部のCライブラリ(ARMのgccとglibcまたはuClibcなど)では、abort()を呼び出しても役に立たない場合があります。なぜなら、abort()関数はnoreturn属性で宣言され、コンパイラはすべての戻り情報を完全に最適化するためです。これにより、コアファイルが使用できなくなります。raise()またはabort()自体の呼び出しを過ぎてそれを追跡することはできません。したがって、raise(SIGABRT)を直接呼び出すか、kill(getpid()、SIGABRT)を呼び出す方がはるかに優れています。これは実質的に同じです。
Alexander Amelkin 14

3
ARMでは、raise(SIGABRT)でも同じことが起こります。追跡可能なコア・ファイルを生成する唯一の方法はあるので、キル(GETPID()、SIGABRT)
アレクサンダーAmelkin

ulimit -c unlimitedSuvesh Pratapaの回答からのヒントは、この回答の助けとなりました。
BorisDäppen19年

74

数年前、Googleはコアダンプライブラリをリリースしました。

概観

coredumperライブラリをアプリケーションにコンパイルして、終了せずに実行中のプログラムのコアダンプを作成できます。カーネルがマルチスレッドのコアファイルをネイティブでサポートしていない場合でも、シングルスレッドとマルチスレッドの両方のコアダンプをサポートします。

コアダンプは、BSDライセンスの条件に基づいて配布されます。

これは完全な例ではありません。コアダンプAPIがどのように見えるかを感じさせるだけです。

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

それはあなたが求めていたものではありませんが、多分それはもっと良いです:)


3
この答えに出会ったとき、私は最初はかなり興奮していました。しかし、コアダンパーはかなり古く、最近は老朽化しています。それは現代のLinux上でもう動作しないことにも表示がありカーネルです:stackoverflow.com/questions/38314020/...
jefe2000

37

シグナルのマンページに記載されているように、アクションが「core」としてリストされているシグナルは、コアダンプを強制します。次に例を示します。

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

おかげで、コアダンプを有効にすることについてのあなたの発言はulimit -c unlimited助けられました。

コード内からどのようにulimitを設定しますか?@ ks1322
Karan Joisher

@KaranJoisherそれ自体はおそらく別の質問に値するでしょうが、簡単に言うとをsetrlimit(RLIMIT_CORE, &core_limits);介してを使用できます#include <sys/resource.h>。タイプの構造体を作成しrlimitrlim_curおよびrlim_maxメンバーを設定します。
ブレントはコードを



6

コアダンプを生成する別の方法:

$ bash
$ kill -s SIGSEGV $$

bashの新しいインスタンスを作成し、指定されたシグナルでそれをkillするだけです。$$シェルのPIDです。それ以外の場合は、現在のbashを強制終了し、ログアウト、ターミナルが閉じられるか切断されます。

$ bash 
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$

とてもシンプルで便利!
2014

1
私も好きです。それもに簡略化できbash -c 'kill -SIGSEGV $$'ます。
クリスチャンクラウゼ2014


2

時々このようなことをすることが適切かもしれません:

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

この単純なアプローチの1つの問題は、1つのスレッドのみがコアダンプされることです。


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;
 }

このアプローチはどこにでも使用できます:)


0
#include <assert.h>
.
.
.
     assert(!"this should not happen");

おそらくNDEBUGを使用する必要があるため、他のアサートがアクティブでない場合でも、この特定のアサートはアクティブです。
Rhys Ulerich
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.