27 #if defined(x86_SOLARIS) 35 #include <sys/stack.h> 36 #include <sys/frame.h> 41 #define FRAME_PTR_REGISTER EBP 43 #define PGRAB_RDONLY 0x04 44 #define MIN(a,b) ((a) < (b) ? (a) : (b)) 46 typedef Elf64_Sym GElf_Sym;
48 extern struct ps_prochandle *Pgrab (pid_t,
int,
int *);
49 extern void Pfree (
struct ps_prochandle *);
50 extern int Plookup_by_addr (
struct ps_prochandle *, uintptr_t,
char *,
size_t, GElf_Sym *);
53 static ulong_t argcount (uintptr_t eip);
54 static int read_safe (
int fd,
struct frame *fp,
struct frame **savefp, uintptr_t * savepc);
63 argcount (uintptr_t eip)
65 const uint8_t *ins = (
const uint8_t *) eip;
78 n = ins[2] + (ins[3] << 8) + (ins[4] << 16) + (ins[5] << 24);
90 return (MIN (n, TR_ARG_MAX));
102 read_safe (
int fd,
struct frame *fp,
struct frame **savefp, uintptr_t * savepc)
106 if ((uintptr_t) fp & (
sizeof (
void *) - 1))
111 if ((pread (fd, (
void *) &newfp,
sizeof (fp->fr_savfp), (off_t) & fp->fr_savfp) != sizeof (fp->fr_savfp))
112 || pread (fd, (
void *) savepc,
sizeof (fp->fr_savpc), (off_t) & fp->fr_savpc) != sizeof (fp->fr_savpc))
122 *savefp = (
struct frame *) newfp;
137 log_stack_info (
print_output & output, uintptr_t pc, ulong_t
argc,
long *
argv,
struct ps_prochandle *Pr)
144 sprintf (buff,
"%.*lx", 8, (
long) pc);
145 strcpy (buff + 8,
" ????????");
147 if (Plookup_by_addr (Pr, pc, buff + 1 + 8,
sizeof (buff) - 1 - 8, &sym) == 0)
149 start = sym.st_value;
156 output (
"%-17s(", buff);
158 for (i = 0; i <
argc; i++)
160 output ((i + 1 == argc) ?
"%lx" :
"%lx, ", argv[i]);
163 output ((start != pc) ?
") + %lx\n" :
")\n", (
long) (pc - start));
178 struct frame *fp, *savefp;
181 struct ps_prochandle *Pr;
185 Pr = Pgrab (getpid (), PGRAB_RDONLY, &err);
191 if (getcontext (&ucp) < 0)
197 fp = (
struct frame *) ((caddr_t) ucp.uc_mcontext.gregs[FRAME_PTR_REGISTER] + STACK_BIAS);
199 fd = open (
"/proc/self/as", O_RDONLY);
208 if (read_safe (fd, fp, &savefp, &savepc) != 0)
221 if (savefp->fr_savfp == 0)
226 argc = argcount (savepc);
227 argv = (
long *) ((
char *) savefp +
sizeof (
struct frame));
229 log_stack_info (output, savepc, argc, argv, Pr);
238 static int er_resolve_function_name (
const void *address,
const char *lib_file_name,
char *buffer,
int buffer_size);
245 #include <ucontext.h> 252 #define PEEK_DATA(addr) (*(size_t *)(addr)) 254 #define BUFFER_SIZE 1024 265 size_t frame_pointer_addr, next_frame_pointer_addr;
266 size_t return_addr, arg;
269 const char *func_name_p;
270 const void *func_addr_p =
NULL;
273 if (getcontext (&ucp) < 0)
278 return_addr = ucp.uc_mcontext.gregs[REG_EIP];
279 frame_pointer_addr = ucp.uc_mcontext.gregs[REG_EBP];
281 while (frame_pointer_addr)
283 if (dladdr ((
size_t *) return_addr, &dl_info) == 0)
288 if (dl_info.dli_fbase >= (
const void *) 0x40000000)
290 func_addr_p = (
void *) ((
size_t) ((
const char *) return_addr) - (size_t) dl_info.dli_fbase);
294 func_addr_p = (
void *) return_addr;
297 if (dl_info.dli_sname)
299 func_name_p = dl_info.dli_sname;
303 if (er_resolve_function_name (func_addr_p, dl_info.dli_fname, buffer, sizeof (buffer)) ==
NO_ERROR)
305 func_name_p = buffer;
313 output (
"%s(%p): %s", dl_info.dli_fname, func_addr_p, func_name_p);
315 next_frame_pointer_addr = PEEK_DATA (frame_pointer_addr);
316 nargs = (next_frame_pointer_addr - frame_pointer_addr - 8) / 4;
325 for (i = 1; i <= nargs; i++)
327 arg = PEEK_DATA (frame_pointer_addr + 4 * (i + 1));
337 if (next_frame_pointer_addr == 0)
342 return_addr = PEEK_DATA (frame_pointer_addr + 4);
343 frame_pointer_addr = next_frame_pointer_addr;
355 #include <execinfo.h> 362 #define BUFFER_SIZE 1024 372 void *return_addr[MAX_TRACE];
375 const char *func_name_p;
376 const void *func_addr_p;
379 trace_count = backtrace (return_addr, MAX_TRACE);
381 for (i = 0; i < trace_count; i++)
383 if (dladdr (return_addr[i], &dl_info) == 0)
388 if (dl_info.dli_fbase >= (
const void *) 0x40000000)
390 func_addr_p = (
void *) ((
size_t) ((
const char *) return_addr[i]) - (size_t) dl_info.dli_fbase);
394 func_addr_p = return_addr[
i];
397 if (dl_info.dli_sname)
399 func_name_p = dl_info.dli_sname;
403 if (er_resolve_function_name (func_addr_p, dl_info.dli_fname, buffer, sizeof (buffer)) ==
NO_ERROR)
405 func_name_p = buffer;
413 output (
"%s(%p): %s\n", dl_info.dli_fname, func_addr_p, func_name_p);
423 er_resolve_function_name (
const void *address,
const char *lib_file_name_p,
char *buffer,
int buffer_size)
427 char *func_name_p, *pos;
430 snprintf (buf,
BUFFER_SIZE,
"%p%s", address, lib_file_name_p);
431 data = (
char *)
mht_get (fname_table, buf);
434 snprintf (buffer, buffer_size, data);
438 snprintf (cmd_line,
sizeof (cmd_line),
"addr2line -f -C -e %s %p 2>/dev/null", lib_file_name_p, address);
440 output = popen (cmd_line,
"r");
446 func_name_p = fgets (buffer, buffer_size - 1, output);
447 if (!func_name_p || !func_name_p[0])
453 pos = strchr (func_name_p,
'\n');
467 data =
strdup (func_name_p);
495 output (
"call stack dump: NOT available in this platform\n");
const void * mht_put(MHT_TABLE *ht, const void *key, void *data)
virtual int flush(void)=0
void er_dump_call_stack_internal(print_output &output)
void * mht_get(MHT_TABLE *ht, const void *key)
char * er_dump_call_stack_to_string(void)
const char * get_buffer() const
char * strdup(const char *str)
void er_dump_call_stack(FILE *outfp)