Mod'ing struct tm causes segmentation fault on RHEL 5.4

Tim P. Starrin Timothy.P.Starrin at nasa.gov
Tue Jul 6 23:39:27 UTC 2010


Yes, all of the systems are 64 bit.  Note that the code runs fine on 
RHEL 4 and on every other platform I have tried, which  makes me want to 
label this as a bug.

Josh Miller wrote:
> On 07/06/2010 09:42 AM, Tim P. Starrin wrote:
>   
>> They're all 64 bit systems.
>>
>> I already gdb'ed it. The segfault occurs in the following location when
>> I mod date->tm_year.
>>
>> (gdb) run
>> Starting program: /home/noid/fault
>>
>> Program received signal SIGSEGV, Segmentation fault.
>> 0x000000000040054f in main () at fault.c:15
>> 15 date->tm_year %= 100;
>>
>> Did you compile the program with "-DBUG"?
>>     
>
> Hi Tim,
>
> I must admit, I'm in a little over my head here.
>
> I was able to reproduce this issue when using a 64 bit system.  I 
> believe the issue has to do with performing a mod on a signed int value. 
>   Are all of the systems that you run this on 64 bit?
>
> When I compile with debugging symbols enabled and run with gdb, it 
> doesn't segfault on me but I do get a negative year value:
>
> $ gcc -g -DBUG -o fault fault.c
>
> Temporary breakpoint 1, main () at fault.c:10
> 10       date_as_int = time ((time_t *) NULL);
> (gdb) step
> 11       date = localtime ((time_t *) &date_as_int);
> (gdb)
> 14       date->tm_year %= 100;
> (gdb)
> 20       printf ("%02d/%02d/%02d %02d:%02d:%02d\n",
> (gdb)
> -4/08/21 14:29:20
> 23      }
> (gdb)
> 0x000000363f41d974 in __libc_start_main () from /lib64/libc.so.6
> (gdb)
> Single stepping until exit from function __libc_start_main,
> which has no line number information.
>
> Program exited with code 022.
>
> When running under valgrind, I get an invalid memory read:
>
> $ valgrind -v ./fault
> ...
> ==19572== Conditional jump or move depends on uninitialised value(s)
> ==19572==    at 0x363F48A754: __offtime (in /lib64/libc-2.5.so)
> ==19572==    by 0x363F48C50D: __tz_convert (in /lib64/libc-2.5.so)
> ==19572==    by 0x400546: main (fault.c:11)
> ==19572==
> ==19572== Invalid read of size 4
> ==19572==    at 0x40054F: main (fault.c:14)
> ==19572==  Address 0x14 is not stack'd, malloc'd or (recently) free'd
> ==19572==
> ...
>
> I did a little bit of research on this and found the following to work 
> properly:
>
> #include <stdio.h>
> #include <time.h>
> #include <sys/time.h>
>
> main ()
> {
>    time_t tim=time(NULL) ;
>    struct tm *date=localtime(&tim) ;
>
> #ifdef BUG
>   date->tm_year %= 100;
> #else
>   while (date->tm_year >= 100)
>     date->tm_year -= 100;
> #endif
>
>   printf ("%02d/%02d/%02d %02d:%02d:%02d\n",
>       date->tm_year, date->tm_mon+1, date->tm_mday,
>       date->tm_hour, date->tm_min, date->tm_sec);
> }
>
> (re:  http://rabbit.eng.miami.edu/info/functions/time.html#localtime)
>
>   



More information about the redhat-list mailing list