[Gc] [rfc] cleanup patch and code style questions os_dep.c

Andreas Tobler toa at pop.agri.ch
Sat Jan 13 13:12:39 PST 2007


Hi all,

I tried to clean up the part in os_dep.c under #if defined(MPROTECT_VDB) 
&& defined(DARWIN).

For me it is non readable and I wanted to give it a try.

Here my second trial, the first went to Hans only and we agreed to ask 
the list on comments.

I work with tabs and ident=2.
I tried to clear the issues from you Hans, but I'm not sure if I got 
them all. Also, some of the formatting was wrong before in regard of 
if(defs|defined).

All, could you please highlight the parts which you think are wrong and 
comment on them?

Thanks in advance.

Andreas



-------------- next part --------------
Index: os_dep.c
===================================================================
RCS file: /cvsroot/bdwgc/bdwgc/os_dep.c,v
retrieving revision 1.18
diff -u -r1.18 os_dep.c
--- os_dep.c	11 Jan 2007 19:32:44 -0000	1.18
+++ os_dep.c	13 Jan 2007 21:04:53 -0000
@@ -3437,15 +3437,16 @@
    code:
       1. Apple's mach/xnu documentation
       2. Timothy J. Wood's "Mach Exception Handlers 101" post to the
-         omnigroup's macosx-dev list. 
+         omnigroup's macosx-dev list.
          www.omnigroup.com/mailman/archive/macosx-dev/2000-June/002030.html
       3. macosx-nat.c from Apple's GDB source code.
 */
-   
+
 /* The bug that caused all this trouble should now be fixed. This should
    eventually be removed if all goes well. */
+
 /* define BROKEN_EXCEPTION_HANDLING */
-    
+
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 #include <mach/thread_status.h>
@@ -3510,62 +3511,52 @@
 
 /* The following should ONLY be called when the world is stopped  */
 static void GC_mprotect_thread_notify(mach_msg_id_t id) {
-    struct {
-        GC_msg_t msg;
-        mach_msg_trailer_t trailer;
-    } buf;
-    mach_msg_return_t r;
-    /* remote, local */
-    buf.msg.head.msgh_bits = 
-        MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND,0);
-    buf.msg.head.msgh_size = sizeof(buf.msg);
-    buf.msg.head.msgh_remote_port = GC_ports.exception;
-    buf.msg.head.msgh_local_port = MACH_PORT_NULL;
-    buf.msg.head.msgh_id = id;
-            
-    r = mach_msg(
-        &buf.msg.head,
-        MACH_SEND_MSG|MACH_RCV_MSG|MACH_RCV_LARGE,
-        sizeof(buf.msg),
-        sizeof(buf),
-        GC_ports.reply,
-        MACH_MSG_TIMEOUT_NONE,
-        MACH_PORT_NULL);
-    if(r != MACH_MSG_SUCCESS)
-	ABORT("mach_msg failed in GC_mprotect_thread_notify");
-    if(buf.msg.head.msgh_id != ID_ACK)
-        ABORT("invalid ack in GC_mprotect_thread_notify");
+
+  struct {
+    GC_msg_t msg;
+    mach_msg_trailer_t trailer;
+  } buf;
+
+  mach_msg_return_t r;
+  /* remote, local */
+  buf.msg.head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
+  buf.msg.head.msgh_size = sizeof(buf.msg);
+  buf.msg.head.msgh_remote_port = GC_ports.exception;
+  buf.msg.head.msgh_local_port = MACH_PORT_NULL;
+  buf.msg.head.msgh_id = id;
+
+  r = mach_msg(&buf.msg.head, MACH_SEND_MSG | MACH_RCV_MSG | MACH_RCV_LARGE,
+	       sizeof(buf.msg), sizeof(buf), GC_ports.reply,
+	       MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+  if(r != MACH_MSG_SUCCESS)
+    ABORT("mach_msg failed in GC_mprotect_thread_notify");
+  if(buf.msg.head.msgh_id != ID_ACK)
+    ABORT("invalid ack in GC_mprotect_thread_notify");
 }
 
 /* Should only be called by the mprotect thread */
 static void GC_mprotect_thread_reply(void) {
-    GC_msg_t msg;
-    mach_msg_return_t r;
-    /* remote, local */
-    msg.head.msgh_bits = 
-        MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND,0);
-    msg.head.msgh_size = sizeof(msg);
-    msg.head.msgh_remote_port = GC_ports.reply;
-    msg.head.msgh_local_port = MACH_PORT_NULL;
-    msg.head.msgh_id = ID_ACK;
-            
-    r = mach_msg(
-        &msg.head,
-        MACH_SEND_MSG,
-        sizeof(msg),
-        0,
-        MACH_PORT_NULL,
-        MACH_MSG_TIMEOUT_NONE,
-        MACH_PORT_NULL);
-    if(r != MACH_MSG_SUCCESS)
-	ABORT("mach_msg failed in GC_mprotect_thread_reply");
+
+  GC_msg_t msg;
+  mach_msg_return_t r;
+  /* remote, local */
+  msg.head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);
+  msg.head.msgh_size = sizeof(msg);
+  msg.head.msgh_remote_port = GC_ports.reply;
+  msg.head.msgh_local_port = MACH_PORT_NULL;
+  msg.head.msgh_id = ID_ACK;
+
+  r = mach_msg(&msg.head, MACH_SEND_MSG, sizeof(msg), 0, MACH_PORT_NULL,
+	       MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+  if(r != MACH_MSG_SUCCESS)
+    ABORT("mach_msg failed in GC_mprotect_thread_reply");
 }
 
 void GC_mprotect_stop(void) {
-    GC_mprotect_thread_notify(ID_STOP);
+  GC_mprotect_thread_notify(ID_STOP);
 }
 void GC_mprotect_resume(void) {
-    GC_mprotect_thread_notify(ID_RESUME);
+  GC_mprotect_thread_notify(ID_RESUME);
 }
 
 #else /* !THREADS */
@@ -3574,97 +3565,87 @@
 #endif
 
 static void *GC_mprotect_thread(void *arg) {
-    mach_msg_return_t r;
-    /* These two structures contain some private kernel data. We don't need to
-       access any of it so we don't bother defining a proper struct. The
-       correct definitions are in the xnu source code. */
-    struct {
-        mach_msg_header_t head;
-        char data[256];
-    } reply;
-    struct {
-        mach_msg_header_t head;
-        mach_msg_body_t msgh_body;
-        char data[1024];
-    } msg;
-
-    mach_msg_id_t id;
-
-    GC_darwin_register_mach_handler_thread(mach_thread_self());
-    
-    for(;;) {
-        r = mach_msg(
-            &msg.head,
-            MACH_RCV_MSG|MACH_RCV_LARGE|
-                (GC_mprotect_state == GC_MP_DISCARDING ? MACH_RCV_TIMEOUT : 0),
-            0,
-            sizeof(msg),
-            GC_ports.exception,
-            GC_mprotect_state == GC_MP_DISCARDING ? 0 : MACH_MSG_TIMEOUT_NONE,
-            MACH_PORT_NULL);
-        
-        id = r == MACH_MSG_SUCCESS ? msg.head.msgh_id : -1;
-        
-#       if defined(THREADS)
-          if(GC_mprotect_state == GC_MP_DISCARDING) {
-            if(r == MACH_RCV_TIMED_OUT) {
-                GC_mprotect_state = GC_MP_STOPPED;
-                GC_mprotect_thread_reply();
-                continue;
-            }
-            if(r == MACH_MSG_SUCCESS && (id == ID_STOP || id == ID_RESUME))
-                ABORT("out of order mprotect thread request");
-          }
-#       endif /* THREADS */
-        
-        if(r != MACH_MSG_SUCCESS) {
-            GC_err_printf("mach_msg failed with %d %s\n", 
-                (int)r, mach_error_string(r));
-            ABORT("mach_msg failed");
-        }
-        
-        switch(id) {
-#         if defined(THREADS)
-            case ID_STOP:
-                if(GC_mprotect_state != GC_MP_NORMAL)
-                    ABORT("Called mprotect_stop when state wasn't normal");
-                GC_mprotect_state = GC_MP_DISCARDING;
-                break;
-            case ID_RESUME:
-                if(GC_mprotect_state != GC_MP_STOPPED)
-                    ABORT("Called mprotect_resume when state wasn't stopped");
-                GC_mprotect_state = GC_MP_NORMAL;
-                GC_mprotect_thread_reply();
-                break;
-#         endif /* THREADS */
-            default:
-	            /* Handle the message (calls catch_exception_raise) */
-    	        if(!exc_server(&msg.head,&reply.head))
-                    ABORT("exc_server failed");
-                /* Send the reply */
-                r = mach_msg(
-                    &reply.head,
-                    MACH_SEND_MSG,
-                    reply.head.msgh_size,
-                    0,
-                    MACH_PORT_NULL,
-                    MACH_MSG_TIMEOUT_NONE,
-                    MACH_PORT_NULL);
-	        if(r != MACH_MSG_SUCCESS) {
-	            /* This will fail if the thread dies, but the thread */
-		    /* shouldn't die... */
-#		    ifdef BROKEN_EXCEPTION_HANDLING
-    	              GC_err_printf(
-                        "mach_msg failed with %d %s while sending exc reply\n",
-                        (int)r,mach_error_string(r));
-#  		    else
-    	        	ABORT("mach_msg failed while sending exception reply");
-#                   endif
-        	}
-        } /* switch */
-    } /* for(;;) */
+  mach_msg_return_t r;
+  /* These two structures contain some private kernel data. We don't need to
+     access any of it so we don't bother defining a proper struct. The
+     correct definitions are in the xnu source code. */
+  struct {
+    mach_msg_header_t head;
+    char data[256];
+  } reply;
+  struct {
+    mach_msg_header_t head;
+    mach_msg_body_t msgh_body;
+    char data[1024];
+  } msg;
+
+  mach_msg_id_t id;
+
+  GC_darwin_register_mach_handler_thread(mach_thread_self());
+
+  for(;;) {
+    r = mach_msg(&msg.head, MACH_RCV_MSG | MACH_RCV_LARGE |
+		 (GC_mprotect_state == GC_MP_DISCARDING ? MACH_RCV_TIMEOUT : 0),
+		 0, sizeof(msg), GC_ports.exception,
+		 GC_mprotect_state == GC_MP_DISCARDING ? 0
+		 : MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+
+    id = r == MACH_MSG_SUCCESS ? msg.head.msgh_id : -1;
+
+#   if defined(THREADS)
+      if(GC_mprotect_state == GC_MP_DISCARDING) {
+	if(r == MACH_RCV_TIMED_OUT) {
+	  GC_mprotect_state = GC_MP_STOPPED;
+	  GC_mprotect_thread_reply();
+	  continue;
+	}
+	if(r == MACH_MSG_SUCCESS && (id == ID_STOP || id == ID_RESUME))
+	  ABORT("out of order mprotect thread request");
+      }
+#   endif /* THREADS */
+
+    if(r != MACH_MSG_SUCCESS) {
+      GC_err_printf("mach_msg failed with %d %s\n", (int)r,
+		    mach_error_string(r));
+      ABORT("mach_msg failed");
+    }
+
+    switch(id) {
+#     if defined(THREADS)
+        case ID_STOP:
+	  if(GC_mprotect_state != GC_MP_NORMAL)
+	    ABORT("Called mprotect_stop when state wasn't normal");
+	  GC_mprotect_state = GC_MP_DISCARDING;
+	  break;
+        case ID_RESUME:
+	  if(GC_mprotect_state != GC_MP_STOPPED)
+	    ABORT("Called mprotect_resume when state wasn't stopped");
+	  GC_mprotect_state = GC_MP_NORMAL;
+	  GC_mprotect_thread_reply();
+	  break;
+#     endif /* THREADS */
+        default:
+	  /* Handle the message (calls catch_exception_raise) */
+	  if(!exc_server(&msg.head, &reply.head))
+	    ABORT("exc_server failed");
+	  /* Send the reply */
+	  r = mach_msg(&reply.head, MACH_SEND_MSG, reply.head.msgh_size, 0,
+		       MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
+		       MACH_PORT_NULL);
+	  if(r != MACH_MSG_SUCCESS) {
+	    /* This will fail if the thread dies, but the thread */
+	    /* shouldn't die... */
+#           ifdef BROKEN_EXCEPTION_HANDLING
+	      GC_err_printf("mach_msg failed with %d %s while sending"
+			    "exc reply\n", (int)r,mach_error_string(r));
+#           else
+	      ABORT("mach_msg failed while sending exception reply");
+#           endif
+	  }
+    } /* switch */
+  } /* for(;;) */
     /* NOT REACHED */
-    return NULL;
+  return NULL;
 }
 
 /* All this SIGBUS code shouldn't be necessary. All protection faults should
@@ -3680,320 +3661,314 @@
    Even if this doesn't get updated property, it isn't really a problem */
 static int GC_sigbus_count;
 
-static void GC_darwin_sigbus(int num,siginfo_t *sip,void *context) {
-    if(num != SIGBUS) ABORT("Got a non-sigbus signal in the sigbus handler");
-    
-    /* Ugh... some seem safe to ignore, but too many in a row probably means
-       trouble. GC_sigbus_count is reset for each mach exception that is
-       handled */
-    if(GC_sigbus_count >= 8) {
-        ABORT("Got more than 8 SIGBUSs in a row!");
-    } else {
-        GC_sigbus_count++;
-        GC_err_printf("GC: WARNING: Ignoring SIGBUS.\n");
-    }
+static void GC_darwin_sigbus(int num, siginfo_t *sip, void *context) {
+  if(num != SIGBUS)
+    ABORT("Got a non-sigbus signal in the sigbus handler");
+
+  /* Ugh... some seem safe to ignore, but too many in a row probably means
+     trouble. GC_sigbus_count is reset for each mach exception that is
+     handled */
+  if(GC_sigbus_count >= 8) {
+    ABORT("Got more than 8 SIGBUSs in a row!");
+  } else {
+    GC_sigbus_count++;
+    GC_err_printf("GC: WARNING: Ignoring SIGBUS.\n");
+  }
 }
 #endif /* BROKEN_EXCEPTION_HANDLING */
 
 void GC_dirty_init(void) {
-    kern_return_t r;
-    mach_port_t me;
-    pthread_t thread;
-    pthread_attr_t attr;
-    exception_mask_t mask;
-    
-    if (GC_print_stats == VERBOSE)
-        GC_log_printf("Inititalizing mach/darwin mprotect virtual dirty bit "
-                      "implementation\n");
-#   ifdef BROKEN_EXCEPTION_HANDLING
-        GC_err_printf("GC: WARNING: Enabling workarounds for various darwin "
-            "exception handling bugs.\n");
-#   endif
-    GC_dirty_maintained = TRUE;
-    if (GC_page_size % HBLKSIZE != 0) {
-        GC_err_printf("Page size not multiple of HBLKSIZE\n");
-        ABORT("Page size not multiple of HBLKSIZE");
-    }
-    
-    GC_task_self = me = mach_task_self();
-    
-    r = mach_port_allocate(me,MACH_PORT_RIGHT_RECEIVE,&GC_ports.exception);
-    if(r != KERN_SUCCESS) ABORT("mach_port_allocate failed (exception port)");
-    
-    r = mach_port_insert_right(me,GC_ports.exception,GC_ports.exception,
-    	MACH_MSG_TYPE_MAKE_SEND);
-    if(r != KERN_SUCCESS)
-    	ABORT("mach_port_insert_right failed (exception port)");
+  kern_return_t r;
+  mach_port_t me;
+  pthread_t thread;
+  pthread_attr_t attr;
+  exception_mask_t mask;
+
+  if (GC_print_stats == VERBOSE)
+    GC_log_printf("Inititalizing mach/darwin mprotect virtual dirty bit "
+		  "implementation\n");
+# ifdef BROKEN_EXCEPTION_HANDLING
+    GC_err_printf("GC: WARNING: Enabling workarounds for various darwin "
+		"exception handling bugs.\n");
+# endif
+  GC_dirty_maintained = TRUE;
+  if (GC_page_size % HBLKSIZE != 0) {
+    GC_err_printf("Page size not multiple of HBLKSIZE\n");
+    ABORT("Page size not multiple of HBLKSIZE");
+  }
 
-    #if defined(THREADS)
-        r = mach_port_allocate(me,MACH_PORT_RIGHT_RECEIVE,&GC_ports.reply);
-        if(r != KERN_SUCCESS) ABORT("mach_port_allocate failed (reply port)");
-    #endif
-
-    /* The exceptions we want to catch */  
-    mask = EXC_MASK_BAD_ACCESS;
-
-    r = task_get_exception_ports(
-        me,
-        mask,
-        GC_old_exc_ports.masks,
-        &GC_old_exc_ports.count,
-        GC_old_exc_ports.ports,
-        GC_old_exc_ports.behaviors,
-        GC_old_exc_ports.flavors
-    );
-    if(r != KERN_SUCCESS) ABORT("task_get_exception_ports failed");
-        
-    r = task_set_exception_ports(
-        me,
-        mask,
-        GC_ports.exception,
-        EXCEPTION_DEFAULT,
-        GC_MACH_THREAD_STATE
-    );
-    if(r != KERN_SUCCESS) ABORT("task_set_exception_ports failed");
-
-    if(pthread_attr_init(&attr) != 0) ABORT("pthread_attr_init failed");
-    if(pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED) != 0) 
-        ABORT("pthread_attr_setdetachedstate failed");
-
-#	undef pthread_create
-    /* This will call the real pthread function, not our wrapper */
-    if(pthread_create(&thread,&attr,GC_mprotect_thread,NULL) != 0)
-        ABORT("pthread_create failed");
-    pthread_attr_destroy(&attr);
-    
-    /* Setup the sigbus handler for ignoring the meaningless SIGBUSs */
-    #ifdef BROKEN_EXCEPTION_HANDLING 
+  GC_task_self = me = mach_task_self();
+
+  r = mach_port_allocate(me, MACH_PORT_RIGHT_RECEIVE, &GC_ports.exception);
+  if(r != KERN_SUCCESS)
+    ABORT("mach_port_allocate failed (exception port)");
+
+  r = mach_port_insert_right(me, GC_ports.exception, GC_ports.exception,
+			     MACH_MSG_TYPE_MAKE_SEND);
+  if(r != KERN_SUCCESS)
+    ABORT("mach_port_insert_right failed (exception port)");
+
+#  if defined(THREADS)
+     r = mach_port_allocate(me, MACH_PORT_RIGHT_RECEIVE, &GC_ports.reply);
+     if(r != KERN_SUCCESS)
+       ABORT("mach_port_allocate failed (reply port)");
+#  endif
+
+  /* The exceptions we want to catch */
+  mask = EXC_MASK_BAD_ACCESS;
+
+  r = task_get_exception_ports(me, mask, GC_old_exc_ports.masks,
+			       &GC_old_exc_ports.count, GC_old_exc_ports.ports,
+			       GC_old_exc_ports.behaviors,
+			       GC_old_exc_ports.flavors);
+  if(r != KERN_SUCCESS)
+    ABORT("task_get_exception_ports failed");
+
+  r = task_set_exception_ports(me, mask, GC_ports.exception, EXCEPTION_DEFAULT,
+			       GC_MACH_THREAD_STATE);
+  if(r != KERN_SUCCESS)
+    ABORT("task_set_exception_ports failed");
+  if(pthread_attr_init(&attr) != 0)
+    ABORT("pthread_attr_init failed");
+  if(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
+    ABORT("pthread_attr_setdetachedstate failed");
+
+# undef pthread_create
+  /* This will call the real pthread function, not our wrapper */
+  if(pthread_create(&thread, &attr, GC_mprotect_thread, NULL) != 0)
+    ABORT("pthread_create failed");
+  pthread_attr_destroy(&attr);
+
+  /* Setup the sigbus handler for ignoring the meaningless SIGBUSs */
+# ifdef BROKEN_EXCEPTION_HANDLING
     {
-        struct sigaction sa, oldsa;
-        sa.sa_handler = (SIG_HNDLR_PTR)GC_darwin_sigbus;
-        sigemptyset(&sa.sa_mask);
-        sa.sa_flags = SA_RESTART|SA_SIGINFO;
-        if(sigaction(SIGBUS,&sa,&oldsa) < 0) ABORT("sigaction");
-        GC_old_bus_handler = (SIG_HNDLR_PTR)oldsa.sa_handler;
-        if (GC_old_bus_handler != SIG_DFL) {
- 	    if (GC_print_stats == VERBOSE)
-                GC_err_printf("Replaced other SIGBUS handler\n");
-        }
+      struct sigaction sa, oldsa;
+      sa.sa_handler = (SIG_HNDLR_PTR)GC_darwin_sigbus;
+      sigemptyset(&sa.sa_mask);
+      sa.sa_flags = SA_RESTART|SA_SIGINFO;
+      if(sigaction(SIGBUS, &sa, &oldsa) < 0)
+	ABORT("sigaction");
+      GC_old_bus_handler = (SIG_HNDLR_PTR)oldsa.sa_handler;
+      if (GC_old_bus_handler != SIG_DFL) {
+	if (GC_print_stats == VERBOSE)
+	  GC_err_printf("Replaced other SIGBUS handler\n");
+      }
     }
-    #endif /* BROKEN_EXCEPTION_HANDLING  */
+#  endif /* BROKEN_EXCEPTION_HANDLING  */
 }
- 
+
 /* The source code for Apple's GDB was used as a reference for the exception
-   forwarding code. This code is similar to be GDB code only because there is 
+   forwarding code. This code is similar to be GDB code only because there is
    only one way to do it. */
-static kern_return_t GC_forward_exception(
-        mach_port_t thread,
-        mach_port_t task,
-        exception_type_t exception,
-        exception_data_t data,
-        mach_msg_type_number_t data_count
-) {
-    int i;
-    kern_return_t r;
-    mach_port_t port;
-    exception_behavior_t behavior;
-    thread_state_flavor_t flavor;
-    
-    thread_state_t thread_state;
-    mach_msg_type_number_t thread_state_count = THREAD_STATE_MAX;
-        
-    for(i=0;i<GC_old_exc_ports.count;i++)
-        if(GC_old_exc_ports.masks[i] & (1 << exception))
-            break;
-    if(i==GC_old_exc_ports.count) ABORT("No handler for exception!");
-    
-    port = GC_old_exc_ports.ports[i];
-    behavior = GC_old_exc_ports.behaviors[i];
-    flavor = GC_old_exc_ports.flavors[i];
-
-    if(behavior != EXCEPTION_DEFAULT) {
-        r = thread_get_state(thread,flavor,thread_state,&thread_state_count);
-        if(r != KERN_SUCCESS)
-            ABORT("thread_get_state failed in forward_exception");
-    }
-    
-    switch(behavior) {
-        case EXCEPTION_DEFAULT:
-            r = exception_raise(port,thread,task,exception,data,data_count);
-            break;
-        case EXCEPTION_STATE:
-            r = exception_raise_state(port,thread,task,exception,data,
-                data_count,&flavor,thread_state,thread_state_count,
-                thread_state,&thread_state_count);
-            break;
-        case EXCEPTION_STATE_IDENTITY:
-            r = exception_raise_state_identity(port,thread,task,exception,data,
-                data_count,&flavor,thread_state,thread_state_count,
-                thread_state,&thread_state_count);
-            break;
-        default:
-            r = KERN_FAILURE; /* make gcc happy */
-            ABORT("forward_exception: unknown behavior");
-            break;
-    }
-    
-    if(behavior != EXCEPTION_DEFAULT) {
-        r = thread_set_state(thread,flavor,thread_state,thread_state_count);
-        if(r != KERN_SUCCESS)
-            ABORT("thread_set_state failed in forward_exception");
+static kern_return_t GC_forward_exception(mach_port_t thread, mach_port_t task,
+					  exception_type_t exception,
+					  exception_data_t data,
+					  mach_msg_type_number_t data_count) {
+  int i;
+  kern_return_t r;
+  mach_port_t port;
+  exception_behavior_t behavior;
+  thread_state_flavor_t flavor;
+
+  thread_state_t thread_state;
+  mach_msg_type_number_t thread_state_count = THREAD_STATE_MAX;
+
+  for(i=0; i < GC_old_exc_ports.count; i++)
+    if(GC_old_exc_ports.masks[i] & (1 << exception))
+      break;
+  if(i==GC_old_exc_ports.count)
+    ABORT("No handler for exception!");
+
+  port = GC_old_exc_ports.ports[i];
+  behavior = GC_old_exc_ports.behaviors[i];
+  flavor = GC_old_exc_ports.flavors[i];
+
+  if(behavior != EXCEPTION_DEFAULT) {
+    r = thread_get_state(thread, flavor, thread_state, &thread_state_count);
+    if(r != KERN_SUCCESS)
+      ABORT("thread_get_state failed in forward_exception");
     }
-    
-    return r;
+
+  switch(behavior) {
+    case EXCEPTION_DEFAULT:
+      r = exception_raise(port, thread, task, exception, data, data_count);
+      break;
+    case EXCEPTION_STATE:
+      r = exception_raise_state(port, thread, task, exception, data, data_count,
+				&flavor, thread_state, thread_state_count,
+				thread_state, &thread_state_count);
+      break;
+    case EXCEPTION_STATE_IDENTITY:
+      r = exception_raise_state_identity(port, thread, task, exception, data,
+					 data_count, &flavor, thread_state,
+					 thread_state_count, thread_state,
+					 &thread_state_count);
+      break;
+    default:
+      r = KERN_FAILURE; /* make gcc happy */
+      ABORT("forward_exception: unknown behavior");
+      break;
+  }
+
+  if(behavior != EXCEPTION_DEFAULT) {
+    r = thread_set_state(thread, flavor, thread_state, thread_state_count);
+    if(r != KERN_SUCCESS)
+      ABORT("thread_set_state failed in forward_exception");
+  }
+
+  return r;
 }
 
-#define FWD() GC_forward_exception(thread,task,exception,code,code_count)
+#define FWD() GC_forward_exception(thread, task, exception, code, code_count)
 
 /* This violates the namespace rules but there isn't anything that can be done
    about it. The exception handling stuff is hard coded to call this */
 kern_return_t
-catch_exception_raise(
-   mach_port_t exception_port,mach_port_t thread,mach_port_t task,
-   exception_type_t exception,exception_data_t code,
-   mach_msg_type_number_t code_count
-) {
-    kern_return_t r;
-    char *addr;
-    struct hblk *h;
-    int i;
-#   if defined(POWERPC)
-#     if CPP_WORDSZ == 32
-        thread_state_flavor_t flavor = PPC_EXCEPTION_STATE;
-	mach_msg_type_number_t exc_state_count = PPC_EXCEPTION_STATE_COUNT;
-	ppc_exception_state_t exc_state;
-#     else
-	thread_state_flavor_t flavor = PPC_EXCEPTION_STATE64;
-	mach_msg_type_number_t exc_state_count = PPC_EXCEPTION_STATE64_COUNT;
-	ppc_exception_state64_t exc_state;
-#     endif
-#   elif defined(I386) || defined(X86_64)
-#     if CPP_WORDSZ == 32
-	thread_state_flavor_t flavor = x86_EXCEPTION_STATE32;
-	mach_msg_type_number_t exc_state_count = x86_EXCEPTION_STATE32_COUNT;
-	x86_exception_state32_t exc_state;
-#     else
-	thread_state_flavor_t flavor = x86_EXCEPTION_STATE64;
-	mach_msg_type_number_t exc_state_count = x86_EXCEPTION_STATE64_COUNT;
-	x86_exception_state64_t exc_state;
-#     endif
+catch_exception_raise(mach_port_t exception_port, mach_port_t thread,
+		      mach_port_t task, exception_type_t exception,
+		      exception_data_t code, mach_msg_type_number_t code_count)
+{
+  kern_return_t r;
+  char *addr;
+  struct hblk *h;
+  int i;
+# if defined(POWERPC)
+#   if CPP_WORDSZ == 32
+      thread_state_flavor_t flavor = PPC_EXCEPTION_STATE;
+      mach_msg_type_number_t exc_state_count = PPC_EXCEPTION_STATE_COUNT;
+      ppc_exception_state_t exc_state;
+#   else
+      thread_state_flavor_t flavor = PPC_EXCEPTION_STATE64;
+      mach_msg_type_number_t exc_state_count = PPC_EXCEPTION_STATE64_COUNT;
+      ppc_exception_state64_t exc_state;
+#   endif
+# elif defined(I386) || defined(X86_64)
+#   if CPP_WORDSZ == 32
+      thread_state_flavor_t flavor = x86_EXCEPTION_STATE32;
+      mach_msg_type_number_t exc_state_count = x86_EXCEPTION_STATE32_COUNT;
+      x86_exception_state32_t exc_state;
 #   else
-#	error FIXME for non-ppc/x86 darwin
+      thread_state_flavor_t flavor = x86_EXCEPTION_STATE64;
+      mach_msg_type_number_t exc_state_count = x86_EXCEPTION_STATE64_COUNT;
+      x86_exception_state64_t exc_state;
 #   endif
+# else
+#   error FIXME for non-ppc/x86 darwin
+# endif
 
-    
-    if(exception != EXC_BAD_ACCESS || code[0] != KERN_PROTECTION_FAILURE) {
-        #ifdef DEBUG_EXCEPTION_HANDLING
-        /* We aren't interested, pass it on to the old handler */
-        GC_printf("Exception: 0x%x Code: 0x%x 0x%x in catch....\n",
-            exception,
-            code_count > 0 ? code[0] : -1,
-            code_count > 1 ? code[1] : -1); 
-        #endif
-        return FWD();
-    }
 
-    r = thread_get_state(thread,flavor,
-        (natural_t*)&exc_state,&exc_state_count);
-    if(r != KERN_SUCCESS) {
-        /* The thread is supposed to be suspended while the exception handler
-           is called. This shouldn't fail. */
-        #ifdef BROKEN_EXCEPTION_HANDLING
-            GC_err_printf("thread_get_state failed in "
-            		  "catch_exception_raise\n");
-            return KERN_SUCCESS;
-        #else
-            ABORT("thread_get_state failed in catch_exception_raise");
-        #endif
-    }
-    
+  if(exception != EXC_BAD_ACCESS || code[0] != KERN_PROTECTION_FAILURE) {
+#   ifdef DEBUG_EXCEPTION_HANDLING
+      /* We aren't interested, pass it on to the old handler */
+      GC_printf("Exception: 0x%x Code: 0x%x 0x%x in catch....\n", exception,
+		code_count > 0 ? code[0] : -1, code_count > 1 ? code[1] : -1);
+#   endif
+    return FWD();
+  }
+
+  r = thread_get_state(thread, flavor, (natural_t*)&exc_state,
+		       &exc_state_count);
+  if(r != KERN_SUCCESS) {
+    /* The thread is supposed to be suspended while the exception handler
+       is called. This shouldn't fail. */
+#   ifdef BROKEN_EXCEPTION_HANDLING
+      GC_err_printf("thread_get_state failed in catch_exception_raise\n");
+      return KERN_SUCCESS;
+#   else
+      ABORT("thread_get_state failed in catch_exception_raise");
+#   endif
+  }
+
     /* This is the address that caused the fault */
-#if defined(POWERPC)
+# if defined(POWERPC)
     addr = (char*) exc_state.dar;
-#elif defined (I386) || defined (X86_64)
+# elif defined (I386) || defined (X86_64)
     addr = (char*) exc_state.faultvaddr;
-#else
+# else
 #   error FIXME for non POWERPC/I386
-#endif
-        
+# endif
+
     if((HDR(addr)) == 0) {
-        /* Ugh... just like the SIGBUS problem above, it seems we get a bogus 
-           KERN_PROTECTION_FAILURE every once and a while. We wait till we get
-           a bunch in a row before doing anything about it. If a "real" fault 
-           ever occurres it'll just keep faulting over and over and we'll hit
-           the limit pretty quickly. */
-        #ifdef BROKEN_EXCEPTION_HANDLING
-            static char *last_fault;
-            static int last_fault_count;
-            
-            if(addr != last_fault) {
-                last_fault = addr;
-                last_fault_count = 0;
-            }
-            if(++last_fault_count < 32) {
-                if(last_fault_count == 1)
-                    GC_err_printf(
-                        "GC: WARNING: Ignoring KERN_PROTECTION_FAILURE at %p\n",
-                        addr);
-                return KERN_SUCCESS;
-            }
-            
-            GC_err_printf("Unexpected KERN_PROTECTION_FAILURE at %p\n",addr);
-            /* Can't pass it along to the signal handler because that is
-               ignoring SIGBUS signals. We also shouldn't call ABORT here as
-               signals don't always work too well from the exception handler. */
-            GC_err_printf("Aborting\n");
-            exit(EXIT_FAILURE);
-        #else /* BROKEN_EXCEPTION_HANDLING */
-            /* Pass it along to the next exception handler 
-               (which should call SIGBUS/SIGSEGV) */
-            return FWD();
-        #endif /* !BROKEN_EXCEPTION_HANDLING */
+      /* Ugh... just like the SIGBUS problem above, it seems we get a bogus
+	 KERN_PROTECTION_FAILURE every once and a while. We wait till we get
+	 a bunch in a row before doing anything about it. If a "real" fault
+	 ever occurres it'll just keep faulting over and over and we'll hit
+	 the limit pretty quickly. */
+#     ifdef BROKEN_EXCEPTION_HANDLING
+        static char *last_fault;
+	static int last_fault_count;
+
+	if(addr != last_fault) {
+	  last_fault = addr;
+	  last_fault_count = 0;
+	}
+	if(++last_fault_count < 32) {
+	  if(last_fault_count == 1)
+	    GC_err_printf("GC: WARNING: Ignoring KERN_PROTECTION_FAILURE"
+			  "at %p\n", addr);
+	  return KERN_SUCCESS;
+	}
+
+	GC_err_printf("Unexpected KERN_PROTECTION_FAILURE at %p\n",addr);
+	/* Can't pass it along to the signal handler because that is
+	   ignoring SIGBUS signals. We also shouldn't call ABORT here as
+	   signals don't always work too well from the exception handler. */
+	GC_err_printf("Aborting\n");
+	exit(EXIT_FAILURE);
+#     else /* BROKEN_EXCEPTION_HANDLING */
+	/* Pass it along to the next exception handler
+	   (which should call SIGBUS/SIGSEGV) */
+	return FWD();
+#     endif /* !BROKEN_EXCEPTION_HANDLING */
     }
 
-    #ifdef BROKEN_EXCEPTION_HANDLING
-        /* Reset the number of consecutive SIGBUSs */
-        GC_sigbus_count = 0;
-    #endif
-    
+#   ifdef BROKEN_EXCEPTION_HANDLING
+      /* Reset the number of consecutive SIGBUSs */
+      GC_sigbus_count = 0;
+#   endif
+
     if(GC_mprotect_state == GC_MP_NORMAL) { /* common case */
-        h = (struct hblk*)((word)addr & ~(GC_page_size-1));
-        UNPROTECT(h, GC_page_size);	
-        for (i = 0; i < divHBLKSZ(GC_page_size); i++) {
-            register int index = PHT_HASH(h+i);
-            async_set_pht_entry_from_index(GC_dirty_pages, index);
-        }
+      h = (struct hblk*)((word)addr & ~(GC_page_size-1));
+      UNPROTECT(h, GC_page_size);
+      for (i = 0; i < divHBLKSZ(GC_page_size); i++) {
+	register int index = PHT_HASH(h+i);
+	async_set_pht_entry_from_index(GC_dirty_pages, index);
+      }
     } else if(GC_mprotect_state == GC_MP_DISCARDING) {
-        /* Lie to the thread for now. No sense UNPROTECT()ing the memory
-           when we're just going to PROTECT() it again later. The thread
-           will just fault again once it resumes */
+      /* Lie to the thread for now. No sense UNPROTECT()ing the memory
+	 when we're just going to PROTECT() it again later. The thread
+	 will just fault again once it resumes */
     } else {
-        /* Shouldn't happen, i don't think */
-        GC_printf("KERN_PROTECTION_FAILURE while world is stopped\n");
-        return FWD();
+      /* Shouldn't happen, i don't think */
+      GC_printf("KERN_PROTECTION_FAILURE while world is stopped\n");
+      return FWD();
     }
     return KERN_SUCCESS;
 }
 #undef FWD
 
 /* These should never be called, but just in case...  */
-kern_return_t catch_exception_raise_state(mach_port_name_t exception_port,
-    int exception, exception_data_t code, mach_msg_type_number_t codeCnt,
-    int flavor, thread_state_t old_state, int old_stateCnt,
-    thread_state_t new_state, int new_stateCnt)
+kern_return_t
+catch_exception_raise_state(mach_port_name_t exception_port, int exception,
+			    exception_data_t code,
+			    mach_msg_type_number_t codeCnt, int flavor,
+			    thread_state_t old_state, int old_stateCnt,
+			    thread_state_t new_state, int new_stateCnt)
 {
-    ABORT("catch_exception_raise_state");
-    return(KERN_INVALID_ARGUMENT);
+  ABORT("catch_exception_raise_state");
+  return(KERN_INVALID_ARGUMENT);
 }
 
-kern_return_t catch_exception_raise_state_identity(
-    mach_port_name_t exception_port, mach_port_t thread, mach_port_t task,
-    int exception, exception_data_t code, mach_msg_type_number_t codeCnt,
-    int flavor, thread_state_t old_state, int old_stateCnt, 
-    thread_state_t new_state, int new_stateCnt)
+kern_return_t
+catch_exception_raise_state_identity(mach_port_name_t exception_port,
+				     mach_port_t thread, mach_port_t task,
+				     int exception, exception_data_t code,
+				     mach_msg_type_number_t codeCnt, int flavor,
+				     thread_state_t old_state, int old_stateCnt,
+				     thread_state_t new_state, int new_stateCnt)
 {
-    ABORT("catch_exception_raise_state_identity");
-    return(KERN_INVALID_ARGUMENT);
+  ABORT("catch_exception_raise_state_identity");
+  return(KERN_INVALID_ARGUMENT);
 }
 
 


More information about the Gc mailing list