2
pstack.c -- asynchronous stack trace of a running process
3
Copyright (c) 1999 Ross Thompson
4
Author: Ross Thompson <ross@whatsis.com>
5
Critical bug fix: Tim Waugh
9
This file is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU General Public License for more details.
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
pstack currently works only on Linux, only on an x86 machine running
27
32 bit ELF binaries (64 bit not supported). Also, for symbolic
28
information, you need to use a GNU compiler to generate your
29
program, and you can't strip symbols from the binaries. For thread
30
information to be dumped, you have to use the debug-aware version
31
of libpthread.so. (To check, run 'nm' on your libpthread.so, and
32
make sure that the symbol "__pthread_threads_debug" is defined.)
34
The details of pulling stuff out of ELF files and running through
35
program images is very platform specific, and I don't want to
36
try to support modes or machine types I can't test in or on.
37
If someone wants to generalize this to other architectures, I would
38
be happy to help and coordinate the activity. Please send me whatever
39
changes you make to support these machines, so that I can own the
40
central font of all truth (at least as regards this program).
45
#include <sys/types.h>
48
#include <sys/ptrace.h>
49
#include <asm/ptrace.h>
63
#include <limits.h> /* PTHREAD_THREADS_MAX */
68
#include "libiberty.h"
70
#include "pstack.h" /* just one function */
71
#include "budbg.h" /* binutils stuff related to debugging symbols. */
72
#include "bucomm.h" /* some common stuff */
73
#include "debug.h" /* and more binutils stuff... */
75
#include "linuxthreads.h" /* LinuxThreads specific stuff... */
79
* fprintf for file descriptors :) NOTE: we have to use fixed-size buffer :)(
80
* due to malloc's unavalaibility.
86
char xbuf[2048];// FIXME: enough?
92
r = vsnprintf(xbuf, sizeof(xbuf), fmt, ap);
94
return write(fd, xbuf, r);
103
return write(fd, &c, sizeof(c));
107
fdputs( const char* s,
112
return write(fd, s, strlen(s));
116
* Use this function to open log file.
117
* Flags: truncate on opening.
119
static const char* path_format = "stack-trace-on-segv-%d.txt";
121
open_log_file( const pthread_t tid,
124
char fname[PATH_MAX];
126
snprintf(fname, sizeof(fname), path_format, tid, pid);
127
r = open(fname, O_WRONLY|O_CREAT|O_TRUNC,
134
* Add additional debugging information for functions.
148
typedef struct debug_block_st {
149
bfd_vma begin_addr; /* where did it start */
150
bfd_vma end_addr; /* where did it end */
151
struct debug_block_st* parent;
152
struct debug_block_st* childs;
157
* Function parameter.
160
bfd_vma offset; /* Offset in the stack */
161
const char* name; /* And name. */
165
* Extra information about functions.
168
asymbol* symbol; /* mangled function name, addr */
169
debug_lineno_t* lines;
173
const char* filename;/* a file name it occured in... */
174
debug_block_t* block; /* each function has a block, or not, you know */
175
debug_parameter_t* argv; /* argument types. */
180
/* This is the structure we use as a handle for these routines. */
183
/* File to print information to. */
185
/* Current indentation level. */
188
struct pr_stack *stack;
189
/* Parameter number we are about to output. */
191
debug_block_t* block; /* current block */
192
debug_function_t* function; /* current function */
193
debug_function_t* functions; /* all functions */
194
int functions_size; /* current size */
195
int functions_maxsize; /* maximum size */
198
/* The type stack. */
202
/* Next element on the stack. */
203
struct pr_stack *next;
206
/* Current visibility of fields if this is a class. */
207
enum debug_visibility visibility;
208
/* Name of the current method we are handling. */
212
static void indent PARAMS ((struct pr_handle *));
213
static boolean push_type PARAMS ((struct pr_handle *, const char *));
214
static boolean prepend_type PARAMS ((struct pr_handle *, const char *));
215
static boolean append_type PARAMS ((struct pr_handle *, const char *));
216
static boolean substitute_type PARAMS ((struct pr_handle *, const char *));
217
static boolean indent_type PARAMS ((struct pr_handle *));
218
static char *pop_type PARAMS ((struct pr_handle *));
219
static void print_vma PARAMS ((bfd_vma, char *, boolean, boolean));
220
static boolean pr_fix_visibility
221
PARAMS ((struct pr_handle *, enum debug_visibility));
223
static boolean pr_start_compilation_unit PARAMS ((PTR, const char *));
224
static boolean pr_start_source PARAMS ((PTR, const char *));
225
static boolean pr_empty_type PARAMS ((PTR));
226
static boolean pr_void_type PARAMS ((PTR));
227
static boolean pr_int_type PARAMS ((PTR, unsigned int, boolean));
228
static boolean pr_float_type PARAMS ((PTR, unsigned int));
229
static boolean pr_complex_type PARAMS ((PTR, unsigned int));
230
static boolean pr_bool_type PARAMS ((PTR, unsigned int));
231
static boolean pr_enum_type
232
PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
233
static boolean pr_pointer_type PARAMS ((PTR));
234
static boolean pr_function_type PARAMS ((PTR, int, boolean));
235
static boolean pr_reference_type PARAMS ((PTR));
236
static boolean pr_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
237
static boolean pr_array_type
238
PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
239
static boolean pr_set_type PARAMS ((PTR, boolean));
240
static boolean pr_offset_type PARAMS ((PTR));
241
static boolean pr_method_type PARAMS ((PTR, boolean, int, boolean));
242
static boolean pr_const_type PARAMS ((PTR));
243
static boolean pr_volatile_type PARAMS ((PTR));
244
static boolean pr_start_struct_type
245
PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int));
246
static boolean pr_struct_field
247
PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
248
static boolean pr_end_struct_type PARAMS ((PTR));
249
static boolean pr_start_class_type
250
PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean,
252
static boolean pr_class_static_member
253
PARAMS ((PTR, const char *, const char *, enum debug_visibility));
254
static boolean pr_class_baseclass
255
PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility));
256
static boolean pr_class_start_method PARAMS ((PTR, const char *));
257
static boolean pr_class_method_variant
258
PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean,
260
static boolean pr_class_static_method_variant
261
PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean));
262
static boolean pr_class_end_method PARAMS ((PTR));
263
static boolean pr_end_class_type PARAMS ((PTR));
264
static boolean pr_typedef_type PARAMS ((PTR, const char *));
265
static boolean pr_tag_type
266
PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
267
static boolean pr_typdef PARAMS ((PTR, const char *));
268
static boolean pr_tag PARAMS ((PTR, const char *));
269
static boolean pr_int_constant PARAMS ((PTR, const char *, bfd_vma));
270
static boolean pr_float_constant PARAMS ((PTR, const char *, double));
271
static boolean pr_typed_constant PARAMS ((PTR, const char *, bfd_vma));
272
static boolean pr_variable
273
PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
274
static boolean pr_start_function PARAMS ((PTR, const char *, boolean));
275
static boolean pr_function_parameter
276
PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
277
static boolean pr_start_block PARAMS ((PTR, bfd_vma));
278
static boolean pr_end_block PARAMS ((PTR, bfd_vma));
279
static boolean pr_end_function PARAMS ((PTR));
280
static boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma));
282
static const struct debug_write_fns pr_fns =
284
pr_start_compilation_unit,
303
pr_start_struct_type,
307
pr_class_static_member,
309
pr_class_start_method,
310
pr_class_method_variant,
311
pr_class_static_method_variant,
323
pr_function_parameter,
331
/* Indent to the current indentation level. */
335
struct pr_handle *info;
339
for (i = 0; i < info->indent; i++)
340
TRACE_PUTC ((' ', info->f));
343
/* Push a type on the type stack. */
346
push_type (info, type)
347
struct pr_handle *info;
355
n = (struct pr_stack *) xmalloc (sizeof *n);
356
memset (n, 0, sizeof *n);
358
n->type = xstrdup (type);
359
n->visibility = DEBUG_VISIBILITY_IGNORE;
361
n->next = info->stack;
367
/* Prepend a string onto the type on the top of the type stack. */
370
prepend_type (info, s)
371
struct pr_handle *info;
376
assert (info->stack != NULL);
378
n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1);
379
sprintf (n, "%s%s", s, info->stack->type);
380
free (info->stack->type);
381
info->stack->type = n;
386
/* Append a string to the type on the top of the type stack. */
389
append_type (info, s)
390
struct pr_handle *info;
398
assert (info->stack != NULL);
400
len = strlen (info->stack->type);
401
info->stack->type = (char *) xrealloc (info->stack->type,
402
len + strlen (s) + 1);
403
strcpy (info->stack->type + len, s);
408
/* We use an underscore to indicate where the name should go in a type
409
string. This function substitutes a string for the underscore. If
410
there is no underscore, the name follows the type. */
413
substitute_type (info, s)
414
struct pr_handle *info;
419
assert (info->stack != NULL);
421
u = strchr (info->stack->type, '|');
426
n = (char *) xmalloc (strlen (info->stack->type) + strlen (s));
428
memcpy (n, info->stack->type, u - info->stack->type);
429
strcpy (n + (u - info->stack->type), s);
432
free (info->stack->type);
433
info->stack->type = n;
438
if (strchr (s, '|') != NULL
439
&& (strchr (info->stack->type, '{') != NULL
440
|| strchr (info->stack->type, '(') != NULL))
442
if (! prepend_type (info, "(")
443
|| ! append_type (info, ")"))
450
return (append_type (info, " ")
451
&& append_type (info, s));
454
/* Indent the type at the top of the stack by appending spaces. */
458
struct pr_handle *info;
462
for (i = 0; i < info->indent; i++)
464
if (! append_type (info, " "))
471
/* Pop a type from the type stack. */
475
struct pr_handle *info;
480
assert (info->stack != NULL);
483
info->stack = o->next;
490
/* Print a VMA value into a string. */
493
print_vma (vma, buf, unsignedp, hexp)
499
if (sizeof (vma) <= sizeof (unsigned long))
502
sprintf (buf, "0x%lx", (unsigned long) vma);
504
sprintf (buf, "%lu", (unsigned long) vma);
506
sprintf (buf, "%ld", (long) vma);
512
sprintf_vma (buf + 2, vma);
516
/* Start a new compilation unit. */
519
pr_start_compilation_unit (p, filename)
521
const char *filename;
523
struct pr_handle *info = (struct pr_handle *) p;
525
assert (info->indent == 0);
527
TRACE_FPRINTF( (info->f, "%s:\n", filename));
532
/* Start a source file within a compilation unit. */
535
pr_start_source (p, filename)
537
const char *filename;
539
struct pr_handle *info = (struct pr_handle *) p;
541
assert (info->indent == 0);
543
TRACE_FPRINTF( (info->f, " %s:\n", filename));
548
/* Push an empty type onto the type stack. */
554
struct pr_handle *info = (struct pr_handle *) p;
556
return push_type (info, "<undefined>");
559
/* Push a void type onto the type stack. */
565
struct pr_handle *info = (struct pr_handle *) p;
567
return push_type (info, "void");
570
/* Push an integer type onto the type stack. */
573
pr_int_type (p, size, unsignedp)
578
struct pr_handle *info = (struct pr_handle *) p;
581
sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8);
582
return push_type (info, ab);
585
/* Push a floating type onto the type stack. */
588
pr_float_type (p, size)
592
struct pr_handle *info = (struct pr_handle *) p;
596
return push_type (info, "float");
598
return push_type (info, "double");
600
sprintf (ab, "float%d", size * 8);
601
return push_type (info, ab);
604
/* Push a complex type onto the type stack. */
607
pr_complex_type (p, size)
611
struct pr_handle *info = (struct pr_handle *) p;
613
if (! pr_float_type (p, size))
616
return prepend_type (info, "complex ");
619
/* Push a boolean type onto the type stack. */
622
pr_bool_type (p, size)
626
struct pr_handle *info = (struct pr_handle *) p;
629
sprintf (ab, "bool%d", size * 8);
631
return push_type (info, ab);
634
/* Push an enum type onto the type stack. */
637
pr_enum_type (p, tag, names, values)
641
bfd_signed_vma *values;
643
struct pr_handle *info = (struct pr_handle *) p;
647
if (! push_type (info, "enum "))
651
if (! append_type (info, tag)
652
|| ! append_type (info, " "))
655
if (! append_type (info, "{ "))
660
if (! append_type (info, "/* undefined */"))
666
for (i = 0; names[i] != NULL; i++)
670
if (! append_type (info, ", "))
674
if (! append_type (info, names[i]))
677
if (values[i] != val)
681
print_vma (values[i], ab, false, false);
682
if (! append_type (info, " = ")
683
|| ! append_type (info, ab))
692
return append_type (info, " }");
695
/* Turn the top type on the stack into a pointer. */
701
struct pr_handle *info = (struct pr_handle *) p;
704
assert (info->stack != NULL);
706
s = strchr (info->stack->type, '|');
707
if (s != NULL && s[1] == '[')
708
return substitute_type (info, "(*|)");
709
return substitute_type (info, "*|");
712
/* Turn the top type on the stack into a function returning that type. */
715
pr_function_type (p, argcount, varargs)
720
struct pr_handle *info = (struct pr_handle *) p;
725
assert (info->stack != NULL);
738
arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
739
for (i = argcount - 1; i >= 0; i--)
741
if (! substitute_type (info, ""))
743
arg_types[i] = pop_type (info);
744
if (arg_types[i] == NULL)
746
len += strlen (arg_types[i]) + 2;
752
/* Now the return type is on the top of the stack. */
754
s = (char *) xmalloc (len);
760
/* Turn off unknown arguments. */
761
strcat (s, "/* unknown */");
768
for (i = 0; i < argcount; i++)
772
strcat (s, arg_types[i]);
786
if (! substitute_type (info, s))
794
/* Turn the top type on the stack into a reference to that type. */
797
pr_reference_type (p)
800
struct pr_handle *info = (struct pr_handle *) p;
802
assert (info->stack != NULL);
804
return substitute_type (info, "&|");
807
/* Make a range type. */
810
pr_range_type (p, lower, upper)
812
bfd_signed_vma lower;
813
bfd_signed_vma upper;
815
struct pr_handle *info = (struct pr_handle *) p;
816
char abl[20], abu[20];
818
assert (info->stack != NULL);
820
if (! substitute_type (info, ""))
823
print_vma (lower, abl, false, false);
824
print_vma (upper, abu, false, false);
826
return (prepend_type (info, "range (")
827
&& append_type (info, "):")
828
&& append_type (info, abl)
829
&& append_type (info, ":")
830
&& append_type (info, abu));
833
/* Make an array type. */
837
pr_array_type (p, lower, upper, stringp)
839
bfd_signed_vma lower;
840
bfd_signed_vma upper;
843
struct pr_handle *info = (struct pr_handle *) p;
845
char abl[20], abu[20], ab[50];
847
range_type = pop_type (info);
848
if (range_type == NULL)
857
print_vma (upper + 1, abu, false, false);
858
sprintf (ab, "|[%s]", abu);
863
print_vma (lower, abl, false, false);
864
print_vma (upper, abu, false, false);
865
sprintf (ab, "|[%s:%s]", abl, abu);
868
if (! substitute_type (info, ab))
871
if (strcmp (range_type, "int") != 0)
873
if (! append_type (info, ":")
874
|| ! append_type (info, range_type))
880
if (! append_type (info, " /* string */"))
887
/* Make a set type. */
891
pr_set_type (p, bitstringp)
895
struct pr_handle *info = (struct pr_handle *) p;
897
if (! substitute_type (info, ""))
900
if (! prepend_type (info, "set { ")
901
|| ! append_type (info, " }"))
906
if (! append_type (info, "/* bitstring */"))
913
/* Make an offset type. */
919
struct pr_handle *info = (struct pr_handle *) p;
922
if (! substitute_type (info, ""))
929
return (substitute_type (info, "")
930
&& prepend_type (info, " ")
931
&& prepend_type (info, t)
932
&& append_type (info, "::|"));
935
/* Make a method type. */
938
pr_method_type (p, domain, argcount, varargs)
944
struct pr_handle *info = (struct pr_handle *) p;
956
if (! substitute_type (info, ""))
958
domain_type = pop_type (info);
959
if (domain_type == NULL)
961
if (strncmp (domain_type, "class ", sizeof "class " - 1) == 0
962
&& strchr (domain_type + sizeof "class " - 1, ' ') == NULL)
963
domain_type += sizeof "class " - 1;
964
else if (strncmp (domain_type, "union class ",
965
sizeof "union class ") == 0
966
&& (strchr (domain_type + sizeof "union class " - 1, ' ')
968
domain_type += sizeof "union class " - 1;
969
len += strlen (domain_type);
981
arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
982
for (i = argcount - 1; i >= 0; i--)
984
if (! substitute_type (info, ""))
986
arg_types[i] = pop_type (info);
987
if (arg_types[i] == NULL)
989
len += strlen (arg_types[i]) + 2;
995
/* Now the return type is on the top of the stack. */
997
s = (char *) xmalloc (len);
1001
strcpy (s, domain_type);
1002
strcat (s, "::| (");
1005
strcat (s, "/* unknown */");
1010
for (i = 0; i < argcount; i++)
1014
strcat (s, arg_types[i]);
1028
if (! substitute_type (info, s))
1036
/* Make a const qualified type. */
1042
struct pr_handle *info = (struct pr_handle *) p;
1044
return substitute_type (info, "const |");
1047
/* Make a volatile qualified type. */
1050
pr_volatile_type (p)
1053
struct pr_handle *info = (struct pr_handle *) p;
1055
return substitute_type (info, "volatile |");
1058
/* Start accumulating a struct type. */
1061
pr_start_struct_type (p, tag, id, structp, size)
1068
struct pr_handle *info = (struct pr_handle *) p;
1072
if (! push_type (info, structp ? "struct " : "union "))
1076
if (! append_type (info, tag))
1083
sprintf (idbuf, "%%anon%u", id);
1084
if (! append_type (info, idbuf))
1088
if (! append_type (info, " {"))
1090
if (size != 0 || tag != NULL)
1094
if (! append_type (info, " /*"))
1099
sprintf (ab, " size %u", size);
1100
if (! append_type (info, ab))
1105
sprintf (ab, " id %u", id);
1106
if (! append_type (info, ab))
1109
if (! append_type (info, " */"))
1112
if (! append_type (info, "\n"))
1115
info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
1117
return indent_type (info);
1120
/* Output the visibility of a field in a struct. */
1123
pr_fix_visibility (info, visibility)
1124
struct pr_handle *info;
1125
enum debug_visibility visibility;
1131
assert (info->stack != NULL);
1133
if (info->stack->visibility == visibility)
1136
assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE);
1140
case DEBUG_VISIBILITY_PUBLIC:
1143
case DEBUG_VISIBILITY_PRIVATE:
1146
case DEBUG_VISIBILITY_PROTECTED:
1149
case DEBUG_VISIBILITY_IGNORE:
1157
/* Trim off a trailing space in the struct string, to make the
1158
output look a bit better, then stick on the visibility string. */
1160
t = info->stack->type;
1162
assert (t[len - 1] == ' ');
1165
if (! append_type (info, s)
1166
|| ! append_type (info, ":\n")
1167
|| ! indent_type (info))
1170
info->stack->visibility = visibility;
1175
/* Add a field to a struct type. */
1178
pr_struct_field (p, name, bitpos, bitsize, visibility)
1183
enum debug_visibility visibility;
1185
struct pr_handle *info = (struct pr_handle *) p;
1189
if (! substitute_type (info, name))
1192
if (! append_type (info, "; /* "))
1197
print_vma (bitsize, ab, true, false);
1198
if (! append_type (info, "bitsize ")
1199
|| ! append_type (info, ab)
1200
|| ! append_type (info, ", "))
1204
print_vma (bitpos, ab, true, false);
1205
if (! append_type (info, "bitpos ")
1206
|| ! append_type (info, ab)
1207
|| ! append_type (info, " */\n")
1208
|| ! indent_type (info))
1211
t = pop_type (info);
1215
if (! pr_fix_visibility (info, visibility))
1218
return append_type (info, t);
1221
/* Finish a struct type. */
1224
pr_end_struct_type (p)
1227
struct pr_handle *info = (struct pr_handle *) p;
1230
assert (info->stack != NULL);
1231
assert (info->indent >= 2);
1235
/* Change the trailing indentation to have a close brace. */
1236
s = info->stack->type + strlen (info->stack->type) - 2;
1237
assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0');
1245
/* Start a class type. */
1248
pr_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
1257
struct pr_handle *info = (struct pr_handle *) p;
1262
if (vptr && ! ownvptr)
1264
tv = pop_type (info);
1269
if (! push_type (info, structp ? "class " : "union class "))
1273
if (! append_type (info, tag))
1280
sprintf (idbuf, "%%anon%u", id);
1281
if (! append_type (info, idbuf))
1285
if (! append_type (info, " {"))
1287
if (size != 0 || vptr || ownvptr || tag != NULL)
1289
if (! append_type (info, " /*"))
1296
sprintf (ab, "%u", size);
1297
if (! append_type (info, " size ")
1298
|| ! append_type (info, ab))
1304
if (! append_type (info, " vtable "))
1308
if (! append_type (info, "self "))
1313
if (! append_type (info, tv)
1314
|| ! append_type (info, " "))
1323
sprintf (ab, " id %u", id);
1324
if (! append_type (info, ab))
1328
if (! append_type (info, " */"))
1332
info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
1334
return (append_type (info, "\n")
1335
&& indent_type (info));
1338
/* Add a static member to a class. */
1341
pr_class_static_member (p, name, physname, visibility)
1344
const char *physname;
1345
enum debug_visibility visibility;
1347
struct pr_handle *info = (struct pr_handle *) p;
1350
if (! substitute_type (info, name))
1353
if (! prepend_type (info, "static ")
1354
|| ! append_type (info, "; /* ")
1355
|| ! append_type (info, physname)
1356
|| ! append_type (info, " */\n")
1357
|| ! indent_type (info))
1360
t = pop_type (info);
1364
if (! pr_fix_visibility (info, visibility))
1367
return append_type (info, t);
1370
/* Add a base class to a class. */
1373
pr_class_baseclass (p, bitpos, virtual, visibility)
1377
enum debug_visibility visibility;
1379
struct pr_handle *info = (struct pr_handle *) p;
1385
assert (info->stack != NULL && info->stack->next != NULL);
1387
if (! substitute_type (info, ""))
1390
t = pop_type (info);
1394
if (strncmp (t, "class ", sizeof "class " - 1) == 0)
1395
t += sizeof "class " - 1;
1397
/* Push it back on to take advantage of the prepend_type and
1398
append_type routines. */
1399
if (! push_type (info, t))
1404
if (! prepend_type (info, "virtual "))
1410
case DEBUG_VISIBILITY_PUBLIC:
1413
case DEBUG_VISIBILITY_PROTECTED:
1414
prefix = "protected ";
1416
case DEBUG_VISIBILITY_PRIVATE:
1417
prefix = "private ";
1420
prefix = "/* unknown visibility */ ";
1424
if (! prepend_type (info, prefix))
1429
print_vma (bitpos, ab, true, false);
1430
if (! append_type (info, " /* bitpos ")
1431
|| ! append_type (info, ab)
1432
|| ! append_type (info, " */"))
1436
/* Now the top of the stack is something like "public A / * bitpos
1437
10 * /". The next element on the stack is something like "class
1438
xx { / * size 8 * /\n...". We want to substitute the top of the
1439
stack in before the {. */
1440
s = strchr (info->stack->next->type, '{');
1444
/* If there is already a ':', then we already have a baseclass, and
1445
we must append this one after a comma. */
1446
for (l = info->stack->next->type; l != s; l++)
1449
if (! prepend_type (info, l == s ? " : " : ", "))
1452
t = pop_type (info);
1456
n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1);
1457
memcpy (n, info->stack->type, s - info->stack->type);
1458
strcpy (n + (s - info->stack->type), t);
1461
free (info->stack->type);
1462
info->stack->type = n;
1469
/* Start adding a method to a class. */
1472
pr_class_start_method (p, name)
1476
struct pr_handle *info = (struct pr_handle *) p;
1478
assert (info->stack != NULL);
1479
info->stack->method = name;
1483
/* Add a variant to a method. */
1486
pr_class_method_variant (p, physname, visibility, constp, volatilep, voffset,
1489
const char *physname;
1490
enum debug_visibility visibility;
1496
struct pr_handle *info = (struct pr_handle *) p;
1500
assert (info->stack != NULL);
1501
assert (info->stack->next != NULL);
1503
/* Put the const and volatile qualifiers on the type. */
1506
if (! append_type (info, " volatile"))
1511
if (! append_type (info, " const"))
1515
/* Stick the name of the method into its type. */
1516
if (! substitute_type (info,
1518
? info->stack->next->next->method
1519
: info->stack->next->method)))
1523
method_type = pop_type (info);
1524
if (method_type == NULL)
1527
/* Pull off the context type if there is one. */
1529
context_type = NULL;
1532
context_type = pop_type (info);
1533
if (context_type == NULL)
1537
/* Now the top of the stack is the class. */
1539
if (! pr_fix_visibility (info, visibility))
1542
if (! append_type (info, method_type)
1543
|| ! append_type (info, " /* ")
1544
|| ! append_type (info, physname)
1545
|| ! append_type (info, " "))
1547
if (context || voffset != 0)
1553
if (! append_type (info, "context ")
1554
|| ! append_type (info, context_type)
1555
|| ! append_type (info, " "))
1558
print_vma (voffset, ab, true, false);
1559
if (! append_type (info, "voffset ")
1560
|| ! append_type (info, ab))
1564
return (append_type (info, " */;\n")
1565
&& indent_type (info));
1568
/* Add a static variant to a method. */
1571
pr_class_static_method_variant (p, physname, visibility, constp, volatilep)
1573
const char *physname;
1574
enum debug_visibility visibility;
1578
struct pr_handle *info = (struct pr_handle *) p;
1581
assert (info->stack != NULL);
1582
assert (info->stack->next != NULL);
1583
assert (info->stack->next->method != NULL);
1585
/* Put the const and volatile qualifiers on the type. */
1588
if (! append_type (info, " volatile"))
1593
if (! append_type (info, " const"))
1597
/* Mark it as static. */
1598
if (! prepend_type (info, "static "))
1601
/* Stick the name of the method into its type. */
1602
if (! substitute_type (info, info->stack->next->method))
1606
method_type = pop_type (info);
1607
if (method_type == NULL)
1610
/* Now the top of the stack is the class. */
1612
if (! pr_fix_visibility (info, visibility))
1615
return (append_type (info, method_type)
1616
&& append_type (info, " /* ")
1617
&& append_type (info, physname)
1618
&& append_type (info, " */;\n")
1619
&& indent_type (info));
1622
/* Finish up a method. */
1625
pr_class_end_method (p)
1628
struct pr_handle *info = (struct pr_handle *) p;
1630
info->stack->method = NULL;
1634
/* Finish up a class. */
1637
pr_end_class_type (p)
1640
return pr_end_struct_type (p);
1643
/* Push a type on the stack using a typedef name. */
1646
pr_typedef_type (p, name)
1650
struct pr_handle *info = (struct pr_handle *) p;
1652
return push_type (info, name);
1655
/* Push a type on the stack using a tag name. */
1658
pr_tag_type (p, name, id, kind)
1662
enum debug_type_kind kind;
1664
struct pr_handle *info = (struct pr_handle *) p;
1665
const char *t, *tag;
1670
case DEBUG_KIND_STRUCT:
1673
case DEBUG_KIND_UNION:
1676
case DEBUG_KIND_ENUM:
1679
case DEBUG_KIND_CLASS:
1682
case DEBUG_KIND_UNION_CLASS:
1690
if (! push_type (info, t))
1696
sprintf (idbuf, "%%anon%u", id);
1700
if (! append_type (info, tag))
1702
if (name != NULL && kind != DEBUG_KIND_ENUM)
1704
sprintf (idbuf, " /* id %u */", id);
1705
if (! append_type (info, idbuf))
1712
/* Output a typedef. */
1719
struct pr_handle *info = (struct pr_handle *) p;
1722
if (! substitute_type (info, name))
1725
s = pop_type (info);
1730
TRACE_FPRINTF( (info->f, "typedef %s;\n", s));
1737
/* Output a tag. The tag should already be in the string on the
1738
stack, so all we have to do here is print it out. */
1746
struct pr_handle *info = (struct pr_handle *) p;
1749
t = pop_type (info);
1754
TRACE_FPRINTF( (info->f, "%s;\n", t));
1761
/* Output an integer constant. */
1764
pr_int_constant (p, name, val)
1770
struct pr_handle *info = (struct pr_handle *) p;
1773
print_vma (val, ab, false, false);
1774
TRACE_FPRINTF( (info->f, "const int %s = %s;\n", name, ab));
1779
/* Output a floating point constant. */
1782
pr_float_constant (p, name, val)
1788
struct pr_handle *info = (struct pr_handle *) p;
1790
TRACE_FPRINTF( (info->f, "const double %s = %g;\n", name, val));
1795
/* Output a typed constant. */
1798
pr_typed_constant (p, name, val)
1803
struct pr_handle *info = (struct pr_handle *) p;
1806
t = pop_type (info);
1812
print_vma (val, ab, false, false);
1813
TRACE_FPRINTF( (info->f, "const %s %s = %s;\n", t, name, ab));
1820
/* Output a variable. */
1823
pr_variable (p, name, kind, val)
1826
enum debug_var_kind kind;
1829
struct pr_handle *info = (struct pr_handle *) p;
1834
if (! substitute_type (info, name))
1837
t = pop_type (info);
1846
case DEBUG_LOCAL_STATIC:
1847
TRACE_FPRINTF( (info->f, "static "));
1849
case DEBUG_REGISTER:
1850
TRACE_FPRINTF( (info->f, "register "));
1855
print_vma (val, ab, true, true);
1856
TRACE_FPRINTF( (info->f, "%s /* %s */;\n", t, ab));
1859
if (kind==DEBUG_STATIC || kind==DEBUG_LOCAL_STATIC) {
1860
print_vma (val, ab, true, true);
1861
TRACE_FPRINTF( (info->f, "STATIC_VAR: %s /* %s */;\n", t, ab));
1871
/* Start outputting a function. */
1874
pr_start_function (p, name, global)
1879
struct pr_handle *info = (struct pr_handle *) p;
1882
if (! substitute_type (info, name))
1885
t = pop_type (info);
1892
TRACE_FPRINTF( (info->f, "static "));
1893
TRACE_FPRINTF( (info->f, "%s (", t));
1894
info->parameter = 1;
1896
if (info->functions_size==info->functions_maxsize) {
1897
info->functions_maxsize *= 2;
1898
info->functions = xrealloc(info->functions,
1899
info->functions_maxsize*sizeof(debug_function_t));
1900
assert(info->functions!=0);
1902
/* info->functions[info->functions_size] = xmalloc(sizeof(debug_function_t)); */
1903
info->function = &info->functions[info->functions_size];
1904
++info->functions_size;
1905
info->function->symbol = NULL;
1906
info->function->lines = NULL;
1907
info->function->lines_count = 0;
1908
info->function->max_lines_count = 0;
1909
info->function->name = t;
1910
info->function->filename = NULL;
1911
info->function->block = NULL;
1912
info->function->argv = NULL;
1913
info->function->argc = 0;
1914
info->function->max_argc = 0;
1919
/* Output a function parameter. */
1922
pr_function_parameter (p, name, kind, val)
1925
enum debug_parm_kind kind;
1928
struct pr_handle *info = (struct pr_handle *) p;
1929
debug_function_t* f = info->function;
1934
if (kind == DEBUG_PARM_REFERENCE
1935
|| kind == DEBUG_PARM_REF_REG)
1937
if (! pr_reference_type (p))
1941
if (! substitute_type (info, name))
1944
t = pop_type (info);
1949
if (info->parameter != 1)
1950
TRACE_FPRINTF( (info->f, ", "));
1952
if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
1953
TRACE_FPRINTF( (info->f, "register "));
1955
print_vma (val, ab, true, true);
1956
TRACE_FPRINTF( (info->f, "%s /* %s */", t, ab));
1961
if (f->argv==NULL) {
1962
f->max_argc = 7; /* rarely anyone has more than that many args... */
1963
f->argv = xmalloc(sizeof(debug_parameter_t)*f->max_argc);
1964
} else if (f->argc==f->max_argc) {
1966
f->argv = realloc(f->argv,sizeof(debug_parameter_t)*f->max_argc);
1968
f->argv[f->argc].offset = val;
1969
f->argv[f->argc].name = t;
1975
/* Start writing out a block. */
1978
pr_start_block (p, addr)
1982
struct pr_handle *info = (struct pr_handle *) p;
1984
debug_block_t* block = 0;
1987
if (info->parameter > 0)
1989
TRACE_FPRINTF( (info->f, ")\n"));
1990
info->parameter = 0;
1993
print_vma (addr, ab, true, true);
1994
TRACE_FPRINTF( (info->f, "{ /* %s */\n", ab));
1998
if (info->block->childs_count==0)
1999
info->block->childs = xmalloc(sizeof(debug_block_t));
2001
info->block->childs = xrealloc(info->block->childs,
2002
info->block->childs_count*sizeof(debug_block_t));
2003
block = &info->block->childs[info->block->childs_count];
2005
block = xmalloc(sizeof(debug_block_t));
2006
info->function->block = block;
2008
block->begin_addr = addr;
2009
block->end_addr = 0;
2010
block->parent = info->block;
2011
block->childs = NULL;
2012
block->childs_count = 0;
2013
info->block = block;
2018
/* Write out line number information. */
2021
pr_lineno (p, filename, lineno, addr)
2023
const char *filename;
2024
unsigned long lineno;
2027
struct pr_handle *info = (struct pr_handle *) p;
2029
debug_function_t* f = info->function;
2034
print_vma (addr, ab, true, true);
2035
TRACE_FPRINTF( (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab));
2037
if (f==NULL) /* FIXME: skips junk silently. */
2039
/* assert(f!=NULL); */
2040
if (f->filename==NULL) {
2041
f->filename = filename;
2042
assert(f->lines==0);
2043
f->max_lines_count = 4;
2044
f->lines = xmalloc(sizeof(debug_lineno_t)*f->max_lines_count);
2046
if (f->lines_count==f->max_lines_count) {
2047
f->max_lines_count *= 2;
2048
f->lines = xrealloc(f->lines, sizeof(debug_lineno_t)*f->max_lines_count);
2050
f->lines[f->lines_count].lineno = lineno;
2051
f->lines[f->lines_count].addr = addr;
2058
/* Finish writing out a block. */
2061
pr_end_block (p, addr)
2065
struct pr_handle *info = (struct pr_handle *) p;
2072
print_vma (addr, ab, true, true);
2073
TRACE_FPRINTF( (info->f, "} /* %s */\n", ab));
2075
assert(info->block!=0);
2076
info->block->end_addr = addr;
2077
info->block = info->block->parent;
2083
/* Finish writing out a function. */
2090
struct pr_handle *info = (struct pr_handle *) p;
2091
assert(info->block==0);
2092
info->function = NULL;
2096
/* third parameter to segv_action. */
2097
/* Got it after a bit of head scratching and stack dumping. */
2099
u_int32_t foo1; /* +0x00 */
2102
u_int32_t foo4; /* usually 2 */
2103
u_int32_t foo5; /* +0x10 */
2104
u_int32_t xgs; /* always zero */
2105
u_int32_t xfs; /* always zero */
2106
u_int32_t xes; /* always es=ds=ss */
2107
u_int32_t xds; /* +0x20 */
2111
u_int32_t esp; /* +0x30 */
2115
u_int32_t eax; /* +0x40 */
2116
u_int32_t foo11; /* usually 0xe */
2117
u_int32_t foo12; /* usually 0x6 */
2118
u_int32_t eip; /* instruction pointer */
2119
u_int32_t xcs; /* +0x50 */
2120
u_int32_t foo21; /* usually 0x2 */
2121
u_int32_t foo22; /* second stack pointer?! Probably. */
2123
u_int32_t foo31; /* +0x60 */ /* usually 0x0 */
2124
u_int32_t foo32; /* usually 0x2 */
2125
u_int32_t fault_addr; /* Address which caused a fault */
2126
u_int32_t foo41; /* usually 0x2 */
2129
signal_regs_t* ptrace_regs = 0; /* Tells my_ptrace to "ptrace" current process" */
2131
* my_ptrace: small wrapper around ptrace.
2132
* Act as normal ptrace if ptrace_regs==0.
2133
* Read data from current process if ptrace_regs!=0.
2136
my_ptrace( int request,
2142
return ptrace(request, pid, addr, data);
2143
/* we are tracing ourselves! */
2145
case PTRACE_ATTACH: return 0;
2146
case PTRACE_CONT: return 0;
2147
case PTRACE_DETACH: return 0;
2148
case PTRACE_PEEKUSER:
2150
case EIP: return ptrace_regs->eip;
2151
case EBP: return ptrace_regs->ebp;
2154
case PTRACE_PEEKTEXT: /* FALLTHROUGH */
2155
case PTRACE_PEEKDATA: return *(int*)(addr);
2158
errno = 1; /* what to do here? */
2159
return 1; /* failed?! */
2165
* To minimize the number of parameters.
2168
asymbol** syms; /* Sorted! */
2170
debug_function_t** functions;
2175
* Perform a search. A binary search for a symbol.
2178
decode_symbol( symbol_data_t* symbol_data,
2179
const unsigned long addr,
2183
asymbol** syms = symbol_data->syms;
2184
const int symcount = symbol_data->symcount;
2186
int top = symcount - 1;
2189
sprintf(buf, "????");
2192
while (top>bottom+1) {
2193
i = (top+bottom) / 2;
2194
if (bfd_asymbol_value(syms[i])==addr) {
2195
sprintf(buf, "%s", syms[i]->name);
2197
} else if (bfd_asymbol_value(syms[i]) > addr)
2203
if (addr<bfd_asymbol_value(syms[i]) || addr>(syms[i]->section->vma+syms[i]->section->_cooked_size))
2204
sprintf(buf, "????");
2206
sprintf(buf, "%s + 0x%lx", syms[i]->name, addr-bfd_asymbol_value(syms[i]));
2210
* 1. Perform a binary search for an debug_function_t.
2211
* 2. Fill buf/bufsize with name, parameters and lineno, if found
2212
* Or with '????' otherwise.
2214
static debug_function_t*
2215
find_debug_function_t( symbol_data_t* symbol_data,
2217
const unsigned long fp, /* frame pointer */
2218
const unsigned long addr,
2219
char* buf, /* string buffer */
2220
const int bufsize)/* FIXME: not used! */
2222
debug_function_t** syms = symbol_data->functions;
2223
debug_function_t* f = NULL;
2224
debug_block_t* block = NULL;
2225
debug_lineno_t* lineno = NULL;
2226
const int symcount = symbol_data->functions_size;
2228
int top = symcount - 1;
2233
sprintf(buf, "????");
2236
while (top>bottom+1) {
2237
i = (top+bottom) / 2;
2238
if (syms[i]->block->begin_addr==addr) {
2241
} else if (syms[i]->block->begin_addr > addr)
2244
if (syms[i]->block->end_addr >= addr) {
2254
block = syms[i]->block;
2255
if (block->begin_addr>=addr && block->end_addr<=addr)
2259
sprintf(buf, "????");
2262
* Do the backtrace the GDB way...
2265
/* assert(f->lines_count>0); */
2266
if (f->lines_count>0) {
2267
lineno = &f->lines[f->lines_count-1];
2268
for (i=1; i<f->lines_count; ++i)
2269
if (f->lines[i].addr>addr) {
2270
lineno = &f->lines[i-1];
2275
bufptr += sprintf(bufptr, "%s+0x%lx (", f->name, addr-block->begin_addr);
2276
for (i=0; i<f->argc; ++i) {
2277
bufptr += sprintf(bufptr, "%s = ", f->argv[i].name);
2278
/* FIXME: better parameter printing */
2280
arg = my_ptrace(PTRACE_PEEKDATA, pid, fp+f->argv[i].offset, 0);
2282
bufptr += sprintf(bufptr, "0x%x", arg);
2284
bufptr += sprintf(bufptr, ", ");
2287
bufptr += sprintf(bufptr, ") at %s:%d", f->filename, lineno->lineno);
2293
* Advance through the stacks and display frames as needed.
2297
symbol_data_t* symbol_data,
2300
unsigned long pc = 0;
2301
unsigned long fp = 0;
2302
unsigned long nextfp;
2303
unsigned long nargs;
2306
char buf[8096]; // FIXME: enough?
2307
debug_function_t* f = 0;
2311
pc = my_ptrace(PTRACE_PEEKUSER, pid, EIP * 4, 0);
2313
fp = my_ptrace(PTRACE_PEEKUSER, pid, EBP * 4, 0);
2317
f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf));
2318
fdprintf(fout,"0x%08lx: %s", pc, buf);
2319
for ( ; !errno && fp; ) {
2320
nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0);
2325
nargs = (nextfp - fp - 8) / 4;
2326
if (nargs > MAXARGS)
2330
for (i = 1; i <= nargs; i++) {
2331
arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0);
2334
fdprintf(fout,"%lx", arg);
2339
nargs = nextfp - fp - 8 - (4 * nargs);
2340
if (!errno && nargs > 0)
2341
fdprintf(fout," + %lx\n", nargs);
2349
if (errno || !nextfp)
2351
pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0);
2355
f = find_debug_function_t(symbol_data, pid, fp, pc, buf, sizeof(buf));
2356
fdprintf(fout,"0x%08lx: %s", pc, buf);
2359
decode_symbol(symbol_data, pc, buf, sizeof(buf));
2360
fdprintf(fout,"0x%08lx: %s", pc, buf);
2361
for ( ; !errno && fp; ) {
2362
nextfp = my_ptrace(PTRACE_PEEKDATA, pid, fp, 0);
2366
nargs = (nextfp - fp - 8) / 4;
2367
if (nargs > MAXARGS)
2371
for (i = 1; i <= nargs; i++) {
2372
arg = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4 * (i + 1), 0);
2375
fdprintf(fout,"%lx", arg);
2380
nargs = nextfp - fp - 8 - (4 * nargs);
2381
if (!errno && nargs > 0)
2382
fdprintf(fout," + %lx\n", nargs);
2388
if (errno || !nextfp)
2390
pc = my_ptrace(PTRACE_PEEKDATA, pid, fp + 4, 0);
2394
decode_symbol(symbol_data, pc, buf, sizeof(buf));
2395
fdprintf(fout,"0x%08lx: %s", pc, buf);
2404
/* layout from /usr/src/linux/arch/i386/kernel/process.c */
2406
show_regs( signal_regs_t* regs,
2409
/* long cr0 = 0L, cr2 = 0L, cr3 = 0L; */
2412
fdprintf(fd,"FAULT ADDR: %08x\n", regs->fault_addr);
2413
fdprintf(fd,"EIP: %04x:[<%08x>]",0xffff & regs->xcs,regs->eip);
2415
fdprintf(fd," ESP: %04x:%08x",0xffff & regs->xss,regs->esp);
2416
/*fdprintf(fd," EFLAGS: %08lx\n",regs->eflags); */
2418
fdprintf(fd,"EAX: %08x EBX: %08x ECX: %08x EDX: %08x\n",
2419
regs->eax,regs->ebx,regs->ecx,regs->edx);
2420
fdprintf(fd,"ESI: %08x EDI: %08x EBP: %08x",
2421
regs->esi, regs->edi, regs->ebp);
2422
fdprintf(fd," DS: %04x ES: %04x\n",
2423
0xffff & regs->xds,0xffff & regs->xes);
2425
__asm__("movl %%cr0, %0": "=r" (cr0));
2426
__asm__("movl %%cr2, %0": "=r" (cr2));
2427
__asm__("movl %%cr3, %0": "=r" (cr3));
2428
fprintf(stderr,"CR0: %08lx CR2: %08lx CR3: %08lx\n", cr0, cr2, cr3); */
2432
* Load a BFD for an executable based on PID. Return 0 on failure.
2435
load_bfd( const int pid)
2440
/* Get the contents from procfs. */
2442
sprintf(filename, "/proc/%d/exe", pid);
2444
sprintf(filename, "crashing");
2447
if ((abfd = bfd_openr (filename, 0))== NULL)
2448
bfd_nonfatal (filename);
2451
assert(bfd_check_format(abfd, bfd_archive)!=true);
2454
* There is no indication in BFD documentation that it should be done.
2457
if (!bfd_check_format_matches (abfd, bfd_object, &matching)) {
2458
bfd_nonfatal (bfd_get_filename (abfd));
2459
if (bfd_get_error () == bfd_error_file_ambiguously_recognized) {
2460
list_matching_formats (matching);
2469
* Those are for qsort. We need only function addresses, so all the others don't count.
2472
* Compare two BFD::asymbol-s.
2475
compare_symbols(const void* ap,
2478
const asymbol *a = *(const asymbol **)ap;
2479
const asymbol *b = *(const asymbol **)bp;
2480
if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
2482
else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
2488
* Compare two debug_asymbol_t-s.
2491
compare_debug_function_t(const void* ap,
2494
const debug_function_t *a = *(const debug_function_t **)ap;
2495
const debug_function_t *b = *(const debug_function_t **)bp;
2496
assert(a->block!=0);
2497
assert(b->block!=0);
2499
const bfd_vma addr1 = a->block->begin_addr;
2500
const bfd_vma addr2 = b->block->begin_addr;
2503
else if (addr2 > addr1)
2510
* Filter out (in place) symbols that are useless for stack tracing.
2511
* COUNT is the number of elements in SYMBOLS.
2512
* Return the number of useful symbols.
2516
remove_useless_symbols( asymbol** symbols,
2519
asymbol** in_ptr = symbols;
2520
asymbol** out_ptr = symbols;
2522
while (--count >= 0) {
2523
asymbol *sym = *in_ptr++;
2525
if (sym->name == NULL || sym->name[0] == '\0' || sym->value==0)
2527
if (sym->flags & (BSF_DEBUGGING))
2529
if (bfd_is_und_section (sym->section) || bfd_is_com_section (sym->section))
2533
return out_ptr - symbols;
2537
* Debugging information.
2539
static bfd* abfd = 0;
2540
static PTR dhandle = 0;
2541
static asymbol** syms = 0;
2542
static long symcount = 0;
2543
static asymbol** sorted_syms = 0;
2544
static long sorted_symcount = 0;
2545
static debug_function_t** functions = 0;
2546
static int functions_size = 0;
2547
static int sigreport = SIGUSR1;
2548
static pthread_t segv_tid; /* What thread did SEGV? */
2549
static pid_t segv_pid;
2552
* We'll get here after a SIGSEGV. But you can install it on other signals, too :)
2553
* Because we are in the middle of the SIGSEGV, we are on our own. We can't do
2554
* any malloc(), any fopen(), nothing. The last is actually a sin. We event can't
2555
* fprintf(stderr,...)!!!
2558
segv_action(int signo, siginfo_t* siginfo, void* ptr)
2560
symbol_data_t symbol_data;
2563
segv_pid = getpid();
2564
segv_tid = pthread_self();
2565
fd = open_log_file(segv_tid, segv_pid);
2566
/* signal(SIGSEGV, SIG_DFL); */
2567
ptrace_regs = (signal_regs_t*)ptr;
2568
assert(ptrace_regs!=0);
2570
/* Show user how guilty we are. */
2571
fdprintf(fd,"--------- SEGV in PROCESS %d, THREAD %d ---------------\n", segv_pid, pthread_self());
2572
show_regs(ptrace_regs, fd);
2574
/* Some form of stack trace, too. */
2575
fdprintf(fd, "STACK TRACE:\n");
2577
symbol_data.syms = sorted_syms;
2578
symbol_data.symcount = sorted_symcount;
2579
symbol_data.functions = functions;
2580
symbol_data.functions_size = functions_size;
2581
my_crawl(segv_pid, &symbol_data, fd);
2584
linuxthreads_notify_others(sigreport);
2589
report_action(int signo, siginfo_t* siginfo, void* ptr)
2591
const int pid = getpid();
2592
pthread_t tid = pthread_self();
2593
symbol_data_t symbol_data;
2595
if (pthread_equal(tid, segv_tid)) {
2596
/* We have already printed our stack trace... */
2600
fd = open_log_file(tid, pid);
2601
fdprintf(fd, "REPORT: CURRENT PROCESS:%d, THREAD:%d\n", getpid(), pthread_self());
2602
/* signal(SIGSEGV, SIG_DFL); */
2603
ptrace_regs = (signal_regs_t*)ptr;
2604
assert(ptrace_regs!=0);
2606
/* Show user how guilty we are. */
2607
fdprintf(fd,"--------- STACK TRACE FOR PROCESS %d, THREAD %d ---------------\n", pid, pthread_self());
2608
show_regs(ptrace_regs, fd);
2610
/* Some form of stack trace, too. */
2611
fdprintf(fd, "STACK TRACE:\n");
2613
symbol_data.syms = sorted_syms;
2614
symbol_data.symcount = sorted_symcount;
2615
symbol_data.functions = functions;
2616
symbol_data.functions_size = functions_size;
2617
my_crawl(pid, &symbol_data, fd);
2620
/* Tell segv_thread to proceed after pause(). */
2621
/*pthread_kill(segv_tid, sigreport);
2622
kill(segv_pid, sigreport);
2623
pthread_cancel(tid); */
2627
* Main library routine. Just call it on your program.
2630
pstack_install_segv_action( const char* path_format_)
2632
const int pid = getpid();
2633
struct sigaction act;
2635
/* Store what we have to for later usage. */
2636
path_format = path_format_;
2638
/* We need a signal action for SIGSEGV and sigreport ! */
2639
sigreport = SIGUSR1;
2641
sigemptyset(&act.sa_mask);
2642
act.sa_flags = SA_SIGINFO|SA_ONESHOT; /* Just one SIGSEGV. */
2643
act.sa_sigaction = segv_action;
2644
act.sa_restorer = NULL;
2645
if (sigaction(SIGSEGV, &act, NULL)!=0) {
2646
perror("sigaction");
2649
act.sa_sigaction = report_action;
2650
act.sa_flags = SA_SIGINFO; /* But many sigreports. */
2651
if (sigaction(sigreport, &act, NULL)!=0) {
2652
perror("sigaction");
2656
/* And a little setup for libiberty. */
2657
program_name = "crashing";
2658
xmalloc_set_program_name (program_name);
2660
/* Umm, and initialize BFD, too */
2663
list_supported_targets(0, stdout);
2664
set_default_bfd_target();
2667
if ((abfd = load_bfd(pid))==0)
2668
fprintf(stderr, "BFD load failed..\n");
2670
long storage_needed= (bfd_get_file_flags(abfd) & HAS_SYMS) ?
2671
bfd_get_symtab_upper_bound (abfd) : 0;
2675
if (storage_needed < 0)
2676
fprintf(stderr, "Symbol table size estimation failure.\n");
2677
else if (storage_needed > 0) {
2678
syms = (asymbol **) xmalloc (storage_needed);
2679
symcount = bfd_canonicalize_symtab (abfd, syms);
2681
TRACE_FPRINTF((stderr, "TOTAL: %ld SYMBOLS.\n", symcount));
2682
/* We need debugging info, too! */
2683
if (symcount==0 || (dhandle = read_debugging_info (abfd, syms, symcount))==0)
2684
fprintf(stderr, "NO DEBUGGING INFORMATION FOUND.\n");
2686
/* We make a copy of syms to sort. We don't want to sort syms
2687
because that will screw up the relocs. */
2688
sorted_syms = (asymbol **) xmalloc (symcount * sizeof (asymbol *));
2689
memcpy (sorted_syms, syms, symcount * sizeof (asymbol *));
2692
for (i=0; i<symcount; ++i)
2693
if (syms[i]->name!=0 && strlen(syms[i]->name)>0 && syms[i]->value!=0)
2694
printf("%08lx T %s\n", syms[i]->section->vma + syms[i]->value, syms[i]->name);
2696
sorted_symcount = remove_useless_symbols (sorted_syms, symcount);
2697
TRACE_FPRINTF((stderr, "SORTED: %ld SYMBOLS.\n", sorted_symcount));
2699
/* Sort the symbols into section and symbol order */
2700
qsort (sorted_syms, sorted_symcount, sizeof (asymbol *), compare_symbols);
2702
for (i=0; i<sorted_symcount; ++i)
2703
if (sorted_syms[i]->name!=0 && strlen(sorted_syms[i]->name)>0 && sorted_syms[i]->value!=0)
2704
printf("%08lx T %s\n", sorted_syms[i]->section->vma + sorted_syms[i]->value, sorted_syms[i]->name);
2706
/* We have symbols, we need debugging info somehow sorted out. */
2708
fprintf(stderr, "STACK TRACE WILL BE UNCOMFORTABLE.\n");
2710
/* Start collecting the debugging information.... */
2711
struct pr_handle info;
2718
info.function = NULL;
2719
info.functions_size = 0;
2720
info.functions_maxsize = 1000;
2721
info.functions = (debug_function_t*)xmalloc(sizeof(debug_function_t)*info.functions_maxsize);
2722
debug_write (dhandle, &pr_fns, (PTR) &info);
2723
TRACE_FPRINTF((stdout, "\n%d DEBUG SYMBOLS\n", info.functions_size));
2724
assert(info.functions_size!=0);
2725
functions = xmalloc(sizeof(debug_function_t*)*info.functions_size);
2726
functions_size = info.functions_size;
2727
for (i=0; i<functions_size; ++i)
2728
functions[i] = &info.functions[i];
2729
/* Sort the symbols into section and symbol order */
2730
qsort (functions, functions_size, sizeof(debug_function_t*),
2731
compare_debug_function_t);
2733
for (i=0; i<info.functions_size; ++i)
2734
fprintf(stdout, "%08lx T %s\n", info.functions[i].block->begin_addr, info.functions[i].name);
2738
} else /* storage_needed == 0 */
2739
fprintf(stderr, "NO SYMBOLS FOUND.\n");
2744
/*********************************************************************/
2745
/*********************************************************************/
2746
/*********************************************************************/