[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: Mod'ing struct tm causes segmentation fault on RHEL 5.4



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)

--
Josh Miller, RHCE/VCP
Seattle, WA
Linux Solutions Provider
Website:  http://itsecureadmin.com/



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]