4

UNIX から LINUX に pro*c コードを移植しています。コードがコンパイルされ、実行可能ファイルが正常に作成されます。しかし、実行時にセグメンテーション違反が発生します。コードを段階的にデバッグしました。以下は GDB デバッグの出力です。

 Breakpoint 4 at 0x3b19690f50
 (gdb) n
 525             strftime (buf, MAX_STRING_LEN, "%d/%b/%Y:%H:%M:%S", dummy_time);
 (gdb) n

 Breakpoint 4, 0x0000003b19690f50 in strftime () from /lib64/libc.so.6
 (gdb) n
 Single stepping until exit from function strftime,
 which has no line number information.
 0x0000003b19690f70 in strftime_l () from /lib64/libc.so.6
 (gdb) n
 Single stepping until exit from function strftime_l,
 which has no line number information.

 Program received signal SIGSEGV, Segmentation fault.
 0x0000003b19690f8b in strftime_l () from /lib64/libc.so.6

実際にはコードで関数strftime()が呼び出されます。しかし、なぜstrftime_l()/lib64/libc.so.6 に到達するのかわかりません。

この問題は UNIX では発生しません。これについて助けてください。コードは

static void speed_hack_libs(void)
{
    time_t dummy_time_t = time(NULL);
    struct tm *dummy_time = localtime (&dummy_time_t);
    struct tm *other_dummy_time = gmtime (&dummy_time_t);
    char buf[MAX_STRING_LEN];
    strftime (buf, MAX_STRING_LEN, "%d/%b/%Y:%H:%M:%S", dummy_time);
}
4

3 に答える 3

5
struct tm *dummy_time = localtime (&dummy_time_t);
struct tm *other_dummy_time = gmtime (&dummy_time_t);

これはうまくいきません。マニュアルページから:

このlocaltime()関数は、カレンダーの時刻timepを、ユーザーが指定したタイムゾーンに関連して表される内訳の時刻表現に変換します。... 戻り値は、静的に割り当てられた構造体を指します。この構造体は、日付と時刻の関数のいずれかへの後続の呼び出しによって上書きされる可能性があります。

このgmtime()関数は、カレンダーの時刻timepを、協定世界時(UTC)で表される内訳の時刻表現に変換します。 年が整数に収まらない場合は、 NULLを返す場合があります。戻り値は、静的に割り当てられた構造体を指します。この構造体は、日付と時刻の関数のいずれかへの後続の呼び出しによって上書きされる可能性があります。

その*dummy_timeため、使用するまでに上書きされ、予測できないゴミが含まれている可能性があります。次のようにデータをバッファにコピーする必要があります。

struct tm dummy_time ;
memcpy(&dummy_time, localtime (&dummy_time_t), sizeof(struct tm));

これによりSIGSEGVがどのように発生するかはわかりませんが(月の名前などを取得することで問題が発生する可能性があります。問題が解決しないかどうかを確認してくださいLC_ALL=C)、先に進む前にこれを修正する必要があります。また、(デバッガーで)の内容を確認してください*dummy_time

于 2012-05-15T11:19:49.460 に答える
1

64 ビットをコンパイルしたため、strftime_l を呼び出しています。これは、strftime の 64 ビット ライブラリ エントリ ポイントです。strftime には、文字列と struct tm ポインターの 2 つのポインターがあります。それらの 1 つは、無効なメモリを指しています。jpalacek は、最初にどこを見るべきかを教えてくれました。

于 2012-05-15T12:06:12.190 に答える