3


システム ライブラリのレベルで発生している segfault の理由を見つけようとしています。getenv()次のスタック トレースで見られる呼び出しの引数を調べるために gdb を使用する方法について、いくつかのヒントを得たいと思います。

トレースが示すように -getenv()私のコードによって直接呼び出されていません - 私のコードで開始されたシステムコールのチェーンに呼び出しがネストされています。呼び出しは、a_logmsg()スレッドセーフを取得しようとする私のルーチンから始まり、後で libc のコード内のどこかで呼び出されます。OSはSolaris 8/SPARCです。localtime - localtime_r()getenv()

Program terminated with signal 11, Segmentation fault.
#0  0xfed3c9a0 in getenv () from /usr/lib/libc.so.1
(gdb) where
#0  0xfed3c9a0 in getenv () from /usr/lib/libc.so.1
#1  0xfed46ab0 in getsystemTZ () from /usr/lib/libc.so.1
#2  0xfed44918 in ltzset_u () from /usr/lib/libc.so.1
#3  0xfed44140 in localtime_r () from /usr/lib/libc.so.1
#4  0x00029c28 in a_logmsg (fmt=0xfd5d0 "%s: no changes to config.") at misc.c:155
#5  0x000273b8 in a_sync_device (device_group=0x11e3ed0 "none", hostname=0xfbbffe8d "router",
    config_by=0xfbbffc8f "scheduled_archiving", platform=0x11e3ee0 "cisco", authset=0x11e3ef0 "set01",
    arch_method=0xffffcfc8 <Address 0xffffcfc8 out of bounds>) at arch.c:256
#6  0x00027ce8 in a_archive_single (arg=0x1606f50) at arch.c:498
#7  0xfe775378 in _lwp_start () from /usr/lib/libthread.so.1
#8  0xfe775378 in _lwp_start () from /usr/lib/libthread.so.1
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
4

1 に答える 1

1

次のスタック トレースに見られる getenv() 呼び出しの引数を調べるために gdb を使用する方法について、いくつかのヒントを得たいと思います。

  1. Solaris libc のソースは、ここから入手できます。
  2. getenv引数にブレークポイントを設定し、レジスタを調べることで引数を調べることができます。使用されているABIを知る必要がありますが、それは非常に簡単です。引数getenvは registeri0にありprint (char*)$i0(gdb)プロンプトで を出力する必要があります"TZ"

最後に、クラッシュの最も可能性の高い理由は、getenv以前に環境を破損したことです。特に、このコードは悪いことに注意してください:

void buggy()
{
   char buf[80];
   strcpy(buf, "FOO=BAR");
   putenv(buf);  // <-- BUG!
}

通常、次のコマンドのいずれかを使用して環境を調べることができます。

(gdb) x/100s __environ
(gdb) x/100s environ

=記号を含まない文字列が表示される可能性があります。

于 2012-09-03T15:30:40.317 に答える