(linenum→info "unix/slp.c:2238")

glibc/2.7/hurd/catch-exc.c

    1: /* Copyright (C) 1994,95,96,97,2002 Free Software Foundation, Inc.
    2:    This file is part of the GNU C Library.
    3: 
    4:    The GNU C Library is free software; you can redistribute it and/or
    5:    modify it under the terms of the GNU Lesser General Public
    6:    License as published by the Free Software Foundation; either
    7:    version 2.1 of the License, or (at your option) any later version.
    8: 
    9:    The GNU C Library is distributed in the hope that it will be useful,
   10:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12:    Lesser General Public License for more details.
   13: 
   14:    You should have received a copy of the GNU Lesser General Public
   15:    License along with the GNU C Library; if not, write to the Free
   16:    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   17:    02111-1307 USA.  */
   18: 
   19: #include <mach/exc_server.h>
   20: #include <hurd/signal.h>
   21: #include <assert.h>
   22: 
   23: /* Called by the microkernel when a thread gets an exception.  */
   24: 
   25: kern_return_t
   26: _S_catch_exception_raise (mach_port_t port,
   27:                           thread_t thread,
   28:                           task_t task,
   29: #ifdef EXC_MASK_ALL             /* New interface flavor.  */
   30:                           exception_type_t exception,
   31:                           exception_data_t code,
   32:                           mach_msg_type_number_t codeCnt
   33: #else                           /* Vanilla Mach 3.0 interface.  */
   34:                           integer_t exception,
   35:                           integer_t code, integer_t subcode
   36: #endif
   37:                           )
   38: {
   39:   struct hurd_sigstate *ss;
   40:   int signo;
   41:   struct hurd_signal_detail d;
   42: 
   43:   if (task != __mach_task_self ())
   44:     /* The sender wasn't the kernel.  */
   45:     return EPERM;
   46: 
   47:   d.exc = exception;
   48: #ifdef EXC_MASK_ALL
   49:   assert (codeCnt >= 2);
   50:   d.exc_code = code[0];
   51:   d.exc_subcode = code[1];
   52: #else
   53:   d.exc_code = code;
   54:   d.exc_subcode = subcode;
   55: #endif
   56: 
   57:   /* Call the machine-dependent function to translate the Mach exception
   58:      codes into a signal number and subcode.  */
   59:   _hurd_exception2signal (&d, &signo);
   60: 
   61:   /* Find the sigstate structure for the faulting thread.  */
   62:   __mutex_lock (&_hurd_siglock);
   63:   for (ss = _hurd_sigstates; ss != NULL; ss = ss->next)
   64:     if (ss->thread == thread)
   65:       break;
   66:   __mutex_unlock (&_hurd_siglock);
   67:   if (ss == NULL)
   68:     ss = _hurd_thread_sigstate (thread); /* Allocate a fresh one.  */
   69: 
   70:   if (__spin_lock_locked (&ss->lock))
   71:     {
   72:       /* Loser.  The thread faulted with its sigstate lock held.  Its
   73:          sigstate data is now suspect.  So we reset the parts of it which
   74:          could cause trouble for the signal thread.  Anything else
   75:          clobbered therein will just hose this user thread, but it's
   76:          faulting already.
   77: 
   78:          This is almost certainly a library bug: unless random memory
   79:          clobberation caused the sigstate lock to gratuitously appear held,
   80:          no code should do anything that can fault while holding the
   81:          sigstate lock.  */
   82: 
   83:       __spin_unlock (&ss->critical_section_lock);
   84:       ss->context = NULL;
   85:       __spin_unlock (&ss->lock);
   86:     }
   87: 
   88:   /* Post the signal.  */
   89:   _hurd_internal_post_signal (ss, signo, &d,
   90:                               MACH_PORT_NULL, MACH_MSG_TYPE_PORT_SEND,
   91:                               0);
   92: 
   93:   return KERN_SUCCESS;
   94: }
   95: 
   96: #ifdef EXC_MASK_ALL
   97: /* XXX New interface flavor has additional RPCs that we could be using
   98:    instead.  These RPCs roll a thread_get_state/thread_set_state into
   99:    the message, so the signal thread ought to use these to save some calls.
  100:  */
  101: kern_return_t
  102: _S_catch_exception_raise_state (mach_port_t port,
  103:                                 exception_type_t exception,
  104:                                 exception_data_t code,
  105:                                 mach_msg_type_number_t codeCnt,
  106:                                 int *flavor,
  107:                                 thread_state_t old_state,
  108:                                 mach_msg_type_number_t old_stateCnt,
  109:                                 thread_state_t new_state,
  110:                                 mach_msg_type_number_t *new_stateCnt)
  111: {
  112:   abort ();
  113:   return KERN_FAILURE;
  114: }
  115: 
  116: kern_return_t
  117: _S_catch_exception_raise_state_identity (mach_port_t exception_port,
  118:                                          thread_t thread,
  119:                                          task_t task,
  120:                                          exception_type_t exception,
  121:                                          exception_data_t code,
  122:                                          mach_msg_type_number_t codeCnt,
  123:                                          int *flavor,
  124:                                          thread_state_t old_state,
  125:                                          mach_msg_type_number_t old_stateCnt,
  126:                                          thread_state_t new_state,
  127:                                          mach_msg_type_number_t *new_stateCnt)
  128: {
  129:   abort ();
  130:   return KERN_FAILURE;
  131: }
  132: #endif
Syntax (Markdown)