1

backstrace_symbols以下を使用してスクリプトをセットアップしました。

void handler(int sig) {
    void *array[20];
    size_t size;
    char **strings;
    size_t  i;

    size = backtrace(array, 20);
    strings = backtrace_symbols(array,size);

    tracelog.open("/var/log/safesquid/safesquid/debug/trace.log", ios::app);
    tracelog << sig << endl;
    for (i=0; i<size; i++)
        tracelog << strings[i] << endl;

    free(strings);

    exit(1);
}

メイン関数では、それを使用して呼び出されます

signal(SIGSEGV, handler);

バックトレース:

11
/opt/scripts/cplusconnector(_Z7handleri+0x2b) [0x40233b]
/lib64/libc.so.6(+0x32920) [0x7fe7b503c920]
/lib64/libc.so.6(+0x131b5f) [0x7fe7b513bb5f]
/opt/scripts/cplusconnector(main+0x163) [0x4035c3]
/lib64/libc.so.6(__libc_start_main+0xfd) [0x7fe7b5028cdd]
/opt/scripts/cplusconnector() [0x402199]
11
/opt/scripts/cplusconnector(_Z7handleri+0x2b) [0x40233b]
/lib64/libc.so.6(+0x32920) [0x7fd9db71a920]
/lib64/libc.so.6(+0x131b5f) [0x7fd9db819b5f]
/opt/scripts/cplusconnector(main+0x163) [0x4035c3]
/lib64/libc.so.6(__libc_start_main+0xfd) [0x7fd9db706cdd]
/opt/scripts/cplusconnector() [0x402199]

[root@server dev]# addr2line -e test-unstrippped 0x402199 0x7f1999f16cdd 0x4035c3
??:0
??:0
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/basic_string.h:975

問題はどこにあり、プログラムを実行するとセグメンテーション違反が発生するのはなぜですか?

アップデート:

これらのオプションを使用してコンパイルされました

g++ cplusconnector-k.cpp -g -rdynamic -O2 -I/usr/include/mysql -L/usr/lib/mysql -lmysqlcppconn -o test  `mysql_config --cflags --libs`

アップデート:

最適化を削除し、バックトレースから add2line を使用してシンボルを解決しようとしましたが、コードでこの行を指していました..

/opt/webcache/scripts/cplusconnector(_Z7handleri+0x25) [0x401d49]
/lib64/libc.so.6(+0x32920) [0x7f6ad974b920]
/lib64/libc.so.6(+0x131b5f) [0x7f6ad984ab5f]
/usr/lib64/libstdc++.so.6(_ZNSsaSEPKc+0x1c) [0x7f6ad9dcd12c]
/opt/webcache/scripts/cplusconnector(main+0x12b) [0x4027ae]
/lib64/libc.so.6(__libc_start_main+0xfd) [0x7f6ad9737cdd]
/opt/webcache/scripts/cplusconnector() [0x401c69]


[root@server dev]# addr2line -e test 0x401d49 0x7f6ad974b920 0x7f6ad984ab5f 0x7f6ad9dcd12c 0x4027ae 0x7f6ad9737cdd 0x401c69
/usr/local/dev/cplusconnector-k.cpp:42
??:0
??:0
??:0
/usr/local/dev/cplusconnector-k.cpp:138
??:0
??:0

行: 42 はメイン関数の外にあり、グローバルです:

ofstream httplog;

line:138 は main 関数内にあります。

    if (std::string::npos != host.find(string("1.0.0.1"))){
          return 0;
       }

何か案は??

4

3 に答える 3

2

プログラムをデバッグするには、コアダンプを有効にすることができます(setrlimit(2) syscall を使用し、多くの場合、ulimit bash ビルトインを介して)。次に、gdbプログラムとコア ダンプを実行します。

がそのbacktrace_symbolsような名前を付けている理由については、名前マングリングが原因です。これも参照してください。

Ian Taylor のlibbacktraceの使用も検討してください(GCC の最近のバージョン (GCC 6 以降など) に統合されています)。コードをコンパイルします-g(および、おそらく のような最適化フラグも-O)

于 2012-08-23T11:25:28.817 に答える
2

free() を使用する正当な理由が確かにあることがわかりました

名前マングリングにはabi::__cxa_demangleを使用します。

于 2012-08-23T11:31:42.230 に答える
1

backtrace() は、シグナル ハンドラから呼び出すことはできません。

シグナルハンドラから呼び出すことができるメソッドの (短い) リストがあります。私はあまりにも怠け者で、今はGoogleです

于 2013-04-24T16:08:34.270 に答える