1f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm/* libunwind - a platform-independent unwind library 230dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm Copyright (C) 2001-2004 Hewlett-Packard Co 3f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 4f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 5f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmPermission is hereby granted, free of charge, to any person obtaining 6f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidma copy of this software and associated documentation files (the 7f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm"Software"), to deal in the Software without restriction, including 8f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmwithout limitation the rights to use, copy, modify, merge, publish, 9f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmdistribute, sublicense, and/or sell copies of the Software, and to 10f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmpermit persons to whom the Software is furnished to do so, subject to 11f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmthe following conditions: 12f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 13f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmThe above copyright notice and this permission notice shall be 14f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmincluded in all copies or substantial portions of the Software. 15f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 16f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 24f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm/* This illustrates the basics of using the unwind interface for 25f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm exception handling. */ 26f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 2730dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm#ifdef HAVE_CONFIG_H 2830dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm# include "config.h" 2930dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm#endif 3030dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm 31f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm#include <stdio.h> 32f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm#include <stdlib.h> 33f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm#include <unistd.h> 34f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 35f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm#include <libunwind.h> 36f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 3730dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm#ifdef HAVE_IA64INTRIN_H 3830dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm# include <ia64intrin.h> 3930dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm#endif 4030dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm 41f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm#define panic(args...) \ 42f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm { ++nerrors; fprintf (stderr, args); } 43f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 44f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmint nerrors = 0; 45f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmint verbose = 0; 469fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidmint depth = 13; 4730dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidmvolatile int got_here = 0; 48f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 499fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidmextern void b (int); 50f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 519fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidmvoid 529fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidmraise_exception (void) 53f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm{ 54f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm unw_cursor_t cursor; 55f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm unw_context_t uc; 569fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm int i; 57f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 58f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm unw_getcontext (&uc); 59f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm if (unw_init_local (&cursor, &uc) < 0) 60f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm { 61f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm panic ("unw_init_local() failed!\n"); 62f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm return; 63f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm } 64f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 6530dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm /* unwind to top-most frame a(), skipping over b() and raise_exception(): */ 6630dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm for (i = 0; i < depth + 2; ++i) 679fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm if (unw_step (&cursor) < 0) 689fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm { 699fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm panic ("unw_step() failed!\n"); 709fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm return; 719fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm } 72f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm unw_resume (&cursor); /* transfer control to exception handler */ 73f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm} 74f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 7530dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidmuintptr_t 7630dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidmget_bsp (void) 77f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm{ 7830dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm#if UNW_TARGET_IA64 7930dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm# ifdef __INTEL_COMPILER 8030dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm return __getReg (_IA64_REG_AR_BSP); 8130dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm# else 8230dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm return (uintptr_t) __builtin_ia64_bsp (); 8330dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm# endif 8430dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm#else 8530dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm return 0; 86f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm#endif 8730dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm} 88f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 899fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidmint 909fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidma (int n) 91f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm{ 92f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm long stack; 9330dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm int result = 99; 94f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 959fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm if (verbose) 9630dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm printf ("a(n=%d): sp=%p bsp=0x%lx\n", 9730dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm n, &stack, (unsigned long) get_bsp ()); 989fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm 999fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm if (n > 0) 1005fedf3407c7c161d12ba4f600cbce12fef780ad7Tommi Rantala a (n - 1); 10130dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm else 10230dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm b (16); 1039fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm 104f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm if (verbose) 105f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm { 10630dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm printf ("exception handler: here we go (sp=%p, bsp=0x%lx)...\n", 10730dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm &stack, (unsigned long) get_bsp ()); 108f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm /* This call works around a bug in gcc (up-to pre3.4) which 109f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm causes invalid assembly code to be generated when 110f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm __builtin_ia64_bsp() gets predicated. */ 111f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm getpid (); 112f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm } 11330dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm if (n == depth) 11430dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm { 11530dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm result = 0; 11630dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm got_here = 1; 11730dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm } 11830dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm return result; 119f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm} 120f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 1219fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidmvoid 1229fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidmb (int n) 123f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm{ 1249fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm if ((n & 1) == 0) 1259fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm { 1269fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm if (verbose) 1279fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm printf ("b(n=%d) calling raise_exception()\n", n); 1289fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm raise_exception (); 1299fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm } 130f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm panic ("FAILURE: b() returned from raise_exception()!!\n"); 131f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm} 132f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 133f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmint 134f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidmmain (int argc, char **argv) 135f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm{ 13630dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm int result; 13730dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm 138f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm if (argc > 1) 1399fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm { 1409fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm ++verbose; 1419fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm depth = atol (argv[1]); 14230dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm if (depth < 1) 14330dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm { 14430dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm fprintf (stderr, "Usage: %s depth\n" 14530dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm " depth must be >= 1\n", argv[0]); 14630dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm exit (-1); 14730dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm } 1489fb355e096eef9a2f005e896727d25a5d4ed0141hp.com!davidm } 149f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 15030dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm result = a (depth); 15130dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm if (result != 0 || !got_here || nerrors > 0) 152f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm { 15330dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm fprintf (stderr, 15430dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm "FAILURE: test failed: result=%d got_here=%d nerrors=%d\n", 15530dec34c3a0bf851cdf41153528659ad347c0ccbhp.com!davidm result, got_here, nerrors); 156f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm exit (-1); 157f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm } 158f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm 159f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm if (verbose) 160f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm printf ("SUCCESS!\n"); 161f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm return 0; 162f77ee147ace13e3d500dc3d4468cb1b0dec2b0a4hp.com!davidm} 163