Changeset 11596

Jan 7, 2009, 10:50:44 AM (11 years ago)

Print the message before suspending other threads on entry to the
kernel debugger.

Also, check to see if fd 0 is open to /dev/null on entry to the
kernel debugger (after printing the message but before suspending
threads.) If so, exit from the kernel debugger with a non-zero
value; this should cause cases where it's entered in response to
an unhandled exception to set a bit in the TCR and should cause
the exception handler to return (repeating the trap/fault). On
Darwin, the Mach exception handler will assert that the exception
wasn't handled, causing the exception to be passed to a task-level
handler (or signal handler); for an OSX GUI application, this can
cause Apple's crash dialog to be invoked.

We could get a vaguely similar effect on other platforms by
de-installing our signal handler (or Windows exception handler),
but it wouldn't be guaranteed that the next (now fatal) exception
would be the one that we tried to propagate in this way: some
other thread might do something innocuous - like consing - that
raises an unrelated exception.

In the case of an OSX GUI application (that hasn't redirected
its standard fds), we may be able to generate a more meaningful
crash report (with lisp thread info, lisp-aware backtraces, etc.)
than what Apple's crash dialog provides. Apple's mechanism does
at least make it clear that the application terminated abnormally;
writing to syslog or writing to a text file somewhere may leave
some end-users (at least) puzzled ("the application terminated
unexpectedly, and I wasn't notified ?").

1 edited


  • trunk/source/lisp-kernel/lisp-debug.c

    r11575 r11596  
    6969Boolean lisp_debugger_in_foreign_code = false;
     71#ifndef WINDOWS
     75  struct stat fd0stat, devnullstat;
     77  if (fstat(0,&fd0stat)) {
     78    return true;
     79  }
     80  if (stat("/dev/null",&devnullstat)) {
     81    return true;
     82  }
     83  return ((fd0stat.st_ino == devnullstat.st_ino) &&
     84          (fd0stat.st_dev == devnullstat.st_dev));
    7189char *
    10261044  debug_command_return state = debug_continue;
    1028   if (threads_initialized) {
    1029     suspend_other_threads(false);
    1030   }
    10321046  va_start(args,message);
    10331047  vfprintf(stderr, message, args);
    10351049  va_end(args);
     1052#ifndef WINDOWS
     1053  if (fd0_is_dev_null()) {
     1054    return -1;
     1055  }
     1057  if (threads_initialized) {
     1058    suspend_other_threads(false);
     1059  }
    10371061  lisp_debugger_in_foreign_code = in_foreign_code;
    10381062  if (in_foreign_code) {   
Note: See TracChangeset for help on using the changeset viewer.