4

我正在将 pro*c 代码从 UNIX 移植到 LINUX。代码已成功编译并创建可执行文件。但是在运行时它会引发分段错误。我一步一步调试了代​​码,下面是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

它调用 strftime_l 是因为您编译了 64 位 - 这是 strftime 的 64 位库入口点。strftime 中有两个指针 - 一个字符串和一个 struct tm 指针。其中之一是指向无效内存。jpalacek 为您提供了首先查看的位置。

于 2012-05-15T12:06:12.190 回答
-1

您是否添加了 time.h 头文件?我想你已经错过了。

于 2017-05-31T23:39:11.390 回答