次のコード(log
関数の一部)を取得しました:
/* set to 32 on purpose */
#define MAX_LOG_MSG_SZ 32
void log(const char *fmt, ...) {
....
char msg[MAX_LOG_MSG_SZ] = {0};
int nb_bytes = 0;
/* get current time */
time_t now = time(NULL);
char time_buf[32] = {0};
/* format time as `14 Jul 20:00:08`, and exactly 16 bytes */
strftime(time_buf, sizeof(time_buf), "%d %b %H:%M:%S", localtime(&now));
nb_bytes = snprintf(msg, sizeof(msg), "%s", time_buf);
va_list ap;
va_start(ap, fmt);
vsnprintf(msg + nb_bytes, MAX_LOG_MSG_SZ, fmt, ap);
va_end(ap);
....
}
注意が必要なのは、長いパラメーターを渡す (32 バイトより長くする) ときにtime_buf
32 未満の値 (16 よりも大きい、たとえば 31) に変更すると、これらのコードはスタック破壊をスローすることです。数分間のデバッグの後、vsnprintf
呼び出しラインを次のように変更しました
vsnprintf(msg + nb_bytes, MAX_LOG_MSG_SZ - nb_bytes, fmt, ap);
スタックスマッシングがなくなり、問題は解決したと思います。
BUT:オンtime_buf[32]
(または他の大きなサイズ)、なぜエラー呼び出し
vsnprintf(msg + nb_bytes, MAX_LOG_MSG_SZ, fmt, ap);
スタックスマッシングを投げませんか?もっと正確に言えば、なぜmsg
のスタック破壊がその無関係なスタック ( time_buf
) スペースに関連しているのですか?
更新:これは私のuname -a
出力です:
Linux coanor 3.5.0-34-generic #55-Ubuntu SMP Thu Jun 6 20:20:19 UTC 2013 i686 i686 i686 GNU/Linux