Ruby  2.0.0p247(2013-06-27revision41674)
vm_dump.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  vm_dump.c -
4 
5  $Author: ko1 $
6 
7  Copyright (C) 2004-2007 Koichi Sasada
8 
9 **********************************************************************/
10 
11 
12 #include "ruby/ruby.h"
13 #include "addr2line.h"
14 #include "vm_core.h"
15 #include "internal.h"
16 
17 /* see vm_insnhelper.h for the values */
18 #ifndef VMDEBUG
19 #define VMDEBUG 0
20 #endif
21 
22 #define MAX_POSBUF 128
23 
24 #define VM_CFP_CNT(th, cfp) \
25  ((rb_control_frame_t *)((th)->stack + (th)->stack_size) - (rb_control_frame_t *)(cfp))
26 
27 static void
29 {
30  ptrdiff_t pc = -1;
31  ptrdiff_t ep = cfp->ep - th->stack;
32  char ep_in_heap = ' ';
33  char posbuf[MAX_POSBUF+1];
34  int line = 0;
35 
36  const char *magic, *iseq_name = "-", *selfstr = "-", *biseq_name = "-";
37  VALUE tmp;
38 
39  if (cfp->block_iseq != 0 && BUILTIN_TYPE(cfp->block_iseq) != T_NODE) {
40  biseq_name = ""; /* RSTRING(cfp->block_iseq->location.label)->ptr; */
41  }
42 
43  if (ep < 0 || (size_t)ep > th->stack_size) {
44  ep = (ptrdiff_t)cfp->ep;
45  ep_in_heap = 'p';
46  }
47 
48  switch (VM_FRAME_TYPE(cfp)) {
49  case VM_FRAME_MAGIC_TOP:
50  magic = "TOP";
51  break;
53  magic = "METHOD";
54  break;
56  magic = "CLASS";
57  break;
59  magic = "BLOCK";
60  break;
62  magic = "CFUNC";
63  break;
65  magic = "PROC";
66  break;
68  magic = "LAMBDA";
69  break;
71  magic = "IFUNC";
72  break;
74  magic = "EVAL";
75  break;
76  case 0:
77  magic = "------";
78  break;
79  default:
80  magic = "(none)";
81  break;
82  }
83 
84  if (0) {
85  tmp = rb_inspect(cfp->self);
86  selfstr = StringValueCStr(tmp);
87  }
88  else {
89  selfstr = "";
90  }
91 
92  if (cfp->iseq != 0) {
93  if (RUBY_VM_IFUNC_P(cfp->iseq)) {
94  iseq_name = "<ifunc>";
95  }
96  else {
97  pc = cfp->pc - cfp->iseq->iseq_encoded;
98  iseq_name = RSTRING_PTR(cfp->iseq->location.label);
99  line = rb_vm_get_sourceline(cfp);
100  if (line) {
101  snprintf(posbuf, MAX_POSBUF, "%s:%d", RSTRING_PTR(cfp->iseq->location.path), line);
102  }
103  }
104  }
105  else if (cfp->me) {
106  iseq_name = rb_id2name(cfp->me->def->original_id);
107  snprintf(posbuf, MAX_POSBUF, ":%s", iseq_name);
108  line = -1;
109  }
110 
111  fprintf(stderr, "c:%04"PRIdPTRDIFF" ",
112  ((rb_control_frame_t *)(th->stack + th->stack_size) - cfp));
113  if (pc == -1) {
114  fprintf(stderr, "p:---- ");
115  }
116  else {
117  fprintf(stderr, "p:%04"PRIdPTRDIFF" ", pc);
118  }
119  fprintf(stderr, "s:%04"PRIdPTRDIFF" ", cfp->sp - th->stack);
120  fprintf(stderr, ep_in_heap == ' ' ? "e:%06"PRIdPTRDIFF" " : "E:%06"PRIxPTRDIFF" ", ep % 10000);
121  fprintf(stderr, "%-6s", magic);
122  if (line) {
123  fprintf(stderr, " %s", posbuf);
124  }
125  if (VM_FRAME_TYPE_FINISH_P(cfp)) {
126  fprintf(stderr, " [FINISH]");
127  }
128  if (0) {
129  fprintf(stderr, " \t");
130  fprintf(stderr, "iseq: %-24s ", iseq_name);
131  fprintf(stderr, "self: %-24s ", selfstr);
132  fprintf(stderr, "%-1s ", biseq_name);
133  }
134  fprintf(stderr, "\n");
135 }
136 
137 void
139 {
140 #if 0
141  VALUE *sp = cfp->sp, *ep = cfp->ep;
142  VALUE *p, *st, *t;
143 
144  fprintf(stderr, "-- stack frame ------------\n");
145  for (p = st = th->stack; p < sp; p++) {
146  fprintf(stderr, "%04ld (%p): %08"PRIxVALUE, (long)(p - st), p, *p);
147 
148  t = (VALUE *)*p;
149  if (th->stack <= t && t < sp) {
150  fprintf(stderr, " (= %ld)", (long)((VALUE *)GC_GUARDED_PTR_REF(t) - th->stack));
151  }
152 
153  if (p == ep)
154  fprintf(stderr, " <- ep");
155 
156  fprintf(stderr, "\n");
157  }
158 #endif
159 
160  fprintf(stderr, "-- Control frame information "
161  "-----------------------------------------------\n");
162  while ((void *)cfp < (void *)(th->stack + th->stack_size)) {
163  control_frame_dump(th, cfp);
164  cfp++;
165  }
166  fprintf(stderr, "\n");
167 }
168 
169 void
171 {
174 }
175 
176 void
178 {
179  int i;
180  fprintf(stderr, "-- env --------------------\n");
181 
182  while (env) {
183  fprintf(stderr, "--\n");
184  for (i = 0; i < env->env_size; i++) {
185  fprintf(stderr, "%04d: %08"PRIxVALUE" (%p)", -env->local_size + i, env->env[i],
186  (void *)&env->env[i]);
187  if (&env->env[i] == ep)
188  fprintf(stderr, " <- ep");
189  fprintf(stderr, "\n");
190  }
191 
192  if (env->prev_envval != 0) {
193  GetEnvPtr(env->prev_envval, env);
194  }
195  else {
196  env = 0;
197  }
198  }
199  fprintf(stderr, "---------------------------\n");
200 }
201 
202 void
204 {
205  rb_env_t *env;
206  char *selfstr;
207  VALUE val = rb_inspect(proc->block.self);
208  selfstr = StringValueCStr(val);
209 
210  fprintf(stderr, "-- proc -------------------\n");
211  fprintf(stderr, "self: %s\n", selfstr);
212  GetEnvPtr(proc->envval, env);
213  rb_vmdebug_env_dump_raw(env, proc->block.ep);
214 }
215 
216 void
218 {
219  rb_thread_t *th;
220  GetThreadPtr(thval, th);
222 }
223 
224 #if VMDEBUG > 2
225 
226 /* copy from vm.c */
227 static VALUE *
229 {
231  VALUE *bp = prev_cfp->sp + cfp->iseq->local_size + 1;
232 
233  if (cfp->iseq->type == ISEQ_TYPE_METHOD) {
234  bp += 1;
235  }
236  return bp;
237 }
238 
239 static void
240 vm_stack_dump_each(rb_thread_t *th, rb_control_frame_t *cfp)
241 {
242  int i;
243 
244  VALUE rstr;
245  VALUE *sp = cfp->sp;
246  VALUE *ep = cfp->ep;
247 
248  int argc = 0, local_size = 0;
249  const char *name;
250  rb_iseq_t *iseq = cfp->iseq;
251 
252  if (iseq == 0) {
253  if (RUBYVM_CFUNC_FRAME_P(cfp)) {
254  name = rb_id2name(cfp->me->called_id);
255  }
256  else {
257  name = "?";
258  }
259  }
260  else if (RUBY_VM_IFUNC_P(iseq)) {
261  name = "<ifunc>";
262  }
263  else {
264  argc = iseq->argc;
265  local_size = iseq->local_size;
266  name = RSTRING_PTR(iseq->location.label);
267  }
268 
269  /* stack trace header */
270 
271  if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_METHOD ||
280 
281  VALUE *ptr = ep - local_size;
282 
283  control_frame_dump(th, cfp);
284 
285  for (i = 0; i < argc; i++) {
286  rstr = rb_inspect(*ptr);
287  fprintf(stderr, " arg %2d: %8s (%p)\n", i, StringValueCStr(rstr),
288  (void *)ptr++);
289  }
290  for (; i < local_size - 1; i++) {
291  rstr = rb_inspect(*ptr);
292  fprintf(stderr, " local %2d: %8s (%p)\n", i, StringValueCStr(rstr),
293  (void *)ptr++);
294  }
295 
296  ptr = vm_base_ptr(cfp);
297  for (; ptr < sp; ptr++, i++) {
298  if (*ptr == Qundef) {
299  rstr = rb_str_new2("undef");
300  }
301  else {
302  rstr = rb_inspect(*ptr);
303  }
304  fprintf(stderr, " stack %2d: %8s (%"PRIdPTRDIFF")\n", i, StringValueCStr(rstr),
305  (ptr - th->stack));
306  }
307  }
308  else if (VM_FRAME_TYPE_FINISH_P(cfp)) {
309  if ((th)->stack + (th)->stack_size > (VALUE *)(cfp + 1)) {
310  vm_stack_dump_each(th, cfp + 1);
311  }
312  else {
313  /* SDR(); */
314  }
315  }
316  else {
317  rb_bug("unsupport frame type: %08lx", VM_FRAME_TYPE(cfp));
318  }
319 }
320 #endif
321 
322 void
324 {
325  rb_control_frame_t *cfp = th->cfp;
326  ptrdiff_t pc = -1;
327  ptrdiff_t ep = cfp->ep - th->stack;
328  ptrdiff_t cfpi;
329 
330  if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
331  pc = cfp->pc - cfp->iseq->iseq_encoded;
332  }
333 
334  if (ep < 0 || (size_t)ep > th->stack_size) {
335  ep = -1;
336  }
337 
338  cfpi = ((rb_control_frame_t *)(th->stack + th->stack_size)) - cfp;
339  fprintf(stderr, " [PC] %04"PRIdPTRDIFF", [SP] %04"PRIdPTRDIFF", [EP] %04"PRIdPTRDIFF", [CFP] %04"PRIdPTRDIFF"\n",
340  pc, (cfp->sp - th->stack), ep, cfpi);
341 }
342 
343 void
345 {
346  rb_thread_t *th;
347  GetThreadPtr(thval, th);
349 }
350 
351 void
353 {
354  rb_iseq_t *iseq = cfp->iseq;
355 
356  if (iseq != 0) {
357  VALUE *seq = iseq->iseq;
358  ptrdiff_t pc = cfp->pc - iseq->iseq_encoded;
359  int i;
360 
361  for (i=0; i<(int)VM_CFP_CNT(th, cfp); i++) {
362  printf(" ");
363  }
364  printf("| ");
365  /* printf("%3"PRIdPTRDIFF" ", VM_CFP_CNT(th, cfp)); */
366  if (pc >= 0) {
367  rb_iseq_disasm_insn(0, seq, (size_t)pc, iseq, 0);
368  }
369  }
370 
371 #if VMDEBUG > 3
372  fprintf(stderr, " (1)");
374 #endif
375 }
376 
377 void
380  , VALUE reg_a, VALUE reg_b
381 #endif
382  )
383 {
384 #if VMDEBUG > 9
385  SDR2(cfp);
386 #endif
387 
388 #if VMDEBUG > 3
389  fprintf(stderr, " (2)");
391 #endif
392  /* stack_dump_raw(th, cfp); */
393 
394 #if VMDEBUG > 2
395  /* stack_dump_thobj(th); */
396  vm_stack_dump_each(th, th->cfp);
397 
398 #if OPT_STACK_CACHING
399  {
400  VALUE rstr;
401  rstr = rb_inspect(reg_a);
402  fprintf(stderr, " sc reg A: %s\n", StringValueCStr(rstr));
403  rstr = rb_inspect(reg_b);
404  fprintf(stderr, " sc reg B: %s\n", StringValueCStr(rstr));
405  }
406 #endif
407  printf
408  ("--------------------------------------------------------------\n");
409 #endif
410 }
411 
412 VALUE
414 {
415  rb_thread_t *th;
416  rb_control_frame_t *cfp;
417  GetThreadPtr(self, th);
418  cfp = th->cfp;
419 
420  fprintf(stderr, "Thread state dump:\n");
421  fprintf(stderr, "pc : %p, sp : %p\n", (void *)cfp->pc, (void *)cfp->sp);
422  fprintf(stderr, "cfp: %p, ep : %p\n", (void *)cfp, (void *)cfp->ep);
423 
424  return Qnil;
425 }
426 
427 #ifndef HAVE_BACKTRACE
428 #define HAVE_BACKTRACE 0
429 #endif
430 #if HAVE_BACKTRACE
431 # include <execinfo.h>
432 #elif defined(_WIN32)
433 # include <imagehlp.h>
434 # ifndef SYMOPT_DEBUG
435 # define SYMOPT_DEBUG 0x80000000
436 # endif
437 # ifndef MAX_SYM_NAME
438 # define MAX_SYM_NAME 2000
439 typedef struct {
440  DWORD64 Offset;
441  WORD Segment;
442  ADDRESS_MODE Mode;
443 } ADDRESS64;
444 typedef struct {
445  DWORD64 Thread;
446  DWORD ThCallbackStack;
447  DWORD ThCallbackBStore;
448  DWORD NextCallback;
449  DWORD FramePointer;
450  DWORD64 KiCallUserMode;
451  DWORD64 KeUserCallbackDispatcher;
452  DWORD64 SystemRangeStart;
453  DWORD64 KiUserExceptionDispatcher;
454  DWORD64 StackBase;
455  DWORD64 StackLimit;
456  DWORD64 Reserved[5];
457 } KDHELP64;
458 typedef struct {
459  ADDRESS64 AddrPC;
460  ADDRESS64 AddrReturn;
461  ADDRESS64 AddrFrame;
462  ADDRESS64 AddrStack;
463  ADDRESS64 AddrBStore;
464  void *FuncTableEntry;
465  DWORD64 Params[4];
466  BOOL Far;
467  BOOL Virtual;
468  DWORD64 Reserved[3];
469  KDHELP64 KdHelp;
470 } STACKFRAME64;
471 typedef struct {
472  ULONG SizeOfStruct;
473  ULONG TypeIndex;
474  ULONG64 Reserved[2];
475  ULONG Index;
476  ULONG Size;
477  ULONG64 ModBase;
478  ULONG Flags;
479  ULONG64 Value;
480  ULONG64 Address;
481  ULONG Register;
482  ULONG Scope;
483  ULONG Tag;
484  ULONG NameLen;
485  ULONG MaxNameLen;
486  char Name[1];
487 } SYMBOL_INFO;
488 typedef struct {
489  DWORD SizeOfStruct;
490  void *Key;
491  DWORD LineNumber;
492  char *FileName;
493  DWORD64 Address;
494 } IMAGEHLP_LINE64;
495 typedef void *PREAD_PROCESS_MEMORY_ROUTINE64;
496 typedef void *PFUNCTION_TABLE_ACCESS_ROUTINE64;
497 typedef void *PGET_MODULE_BASE_ROUTINE64;
498 typedef void *PTRANSLATE_ADDRESS_ROUTINE64;
499 # endif
500 
501 static void
502 dump_thread(void *arg)
503 {
504  HANDLE dbghelp;
505  BOOL (WINAPI *pSymInitialize)(HANDLE, const char *, BOOL);
506  BOOL (WINAPI *pSymCleanup)(HANDLE);
507  BOOL (WINAPI *pStackWalk64)(DWORD, HANDLE, HANDLE, STACKFRAME64 *, void *, PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64, PGET_MODULE_BASE_ROUTINE64, PTRANSLATE_ADDRESS_ROUTINE64);
508  DWORD64 (WINAPI *pSymGetModuleBase64)(HANDLE, DWORD64);
509  BOOL (WINAPI *pSymFromAddr)(HANDLE, DWORD64, DWORD64 *, SYMBOL_INFO *);
510  BOOL (WINAPI *pSymGetLineFromAddr64)(HANDLE, DWORD64, DWORD *, IMAGEHLP_LINE64 *);
511  HANDLE (WINAPI *pOpenThread)(DWORD, BOOL, DWORD);
512  DWORD tid = *(DWORD *)arg;
513  HANDLE ph;
514  HANDLE th;
515 
516  dbghelp = LoadLibrary("dbghelp.dll");
517  if (!dbghelp) return;
518  pSymInitialize = (BOOL (WINAPI *)(HANDLE, const char *, BOOL))GetProcAddress(dbghelp, "SymInitialize");
519  pSymCleanup = (BOOL (WINAPI *)(HANDLE))GetProcAddress(dbghelp, "SymCleanup");
520  pStackWalk64 = (BOOL (WINAPI *)(DWORD, HANDLE, HANDLE, STACKFRAME64 *, void *, PREAD_PROCESS_MEMORY_ROUTINE64, PFUNCTION_TABLE_ACCESS_ROUTINE64, PGET_MODULE_BASE_ROUTINE64, PTRANSLATE_ADDRESS_ROUTINE64))GetProcAddress(dbghelp, "StackWalk64");
521  pSymGetModuleBase64 = (DWORD64 (WINAPI *)(HANDLE, DWORD64))GetProcAddress(dbghelp, "SymGetModuleBase64");
522  pSymFromAddr = (BOOL (WINAPI *)(HANDLE, DWORD64, DWORD64 *, SYMBOL_INFO *))GetProcAddress(dbghelp, "SymFromAddr");
523  pSymGetLineFromAddr64 = (BOOL (WINAPI *)(HANDLE, DWORD64, DWORD *, IMAGEHLP_LINE64 *))GetProcAddress(dbghelp, "SymGetLineFromAddr64");
524  pOpenThread = (HANDLE (WINAPI *)(DWORD, BOOL, DWORD))GetProcAddress(GetModuleHandle("kernel32.dll"), "OpenThread");
525  if (pSymInitialize && pSymCleanup && pStackWalk64 && pSymGetModuleBase64 &&
526  pSymFromAddr && pSymGetLineFromAddr64 && pOpenThread) {
527  SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG | SYMOPT_LOAD_LINES);
528  ph = GetCurrentProcess();
529  pSymInitialize(ph, NULL, TRUE);
530  th = pOpenThread(THREAD_SUSPEND_RESUME|THREAD_GET_CONTEXT, FALSE, tid);
531  if (th) {
532  if (SuspendThread(th) != (DWORD)-1) {
533  CONTEXT context;
534  memset(&context, 0, sizeof(context));
535  context.ContextFlags = CONTEXT_FULL;
536  if (GetThreadContext(th, &context)) {
537  char libpath[MAX_PATH];
538  char buf[sizeof(SYMBOL_INFO) + MAX_SYM_NAME];
539  SYMBOL_INFO *info = (SYMBOL_INFO *)buf;
540  DWORD mac;
541  STACKFRAME64 frame;
542  memset(&frame, 0, sizeof(frame));
543 #if defined(_M_AMD64) || defined(__x86_64__)
544  mac = IMAGE_FILE_MACHINE_AMD64;
545  frame.AddrPC.Mode = AddrModeFlat;
546  frame.AddrPC.Offset = context.Rip;
547  frame.AddrFrame.Mode = AddrModeFlat;
548  frame.AddrFrame.Offset = context.Rbp;
549  frame.AddrStack.Mode = AddrModeFlat;
550  frame.AddrStack.Offset = context.Rsp;
551 #elif defined(_M_IA64) || defined(__ia64__)
552  mac = IMAGE_FILE_MACHINE_IA64;
553  frame.AddrPC.Mode = AddrModeFlat;
554  frame.AddrPC.Offset = context.StIIP;
555  frame.AddrBStore.Mode = AddrModeFlat;
556  frame.AddrBStore.Offset = context.RsBSP;
557  frame.AddrStack.Mode = AddrModeFlat;
558  frame.AddrStack.Offset = context.IntSp;
559 #else /* i386 */
560  mac = IMAGE_FILE_MACHINE_I386;
561  frame.AddrPC.Mode = AddrModeFlat;
562  frame.AddrPC.Offset = context.Eip;
563  frame.AddrFrame.Mode = AddrModeFlat;
564  frame.AddrFrame.Offset = context.Ebp;
565  frame.AddrStack.Mode = AddrModeFlat;
566  frame.AddrStack.Offset = context.Esp;
567 #endif
568 
569  while (pStackWalk64(mac, ph, th, &frame, &context, NULL,
570  NULL, NULL, NULL)) {
571  DWORD64 addr = frame.AddrPC.Offset;
572  IMAGEHLP_LINE64 line;
573  DWORD64 displacement;
574  DWORD tmp;
575 
576  if (addr == frame.AddrReturn.Offset || addr == 0 ||
577  frame.AddrReturn.Offset == 0)
578  break;
579 
580  memset(buf, 0, sizeof(buf));
581  info->SizeOfStruct = sizeof(SYMBOL_INFO);
582  info->MaxNameLen = MAX_SYM_NAME;
583  if (pSymFromAddr(ph, addr, &displacement, info)) {
584  if (GetModuleFileName((HANDLE)(uintptr_t)pSymGetModuleBase64(ph, addr), libpath, sizeof(libpath)))
585  fprintf(stderr, "%s", libpath);
586  fprintf(stderr, "(%s+0x%I64x)",
587  info->Name, displacement);
588  }
589  fprintf(stderr, " [0x%p]", (void *)(VALUE)addr);
590  memset(&line, 0, sizeof(line));
591  line.SizeOfStruct = sizeof(line);
592  if (pSymGetLineFromAddr64(ph, addr, &tmp, &line))
593  fprintf(stderr, " %s:%lu", line.FileName, line.LineNumber);
594  fprintf(stderr, "\n");
595  }
596  }
597 
598  ResumeThread(th);
599  }
600  CloseHandle(th);
601  }
602  pSymCleanup(ph);
603  }
604  FreeLibrary(dbghelp);
605 }
606 #endif
607 
608 void
610 {
611 #ifdef __linux__
612 # define PROC_MAPS_NAME "/proc/self/maps"
613 #endif
614 #ifdef PROC_MAPS_NAME
615  enum {other_runtime_info = 1};
616 #else
617  enum {other_runtime_info = 0};
618 #endif
619  const rb_vm_t *const vm = GET_VM();
620 
621 #if defined __APPLE__
622  fputs("-- Crash Report log information "
623  "--------------------------------------------\n"
624  " See Crash Report log file under the one of following:\n"
625  " * ~/Library/Logs/CrashReporter\n"
626  " * /Library/Logs/CrashReporter\n"
627  " * ~/Library/Logs/DiagnosticReports\n"
628  " * /Library/Logs/DiagnosticReports\n"
629  " the more detail of.\n"
630  "\n",
631  stderr);
632 #endif
633  if (vm) {
634  SDR();
636  fputs("\n", stderr);
637  }
638 
639 #if HAVE_BACKTRACE || defined(_WIN32)
640  fprintf(stderr, "-- C level backtrace information "
641  "-------------------------------------------\n");
642 
643  {
644 #if HAVE_BACKTRACE
645 #define MAX_NATIVE_TRACE 1024
646  static void *trace[MAX_NATIVE_TRACE];
647  int n = backtrace(trace, MAX_NATIVE_TRACE);
648  char **syms = backtrace_symbols(trace, n);
649 
650  if (syms) {
651 #ifdef USE_ELF
652  rb_dump_backtrace_with_lines(n, trace, syms);
653 #else
654  int i;
655  for (i=0; i<n; i++) {
656  fprintf(stderr, "%s\n", syms[i]);
657  }
658 #endif
659  free(syms);
660  }
661 #elif defined(_WIN32)
662  DWORD tid = GetCurrentThreadId();
663  HANDLE th = (HANDLE)_beginthread(dump_thread, 0, &tid);
664  if (th != (HANDLE)-1)
665  WaitForSingleObject(th, INFINITE);
666 #endif
667  }
668 
669  fprintf(stderr, "\n");
670 #endif /* HAVE_BACKTRACE */
671 
672  if (other_runtime_info || vm) {
673  fprintf(stderr, "-- Other runtime information "
674  "-----------------------------------------------\n\n");
675  }
676  if (vm) {
677  int i;
678  VALUE name;
679  long len;
680  const int max_name_length = 1024;
681 # define LIMITED_NAME_LENGTH(s) \
682  (((len = RSTRING_LEN(s)) > max_name_length) ? max_name_length : (int)len)
683 
684  name = vm->progname;
685  fprintf(stderr, "* Loaded script: %.*s\n",
686  LIMITED_NAME_LENGTH(name), RSTRING_PTR(name));
687  fprintf(stderr, "\n");
688  fprintf(stderr, "* Loaded features:\n\n");
689  for (i=0; i<RARRAY_LEN(vm->loaded_features); i++) {
690  name = RARRAY_PTR(vm->loaded_features)[i];
691  if (RB_TYPE_P(name, T_STRING)) {
692  fprintf(stderr, " %4d %.*s\n", i,
693  LIMITED_NAME_LENGTH(name), RSTRING_PTR(name));
694  }
695  else {
696  fprintf(stderr, " %4d #<%s:%p>\n", i,
697  rb_class2name(CLASS_OF(name)), (void *)name);
698  }
699  }
700  fprintf(stderr, "\n");
701  }
702 
703  {
704 #ifdef PROC_MAPS_NAME
705  {
706  FILE *fp = fopen(PROC_MAPS_NAME, "r");
707  if (fp) {
708  fprintf(stderr, "* Process memory map:\n\n");
709 
710  while (!feof(fp)) {
711  char buff[0x100];
712  size_t rn = fread(buff, 1, 0x100, fp);
713  if (fwrite(buff, 1, rn, stderr) != rn)
714  break;
715  }
716 
717  fclose(fp);
718  fprintf(stderr, "\n\n");
719  }
720  }
721 #endif /* __linux__ */
722  }
723 }
#define RB_TYPE_P(obj, type)
RARRAY_PTR(q->result)[0]
rb_control_frame_t * cfp
Definition: vm_core.h:500
#define VM_FRAME_MAGIC_BLOCK
Definition: vm_core.h:725
volatile VALUE tmp
Definition: tcltklib.c:10209
int rb_iseq_disasm_insn(VALUE ret, VALUE *iseq, size_t pos, rb_iseq_t *iseqdat, VALUE child)
Disassemble a instruction Iseq -&gt; Iseq inspect object.
Definition: iseq.c:1250
VALUE * env
Definition: vm_core.h:682
ssize_t n
Definition: bigdecimal.c:5655
VALUE prev_envval
Definition: vm_core.h:685
VP_EXPORT int
Definition: bigdecimal.c:5050
void rb_bug(const char *fmt,...)
Definition: error.c:290
#define FALSE
Definition: nkf.h:174
void rb_backtrace_print_as_bugreport(void)
Definition: vm_backtrace.c:750
static VALUE VALUE th
Definition: tcltklib.c:2948
#define RUBY_VM_IFUNC_P(ptr)
Definition: vm_core.h:796
int rb_vm_get_sourceline(const rb_control_frame_t *cfp)
Definition: vm_backtrace.c:33
#define VM_CFP_CNT(th, cfp)
Definition: vm_dump.c:24
static void control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
Definition: vm_dump.c:28
Win32OLEIDispatch * p
Definition: win32ole.c:786
#define VM_FRAME_TYPE_FINISH_P(cfp)
Definition: vm_core.h:741
#define VM_FRAME_MAGIC_CFUNC
Definition: vm_core.h:728
VALUE rb_vmdebug_thread_dump_state(VALUE self)
Definition: vm_dump.c:413
#define RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)
Definition: vm_core.h:787
#define RUBY_VM_NORMAL_ISEQ_P(ptr)
Definition: vm_core.h:797
VALUE progname
Definition: vm_core.h:381
VALUE proc
Definition: tcltklib.c:2959
ssize_t i
Definition: bigdecimal.c:5655
#define T_NODE
Tcl_CmdInfo * info
Definition: tcltklib.c:1463
int env_size
Definition: vm_core.h:683
void rb_vmdebug_stack_dump_th(VALUE thval)
Definition: vm_dump.c:217
#define RSTRING_PTR(str)
#define CLASS_OF(v)
#define MAX_POSBUF
Definition: vm_dump.c:22
#define SDR2(cfp)
Definition: vm_core.h:815
#define VM_FRAME_MAGIC_METHOD
Definition: vm_core.h:724
#define VM_FRAME_TYPE(cfp)
Definition: vm_core.h:736
ID called_id
Definition: method.h:99
#define VM_FRAME_MAGIC_IFUNC
Definition: vm_core.h:730
#define SDR()
Definition: vm_core.h:814
#define GetEnvPtr(obj, ptr)
Definition: vm_core.h:678
#define rb_str_new2
void rb_vmdebug_stack_dump_raw(rb_thread_t *, rb_control_frame_t *)
Definition: vm_dump.c:138
VALUE envval
Definition: vm_core.h:671
#define OPT_STACK_CACHING
VALUE * iseq
Definition: vm_core.h:215
VALUE * stack
Definition: vm_core.h:498
enum rb_iseq_struct::iseq_type type
memset(y->frac+ix+1, 0,(y->Prec-(ix+1))*sizeof(BDIGIT))
#define RARRAY_LEN(a)
#define Qnil
Definition: tcltklib.c:1896
#define val
Definition: tcltklib.c:1949
rb_iseq_t * block_iseq
Definition: vm_core.h:433
IUnknown DWORD
Definition: win32ole.c:149
#define StringValueCStr(v)
int argc
argument information
Definition: vm_core.h:264
rb_iseq_t * iseq
Definition: vm_core.h:428
#define PRIxVALUE
#define T_STRING
#define PRIxPTRDIFF
void rb_vm_bugreport(void)
Definition: vm_dump.c:609
#define VM_FRAME_MAGIC_CLASS
Definition: vm_core.h:726
void rb_vmdebug_debug_print_pre(rb_thread_t *th, rb_control_frame_t *cfp)
Definition: vm_dump.c:352
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
void rb_vmdebug_debug_print_register(rb_thread_t *th)
Definition: vm_dump.c:323
#define TRUE
Definition: nkf.h:175
VALUE loaded_features
Definition: vm_core.h:365
#define RUBYVM_CFUNC_FRAME_P(cfp)
Definition: vm_core.h:743
int local_size
Definition: vm_core.h:684
unsigned int uintptr_t
Definition: win32.h:94
#define VM_FRAME_MAGIC_EVAL
Definition: vm_core.h:731
VALUE * iseq_encoded
Definition: vm_core.h:216
int argc
Definition: tcltklib.c:1970
static VALUE * vm_base_ptr(rb_control_frame_t *cfp)
rb_iseq_location_t location
Definition: vm_core.h:213
void rb_vmdebug_env_dump_raw(rb_env_t *env, VALUE *ep)
Definition: vm_dump.c:177
#define free(x)
Definition: dln.c:50
return ptr
Definition: tcltklib.c:784
#define VM_FRAME_MAGIC_TOP
Definition: vm_core.h:727
#define VM_FRAME_MAGIC_PROC
Definition: vm_core.h:729
const char * rb_class2name(VALUE)
Definition: variable.c:384
arg
Definition: ripper.y:1312
#define VM_FRAME_MAGIC_LAMBDA
Definition: vm_core.h:732
rb_block_t block
Definition: vm_core.h:669
#define Qundef
rb_method_definition_t * def
Definition: method.h:98
int t
Definition: ripper.c:13760
const rb_method_entry_t * me
Definition: vm_core.h:435
#define PRIdPTRDIFF
void rb_vmdebug_thread_dump_regs(VALUE thval)
Definition: vm_dump.c:344
int local_size
Definition: vm_core.h:229
#define GetThreadPtr(obj, ptr)
Definition: vm_core.h:452
void rb_vmdebug_proc_dump_raw(rb_proc_t *proc)
Definition: vm_dump.c:203
void rb_vmdebug_stack_dump_raw_current(void)
Definition: vm_dump.c:170
void rb_vmdebug_debug_print_post(rb_thread_t *th, rb_control_frame_t *cfp)
Definition: vm_dump.c:378
const char * rb_id2name(ID id)
Definition: ripper.c:16068
size_t stack_size
Definition: vm_core.h:499
#define BUILTIN_TYPE(x)
unsigned long VALUE
Definition: ripper.y:104
#define GC_GUARDED_PTR_REF(p)
Definition: vm_core.h:762
#define snprintf
#define feof(p)
Definition: vsnprintf.c:218
#define env
#define NULL
Definition: _sdbm.c:103
const char * name
Definition: nkf.c:208
static rb_thread_t * GET_THREAD(void)
Definition: vm_core.h:883
static ULONG(STDMETHODCALLTYPE AddRef)(IDispatch __RPC_FAR *This)
Definition: win32ole.c:614
#define bp()
Definition: vm_debug.h:27
Tcl_Interp *int * st
Definition: stubs.c:510
#define LIMITED_NAME_LENGTH(s)
VALUE * ep
Definition: vm_core.h:445
VALUE rb_inspect(VALUE)
Definition: object.c:402
#define GET_VM()
Definition: vm_core.h:876
size_t len
Definition: tcltklib.c:3568