1576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma/* libunwind - a platform-independent unwind library
2576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma   Copyright (C) 2009 Google, Inc
3576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma	Contributed by Arun Sharma <arun.sharma@google.com>
4576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
5576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaPermission is hereby granted, free of charge, to any person obtaining
6576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmaa copy of this software and associated documentation files (the
7576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma"Software"), to deal in the Software without restriction, including
8576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmawithout limitation the rights to use, copy, modify, merge, publish,
9576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmadistribute, sublicense, and/or sell copies of the Software, and to
10576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmapermit persons to whom the Software is furnished to do so, subject to
11576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmathe following conditions:
12576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
13576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaThe above copyright notice and this permission notice shall be
14576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmaincluded in all copies or substantial portions of the Software.
15576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
16576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun SharmaWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
23576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
24576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <unistd.h>
25576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <stdio.h>
26576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <stdlib.h>
27576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <dlfcn.h>
28576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <libunwind.h>
29576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
30576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#define panic(args...)				\
31576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma	{ fprintf (stderr, args); exit (-1); }
32576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
33576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmaint verbose;
34576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmaint num_errors;
35576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmaint in_unwind;
36576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
37576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmavoid *
38576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmamalloc(size_t s)
39576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma{
40576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  static void * (*func)();
41576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
42576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  if(!func)
43576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    func = (void *(*)()) dlsym(RTLD_NEXT, "malloc");
44576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
45576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  if (in_unwind) {
46576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    num_errors++;
47576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    return NULL;
48576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  } else {
49576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    return func(s);
50576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  }
51576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma}
52576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
53576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic void
54576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmado_backtrace (void)
55576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma{
56576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  unw_word_t ip, sp;
57576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  unw_cursor_t cursor;
58576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  unw_context_t uc;
59576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  int ret;
60576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
61576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  in_unwind = 1;
62576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  unw_getcontext (&uc);
63576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  if (unw_init_local (&cursor, &uc) < 0)
64576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    panic ("unw_init_local failed!\n");
65576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
66576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  do
67576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    {
68576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma      unw_get_reg (&cursor, UNW_REG_IP, &ip);
69576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma      unw_get_reg (&cursor, UNW_REG_SP, &sp);
70576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
71576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma      ret = unw_step (&cursor);
72576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma      if (ret < 0)
73576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma	{
74576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma	  ++num_errors;
75576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma	}
76576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    }
77576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  while (ret > 0);
78576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  in_unwind = 0;
79576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma}
80576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
81576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmavoid
82e9f161a677087dfdf8e543b9e70c7131ac3fd942Tommi Rantalafoo3 (void)
83576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma{
84576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  do_backtrace ();
85576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma}
86576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
87576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmavoid
88e9f161a677087dfdf8e543b9e70c7131ac3fd942Tommi Rantalafoo2 (void)
89576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma{
90576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  foo3 ();
91576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma}
92576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
93576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmavoid
94e9f161a677087dfdf8e543b9e70c7131ac3fd942Tommi Rantalafoo1 (void)
95576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma{
96576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  foo2 ();
97576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma}
98576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
99576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmaint
10047a99b6f0007c69959d7d56e52243c1780102d80Tommi Rantalamain (void)
101576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma{
102576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  foo1();
103576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
104576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  if (num_errors > 0)
105576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    {
106576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma      fprintf (stderr, "FAILURE: detected %d errors\n", num_errors);
107576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma      exit (-1);
108576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    }
109576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma  return 0;
110576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma}
111