This is the mail archive of the libc-alpha@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[Bug, 2.1.3] getlogin() can call alarm() but shouldn't.



Version

This has been observed to occur in glibc 2.1.3.

Short Description

getlogin() can call alarm() but shouldn't

Symptoms

1. Applications are likely to loose
resolution and their timers will fail to restart.

2. XEmacs will crash when used with socks under glibc 2.1.3 with the
following back trace.

#10 0x8094ee4 in assert_failed (..
 at /usr/local/src/XEmacs-21.2/src/emacs.c:2770
 #11 0x81bde9d in alarm (howlong=0)
 at /usr/local/src/XEmacs-21.2/src/signal.c:340
 #12 0x4055045d in getutline_r () from /lib/libc.so.6
 #14 0x40509b5d in getlogin () from /lib/libc.so.6
 #15 0x400183c1 in lsEffUser () from /usr/local/lib/libsocks5_sh.so
 #18 0x4002262f in connect () from /usr/local/lib/libsocks5_sh.so
 #26 0x4051664b in getaddrinfo () from /lib/libc.so.6
 #27 0x81d386d in init_system_name ()
 at /usr/local/src/XEmacs-21.2/src/sysdep.c:2361

XEmacs uses itimers heavily and
reimplements alarm() (and setitimer) to make sure nobody calls it
inappropriately. Libraries that are known to use it are carefully
wrapped with code that manages the XEmacs timers. Unfortunately as
seen above, with socks any call to the network can potentially call
alarm.

Solutions

1. [prefered] Glibc should never mess with the SIGALRM timer
   internally.
2. getitimer/setitimer should be used instead of alarm. This will
   at least preserve more information.

Why is messing with the timer bad?

This from a message (from yours truly) previously posted to the XEmacs
use

Typical usage is, i.e.  (this is also what is used in glibc).

old_timeout = alarm(0);
push new SIGALARM handler
alarm(our_time);
/* do your thing */
alarm(0);
pop SIGALARM handler
alarm(old_timeout);

The reason XEmacs overrides the alarm() functions is exactly to detect
stuff like this because it is often wrong

urysohn:/tmp> gcc testlarm.c [1]
urysohn:/tmp> ./a.out 
value from alarm() was : 1
Restored to: 1.000000 s , should be 0.000500 s
Repeat to: 0.000000 s , should be 0.000700 s

So IMO this is a bug in glibc (should I file one?)

1. This really is a wart in the Unix API. The above code is only
   correct if our_time << old_timeout (because it doesn't check for
   the fact that the real timer could very well have expired). For that
   reason it would be really nice if glibc would refrain from messing with
   the timers, especially in stuff like get_login() where it is not
   obvious.
2. If it really wants to mess with the timer (Don't the posix realtime
   extensions now offer independent timers?), it should do so using
   getitimer/setitimer because that doesn't loose precision and repeat
   values.

Jan

Footnotes: 
[1]
#include <stdio.h>
#include <sys/time.h>
#include <time.h>

int main (int argc, char *argv[])
{
  struct itimerval mydelay = {{0, 700} , {0,500}}; /* 500 msec, repeat 700 */
  struct itimerval newdelay;
  int inseconds;

  
  if (setitimer(ITIMER_REAL,&mydelay,NULL))
    {
      perror("setimer: ");
      exit(1);
    }
  inseconds = alarm(0);
  alarm(inseconds);
  getitimer(ITIMER_REAL,&newdelay);
  alarm(0);
  printf("value from alarm() was : %i\n",inseconds);
  printf("Restored to: %li.%6.6li s , should be %li.%6.6li s\n",
         newdelay.it_value.tv_sec, newdelay.it_value.tv_usec,
         mydelay.it_value.tv_sec, mydelay.it_value.tv_usec);
  printf("Repeat to: %li.%6.6li s , should be %li.%6.6li s\n",
         newdelay.it_interval.tv_sec, newdelay.it_interval.tv_usec,
         mydelay.it_interval.tv_sec, mydelay.it_interval.tv_usec);
}




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]