Gtest-exc.c revision 9fb355e096eef9a2f005e896727d25a5d4ed0141
1/* libunwind - a platform-independent unwind library 2 Copyright (C) 2001-2003 Hewlett-Packard Co 3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 4 5Permission is hereby granted, free of charge, to any person obtaining 6a copy of this software and associated documentation files (the 7"Software"), to deal in the Software without restriction, including 8without limitation the rights to use, copy, modify, merge, publish, 9distribute, sublicense, and/or sell copies of the Software, and to 10permit persons to whom the Software is furnished to do so, subject to 11the following conditions: 12 13The above copyright notice and this permission notice shall be 14included in all copies or substantial portions of the Software. 15 16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 24/* This illustrates the basics of using the unwind interface for 25 exception handling. */ 26 27#include <stdio.h> 28#include <stdlib.h> 29#include <unistd.h> 30 31#include <libunwind.h> 32 33#define panic(args...) \ 34 { ++nerrors; fprintf (stderr, args); } 35 36int nerrors = 0; 37int verbose = 0; 38int depth = 13; 39 40extern void b (int); 41 42void 43raise_exception (void) 44{ 45 unw_cursor_t cursor; 46 unw_context_t uc; 47 int i; 48 49 unw_getcontext (&uc); 50 if (unw_init_local (&cursor, &uc) < 0) 51 { 52 panic ("unw_init_local() failed!\n"); 53 return; 54 } 55 56 /* unwind to frame b(): */ 57 if (unw_step (&cursor) < 0) 58 { 59 panic ("unw_step() failed!\n"); 60 return; 61 } 62 63 /* unwind to top-most frame a(): */ 64 for (i = 0; i < depth - 1; ++i) 65 if (unw_step (&cursor) < 0) 66 { 67 panic ("unw_step() failed!\n"); 68 return; 69 } 70 unw_resume (&cursor); /* transfer control to exception handler */ 71} 72 73#if !UNW_TARGET_IA64 || defined(__INTEL_COMPILER) 74 75void * 76__builtin_ia64_bsp (void) 77{ 78 return NULL; 79} 80 81#endif 82 83int 84a (int n) 85{ 86 long stack; 87 88 if (verbose) 89 printf ("a(n=%d)\n", n); 90 91 if (n > 0) 92 return a (n - 1); 93 94 if (verbose) 95 printf ("a: sp=%p bsp=%p\n", &stack, __builtin_ia64_bsp ()); 96 97 b (16); 98 99 if (verbose) 100 { 101 printf ("exception handler: here we go (sp=%p, bsp=%p)...\n", 102 &stack, __builtin_ia64_bsp ()); 103 /* This call works around a bug in gcc (up-to pre3.4) which 104 causes invalid assembly code to be generated when 105 __builtin_ia64_bsp() gets predicated. */ 106 getpid (); 107 } 108 return 0; 109} 110 111void 112b (int n) 113{ 114 if ((n & 1) == 0) 115 { 116 if (verbose) 117 printf ("b(n=%d) calling raise_exception()\n", n); 118 raise_exception (); 119 } 120 panic ("FAILURE: b() returned from raise_exception()!!\n"); 121} 122 123int 124main (int argc, char **argv) 125{ 126 if (argc > 1) 127 { 128 ++verbose; 129 depth = atol (argv[1]); 130 } 131 132 if (a (depth) != 0 || nerrors > 0) 133 { 134 fprintf (stderr, "FAILURE: test failed; try again?\n"); 135 exit (-1); 136 } 137 138 if (verbose) 139 printf ("SUCCESS!\n"); 140 return 0; 141} 142