In Solaris 7 with gcc 2.95.1, I wrote a function to log error messages with
timestamp. I use time() and localtime_t() just like this.
void ErrorLog(char *s)
{
time_t t;
struct tm tm;
time(&t);
localtime_r(&t, &tm);
fprintf(stderr, "%04d%02d%02d%02d%02d%02d %s",
tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min,
tm.tm_sec, s);
And when I call this function from the start of thread routine created byQuote:}
pthread_create(), localtime_r() generates SEGV and the thread stops. This
happens once in a while, not always.
signal fault in critical section
signal number: 11, signal code: 1, fault address: 0xfe7d1e20,
pc: 0xff10c548, sp: 0xff0113e0
libthread panic: fault in libthread critical section (PID: 6182 LWP 4)
stacktrace:
ff10c52c // <_mutex_adaptive_lock+132>: call 0xff11ba7c
<_lock_owner>
ff10c378 // <_cmutex_lock+80>: call 0xff10c4a8
<_mutex_adaptive_lock>
ff1d32ec // <localtime_r+24>: call 0xff234858
<_PROCEDURE_LINKAGE_TABLE_+48>
80784 // <ErrorLog+60>: call 0xde188 <localtime_r>
27e8c // Calling ErrorLog()
79bc4
ff11b824
79b48
I ran gdb to see what caused SEGV and found these.
(gdb) where
#0 0xff2145fc in _libc_sigtimedwait () from /usr/lib/libc.so.1
#1 0xff10db54 in _panic () from /usr/lib/libthread.so.1
#2 <signal handler called>
#3 0xff10a320 in _co_timerset () from /usr/lib/libthread.so.1
#4 0xff10c380 in _cmutex_lock () from /usr/lib/libthread.so.1
#5 0xff1d32f4 in localtime_r () from /usr/lib/libc.so.1
#6 0x8078c in ErrorLog (s=0xc6110 "Watchdog thread start\n") at
errorlog.c:45
...
(gdb) disassemble 0xff10c548
...
0xff10c52c <_mutex_adaptive_lock+132>: call 0xff11ba7c <_lock_owner>
0xff10c530 <_mutex_adaptive_lock+136>: mov %i0, %o0
0xff10c534 <_mutex_adaptive_lock+140>: cmp %l0, 0x64
0xff10c538 <_mutex_adaptive_lock+144>:
bge 0xff10c590 <_mutex_adaptive_lock+232>
0xff10c53c <_mutex_adaptive_lock+148>: cmp %o0, 0
0xff10c540 <_mutex_adaptive_lock+152>:
be,a 0xff10c594 <_mutex_adaptive_lock+236>
0xff10c544 <_mutex_adaptive_lock+156>: ldub [ %i0 + 0xf ], %l0
0xff10c548 <_mutex_adaptive_lock+160>: ldsb [ %o0 + 0x58 ], %o1 <-- pc
points here
0xff10c54c <_mutex_adaptive_lock+164>: cmp %o1, 4
0xff10c550 <_mutex_adaptive_lock+168>:
bne,a 0xff10c594 <_mutex_adaptive_lock+236>
...
and %o0 is 0xb(11) at "#3 0xff10a320 in _co_timerset () from
/usr/lib/libthread.so.1"
I think localtime_r() uses mutex object to make it as multithread-safe and
first time a process calls localtime_r(), it creates a mutex object and
locks/unlocks it everytime localtime_r() is called. This problem occurs only
by first localtime_r() call in a process. Maybe when localtime_r() creates a
mutex object, it doesn't initialize the mutex object I think.
If anyone had this kind of problem before or have any solution for this,
Thanks in advance.