Changeset 11596


Ignore:
Timestamp:
Jan 7, 2009, 10:50:44 AM (11 years ago)
Author:
gb
Message:

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 ?").

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/lisp-kernel/lisp-debug.c

    r11575 r11596  
    6868
    6969Boolean lisp_debugger_in_foreign_code = false;
     70
     71#ifndef WINDOWS
     72Boolean
     73fd0_is_dev_null()
     74{
     75  struct stat fd0stat, devnullstat;
     76
     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));
     85}
     86
     87#endif
    7088
    7189char *
     
    10261044  debug_command_return state = debug_continue;
    10271045
    1028   if (threads_initialized) {
    1029     suspend_other_threads(false);
    1030   }
    1031 
    10321046  va_start(args,message);
    10331047  vfprintf(stderr, message, args);
     
    10351049  va_end(args);
    10361050 
     1051
     1052#ifndef WINDOWS
     1053  if (fd0_is_dev_null()) {
     1054    return -1;
     1055  }
     1056#endif
     1057  if (threads_initialized) {
     1058    suspend_other_threads(false);
     1059  }
     1060
    10371061  lisp_debugger_in_foreign_code = in_foreign_code;
    10381062  if (in_foreign_code) {   
Note: See TracChangeset for help on using the changeset viewer.