4

エラーコード、エラー文字列、ログ以外に、コードの実行時にデバッグ/トレース情報を取得するためにコードに組み込むことができ、実行時に問題をデバッグする(または何が起こっているのかを知らせる)のに役立つ機能はありますか?

4

3 に答える 3

2
  • コードの「意図」を可能な限り維持するために、最適化せずにビルドする
  • シンボル情報を追加するには、デバッグモードでビルドします
  • デバッガーが使用できるようにできるだけ多くのシンボル情報を保持するために、実行可能ファイルを削除しないでください(Linux / Unixシステムの場合)。
于 2010-02-01T15:12:20.327 に答える
2

セグメンテーション違反時にスタックトレースをファイルに送信するコードの例を次に示します。

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <stdarg.h>

static void signal_handler(int);
static void dumpstack(void);
static void cleanup(void);
void init_signals(void);
void panic(const char *、...);

struct sigaction sigact;
char * progname;

int main(int argc、char ** argv){
    char * s;
    progname = *(argv);
    atexit(クリーンアップ);
    init_signals();
    printf("* s \ nにゼロを割り当てて障害をセグメント化しようとしています");
    * s = 0;
    sigemptyset(&sigact.sa_mask);
    0を返します。
}

void init_signals(void){
    sigact.sa_handler = signal_handler;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigaction(SIGINT、&sigact、(struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask、SIGSEGV);
    sigaction(SIGSEGV、&sigact、(struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask、SIGBUS);
    sigaction(SIGBUS、&sigact、(struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask、SIGQUIT);
    sigaction(SIGQUIT、&sigact、(struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask、SIGHUP);
    sigaction(SIGHUP、&sigact、(struct sigaction *)NULL);

    sigaddset(&sigact.sa_mask、SIGKILL);
    sigaction(SIGKILL、&sigact、(struct sigaction *)NULL);
}

static void signal_handler(int sig){
    if(sig == SIGHUP)panic( "致命的:プログラムがハングアップしました\ n");
    if(sig == SIGSEGV || sig == SIGBUS){
        dumpstack();
        panic( "FATAL:%sFault。LoggedStackTrace \ n"、(sig == SIGSEGV)? "Segmentation":((sig == SIGBUS)? "Bus": "Unknown"));
    }
    if(sig == SIGQUIT)panic("QUITシグナルがプログラムを終了しました\n");
    if(sig == SIGKILL)panic("KILLシグナルがプログラムを終了しました\n");
    if(sig == SIGINT);
}

void panic(const char * fmt、...){
    char buf [50];
    va_list argptr;
    va_start(argptr、fmt);
    vsprintf(buf、fmt、argptr);
    va_end(argptr);
    fprintf(stderr、buf);
    exit(-1);
}

static void dumpstack(void){
    /*http://www.whitefang.com/unix/faq_toc.htmlからこのルーチンを入手しました
    **セクション6.5。混乱を防ぐためにファイルにリダイレクトするように変更
    * /
    char dbx [160];
    sprintf(dbx、 "echo'where \ ndetach' | dbx -a%d>%s.dump"、getpid()、progname);
    system(dbx);
    戻る;
}

void cleanup(void){
    sigemptyset(&sigact.sa_mask);
    /*ここで雑用を片付けます*/
}

関数dumpstackでは、GNUデバッガーdbxなど、デバッガーに合わせて変更する必要がありますgdb。このコードは、数年前にAIXボックスでプログラミングしていたときに使用されました。シグナルがどのように設定されているかに注意してください。SIGSEGV障害が発生した場合、ハンドラーはスタックを拡張子が.のファイルにダンプします.dump。このコードは、セグメンテーションフォールトを示し、スタックトレースをダンプします。

それが私のお気に入りのコードです。

これがお役に立てば幸いです、よろしく、トム。

于 2010-02-01T15:26:29.300 に答える
1

Linux用にビルドするときは、シグナルハンドラーからスタックバックトレースを出力できるようにしたいと思います。これは、クラッシュのデバッグに役立ちます(SIGSEGV)。または、実行時にスタックバックトレースを開始するためのシグナルをプログラムに送信できます。 コアダンプは、クラッシュのデバッグにも役立ちます(これもLinuxで)。

于 2010-02-01T15:17:33.267 に答える