Gtest-exc.c revision f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4
1830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant/* libunwind - a platform-independent unwind library 2830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant Copyright (C) 2001-2003 Hewlett-Packard Co 3830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 4830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 5830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantPermission is hereby granted, free of charge, to any person obtaining 6830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnanta copy of this software and associated documentation files (the 7830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant"Software"), to deal in the Software without restriction, including 8830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantwithout limitation the rights to use, copy, modify, merge, publish, 9830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantdistribute, sublicense, and/or sell copies of the Software, and to 10830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantpermit persons to whom the Software is furnished to do so, subject to 11830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantthe following conditions: 12830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 13830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantThe above copyright notice and this permission notice shall be 14830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantincluded in all copies or substantial portions of the Software. 15830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 16830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22830713c63ecaf0a5d7690db92f83f2741754de15Howard HinnantWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 24830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant/* This illustrates the basics of using the unwind interface for 25830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant exception handling. */ 26830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 27830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#include <stdio.h> 28830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#include <stdlib.h> 29830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#include <unistd.h> 30830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 31830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#include <libunwind.h> 32830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 33830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#define panic(args...) \ 34830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { ++nerrors; fprintf (stderr, args); } 35830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 36830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantint nerrors = 0; 37830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantint verbose = 0; 38830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 39830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantstatic void b (void *); 40830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 41830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantstatic void 42830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantraise_exception (void *addr) 43830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{ 44830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant unw_cursor_t cursor; 45830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant unw_word_t ip; 46830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant unw_context_t uc; 47830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 48830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant unw_getcontext (&uc); 49830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant if (unw_init_local (&cursor, &uc) < 0) 50830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 51830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant panic ("unw_init_local() failed!\n"); 52830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant return; 53830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 54830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 55830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant /* unwind to frame b(): */ 56830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant if (unw_step (&cursor) < 0) 57830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 58830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant panic ("unw_step() failed!\n"); 59 return; 60 } 61 62 /* unwind to frame a(): */ 63 if (unw_step (&cursor) < 0) 64 { 65 panic ("unw_step() failed!\n"); 66 return; 67 } 68 69 unw_get_reg (&cursor, UNW_REG_IP, &ip); 70 if (verbose) 71 printf ("old ip = %lx, new ip = %p\n", (long) ip, addr); 72 73 if (unw_set_reg (&cursor, UNW_REG_IP, (unw_word_t) addr) < 0) 74 { 75 panic ("unw_set_reg() failed!\n"); 76 return; 77 } 78 79 unw_resume (&cursor); /* transfer control to exception handler */ 80} 81 82#if !UNW_TARGET_IA64 83 84void * 85__builtin_ia64_bsp (void) 86{ 87 return NULL; 88} 89 90#endif 91 92static int 93a (void) 94{ 95 long stack; 96 97 if (verbose) 98 printf ("a: sp=%p bsp=%p\n", &stack, __builtin_ia64_bsp ()); 99 b (&&handler); 100 panic ("FAILURE: unexpected return from func()!\n"); 101 102#if UNW_TARGET_IA64 103 asm volatile ("1:"); /* force a new bundle */ 104#endif 105 handler: 106 if (verbose) 107 { 108 printf ("exception handler: here we go (sp=%p, bsp=%p)...\n", 109 &stack, __builtin_ia64_bsp ()); 110 /* This call works around a bug in gcc (up-to pre3.4) which 111 causes invalid assembly code to be generated when 112 __builtin_ia64_bsp() gets predicated. */ 113 getpid (); 114 } 115 return 0; 116} 117 118static void 119b (void *addr) 120{ 121 if (verbose) 122 printf ("b() calling raise_exception()\n"); 123 raise_exception (addr); 124 panic ("FAILURE: b() returned from raise_exception()!!\n"); 125} 126 127int 128main (int argc, char **argv) 129{ 130 if (argc > 1) 131 ++verbose; 132 133 if (a () != 0 || nerrors > 0) 134 { 135 fprintf (stderr, "FAILURE: test failed; try again?\n"); 136 exit (-1); 137 } 138 139 if (verbose) 140 printf ("SUCCESS!\n"); 141 return 0; 142} 143