trouble with __builtin_frame_address and __builtin_return_address

thunder7@xs4all.nl thunder7@xs4all.nl
Sat Sep 4 23:28:00 GMT 1999


I'm having a hard time setting up a signal-handler in my source.

It works fine in Linux, works in DJGPP, but hangs windows with Cygwin.
(add your standard derogatory comments about windows here).
Unfortunately, 80% of people who play my game play in windows.

the handler looks like this:

===================================================================
static bool continue_stack_trace = TRUE;

#define MAX_STACK_ADDR 40

#define handle_stack_address(X) \
   if (continue_stack_trace && (__builtin_frame_address((X)) != 0L) && ((X) < MAX_STACK_ADDR)) \
   { \
      stack_addr[(X)]= (unsigned long)__builtin_return_address((X)); \
      dlog(DEBUGEXTRA,"files.c: handle_signal_abort: stack %d %08lx frame %d %08lx\n", \
                      (X), __builtin_return_address((X)), (X), __builtin_frame_address((X))); \
   } \
   else if (continue_stack_trace) \
   { \
      continue_stack_trace = FALSE; \
   }

#endif
/*
 * Handle signal -- abort, kill, etc
 */
static void handle_signal_abort(int sig)
{
   bool                 save_ok = FALSE;

#ifdef USE_DEBUG_MAP
   FILE                *fff = NULL;
   char                 filename[1024];
   s16b                 i;
   bool                 dump_ok = FALSE;
   static unsigned long stack_addr[MAX_STACK_ADDR];

   dlog(DEBUGEXTRA,"files.c: handle_signal_abort: active!\n");

   /* clean the stack addresses if necessary */
   for (i=0; i < MAX_STACK_ADDR; i++)
   {
      stack_addr[i] = (unsigned long)0;
   }
   /* Disable handler, if we crash in here, crash hard! */
   (void)signal(sig, SIG_IGN);

   /* __builtin_return_address needs a constant, so this cannot be in a loop */

   handle_stack_address(0);
   handle_stack_address(1);
   handle_stack_address(2);
   handle_stack_address(3);
   handle_stack_address(4);
   handle_stack_address(5);
   handle_stack_address(6);

===================================================================
the program then uses the information in stack_addr[] to look up the
addresses in the output from nm, and prints nice function-names to a
dumpfile.

The signals are set up like this:

===================================================================
void signals_init()
{
#ifdef SIGFPE
    (void)signal(SIGFPE, handle_signal_abort);
#endif
===================================================================
idem for SIGSEGV & SIGBUS

If I induce a crash, with this:

===================================================================
static void wiz_create_crash(void)
{
   bool useless;

   if (get_check("You really want to crash, don't you?"))
   {
      /* this doesn't seem to crash DOS */
      strcpy(NULL, "crashing now!");
      
      /* but this should :-)            */
      item_tester_hook = NULL;
      useless = (*item_tester_hook)(NULL);
   }
}
===================================================================
it just hangs. Windows complains it's not responding. I'm thinking this
has means __builtin_frame_address doesn't become 0 when there's no more 
return addresses to get off the stack with __builtin_return_address.
Is there any other way to do this? Should this work? Should I use a
snapshot of the dll?

Thanks for pointers!

Jurriaan
-- 
An ill wind comes arising
Across the cities of the plain
There's no swimming in the heavy water
No singing in the acid rain
   Rush - Distant Early Warning

--
Want to unsubscribe from this list?
Send a message to cygwin-unsubscribe@sourceware.cygnus.com



More information about the Cygwin mailing list