|
|
1.1 ! root 1: /* Print and select stack frames for GDB, the GNU debugger. ! 2: Copyright (C) 1986, 1987 Free Software Foundation, Inc. ! 3: ! 4: GDB is distributed in the hope that it will be useful, but WITHOUT ANY ! 5: WARRANTY. No author or distributor accepts responsibility to anyone ! 6: for the consequences of using it or for whether it serves any ! 7: particular purpose or works at all, unless he says so in writing. ! 8: Refer to the GDB General Public License for full details. ! 9: ! 10: Everyone is granted permission to copy, modify and redistribute GDB, ! 11: but only under the conditions described in the GDB General Public ! 12: License. A copy of this license is supposed to have been given to you ! 13: along with GDB so you can know your rights and responsibilities. It ! 14: should be in a file named COPYING. Among other things, the copyright ! 15: notice and this notice must be preserved on all copies. ! 16: ! 17: In other words, go ahead and share GDB, but don't try to stop ! 18: anyone else from sharing it farther. Help stamp out software hoarding! ! 19: */ ! 20: ! 21: #include <stdio.h> ! 22: ! 23: #include "defs.h" ! 24: #include "initialize.h" ! 25: #include "param.h" ! 26: #include "symtab.h" ! 27: #include "frame.h" ! 28: ! 29: START_FILE ! 30: ! 31: /* Thie "selected" stack frame is used by default for local and arg access. ! 32: May be zero, for no selected frame. */ ! 33: ! 34: FRAME selected_frame; ! 35: ! 36: /* Level of the selected frame: ! 37: 0 for innermost, 1 for its caller, ... ! 38: or -1 for frame specified by address with no defined level. */ ! 39: ! 40: int selected_frame_level; ! 41: ! 42: /* Nonzero means print the full filename and linenumber ! 43: when a frame is printed, and do so in a format programs can parse. */ ! 44: ! 45: int frame_file_full_name = 0; ! 46: ! 47: static void select_calling_frame (); ! 48: ! 49: void print_frame_info (); ! 50: ! 51: /* Print a stack frame briefly. FRAME should be the frame address ! 52: and LEVEL should be its level in the stack (or -1 for level not defined). ! 53: This prints the level, the function executing, the arguments, ! 54: and the file name and line number. ! 55: If the pc is not at the beginning of the source line, ! 56: the actual pc is printed at the beginning. ! 57: ! 58: If SOURCE is 1, print the source line as well. ! 59: If SOURCE is -1, print ONLY the source line. */ ! 60: ! 61: static void ! 62: print_stack_frame (frame, level, source) ! 63: FRAME frame; ! 64: int level; ! 65: int source; ! 66: { ! 67: struct frame_info fi; ! 68: ! 69: fi = get_frame_info (frame); ! 70: ! 71: print_frame_info (&fi, level, source, 1); ! 72: } ! 73: ! 74: void ! 75: print_frame_info (fi, level, source, args) ! 76: struct frame_info *fi; ! 77: register int level; ! 78: int source; ! 79: int args; ! 80: { ! 81: register FRAME frame = fi->frame; ! 82: struct symtab_and_line sal; ! 83: struct symbol *func; ! 84: register char *funname = 0; ! 85: int numargs; ! 86: ! 87: sal = find_pc_line (fi->pc, fi->next_frame); ! 88: func = get_frame_function (frame); ! 89: if (func) ! 90: funname = SYMBOL_NAME (func); ! 91: else ! 92: { ! 93: register int misc_index = find_pc_misc_function (fi->pc); ! 94: if (misc_index >= 0) ! 95: funname = misc_function_vector[misc_index].name; ! 96: } ! 97: ! 98: if (source >= 0 || !sal.symtab) ! 99: { ! 100: /* This avoids a bug in cc on the sun. */ ! 101: struct frame_info tem; ! 102: tem = *fi; ! 103: ! 104: if (level >= 0) ! 105: printf ("#%-2d ", level); ! 106: if (fi->pc != sal.pc || !sal.symtab) ! 107: printf ("0x%x in ", fi->pc); ! 108: printf ("%s (", funname ? funname : "??"); ! 109: if (args) ! 110: { ! 111: FRAME_NUM_ARGS (numargs, tem); ! 112: print_frame_args (func, FRAME_ARGS_ADDRESS (tem), numargs, stdout); ! 113: } ! 114: printf (")"); ! 115: if (sal.symtab) ! 116: printf (" (%s line %d)", sal.symtab->filename, sal.line); ! 117: printf ("\n"); ! 118: } ! 119: ! 120: if (source != 0 && sal.symtab) ! 121: { ! 122: int done = 0; ! 123: int mid_statement = source < 0 && fi->pc != sal.pc; ! 124: if (frame_file_full_name) ! 125: done = identify_source_line (sal.symtab, sal.line, mid_statement); ! 126: if (!done) ! 127: { ! 128: if (mid_statement) ! 129: printf ("0x%x\t", fi->pc); ! 130: print_source_lines (sal.symtab, sal.line, sal.line + 1, 1); ! 131: } ! 132: current_source_line = max (sal.line - 5, 1); ! 133: } ! 134: if (source != 0) ! 135: set_default_breakpoint (1, fi->pc, sal.symtab, sal.line); ! 136: ! 137: fflush (stdout); ! 138: } ! 139: ! 140: /* Call here to print info on selected frame, after a trap. */ ! 141: ! 142: void ! 143: print_sel_frame (just_source) ! 144: int just_source; ! 145: { ! 146: print_stack_frame (selected_frame, -1, just_source ? -1 : 1); ! 147: } ! 148: ! 149: /* Print info on the selected frame, including level number ! 150: but not source. */ ! 151: ! 152: print_selected_frame () ! 153: { ! 154: print_stack_frame (selected_frame, selected_frame_level, 0); ! 155: } ! 156: ! 157: /* Print verbosely the selected frame or the frame at address ADDR. ! 158: This means absolutely all information in the frame is printed. */ ! 159: ! 160: static void ! 161: frame_info (addr_exp) ! 162: char *addr_exp; ! 163: { ! 164: FRAME frame = addr_exp ? parse_and_eval_address (addr_exp) : selected_frame; ! 165: struct frame_info fi; ! 166: struct frame_saved_regs fsr; ! 167: struct symtab_and_line sal; ! 168: struct symbol *func; ! 169: FRAME calling_frame; ! 170: int i, count; ! 171: char *funname = 0; ! 172: int numargs; ! 173: ! 174: fi = get_frame_info (frame); ! 175: get_frame_saved_regs (&fi, &fsr); ! 176: sal = find_pc_line (fi.pc, fi.next_frame); ! 177: func = get_frame_function (frame); ! 178: if (func) ! 179: funname = SYMBOL_NAME (func); ! 180: else ! 181: { ! 182: register int misc_index = find_pc_misc_function (fi.pc); ! 183: if (misc_index >= 0) ! 184: funname = misc_function_vector[misc_index].name; ! 185: } ! 186: calling_frame = get_prev_frame (frame); ! 187: ! 188: if (!addr_exp && selected_frame_level >= 0) ! 189: printf ("Stack level %d, frame at 0x%x:\n pc = 0x%x", ! 190: selected_frame_level, frame, fi.pc); ! 191: else ! 192: printf ("Stack frame at 0x%x:\n pc = 0x%x", ! 193: frame, fi.pc); ! 194: ! 195: if (funname) ! 196: printf (" in %s", funname); ! 197: if (sal.symtab) ! 198: printf (" (%s line %d)", sal.symtab->filename, sal.line); ! 199: printf ("; saved pc 0x%x\n", FRAME_SAVED_PC (frame)); ! 200: if (calling_frame) ! 201: printf (" called by frame at 0x%x", calling_frame); ! 202: if (fi.next_frame && calling_frame) ! 203: printf (","); ! 204: if (fi.next_frame) ! 205: printf (" caller of frame at 0x%x", fi.next_frame); ! 206: if (fi.next_frame || calling_frame) ! 207: printf ("\n"); ! 208: printf (" Arglist at 0x%x,", FRAME_ARGS_ADDRESS (fi)); ! 209: FRAME_NUM_ARGS (i, fi); ! 210: if (i < 0) ! 211: printf (" args: "); ! 212: else if (i == 0) ! 213: printf (" no args."); ! 214: else if (i == 1) ! 215: printf (" 1 arg: "); ! 216: else ! 217: printf (" %d args: ", i); ! 218: ! 219: FRAME_NUM_ARGS (numargs, fi); ! 220: print_frame_args (func, FRAME_ARGS_ADDRESS (fi), numargs, stdout); ! 221: printf ("\n"); ! 222: count = 0; ! 223: for (i = 0; i < NUM_REGS; i++) ! 224: if (fsr.regs[i]) ! 225: { ! 226: if (count % 4 != 0) ! 227: printf (", "); ! 228: else ! 229: { ! 230: if (count == 0) ! 231: printf (" Saved registers:"); ! 232: printf ("\n "); ! 233: } ! 234: printf ("%s at 0x%x", reg_names[i], fsr.regs[i]); ! 235: count++; ! 236: } ! 237: if (count) ! 238: printf ("\n"); ! 239: } ! 240: ! 241: /* Print briefly all stack frames or just the innermost COUNT frames. */ ! 242: ! 243: static void ! 244: backtrace_command (count_exp) ! 245: char *count_exp; ! 246: { ! 247: struct frame_info fi; ! 248: register int count; ! 249: register FRAME frame; ! 250: register int i; ! 251: ! 252: if (count_exp) ! 253: count = parse_and_eval_address (count_exp); ! 254: else ! 255: count = -1; ! 256: ! 257: for (i = 0, frame = get_current_frame (), fi = get_frame_info (frame); ! 258: frame && count--; ! 259: i++, fi = get_prev_frame_info (fi.frame), frame = fi.frame) ! 260: { ! 261: QUIT; ! 262: print_frame_info (&fi, i, 0, 1); ! 263: } ! 264: } ! 265: ! 266: /* Print the local variables of a block B active in FRAME. */ ! 267: ! 268: static void ! 269: print_block_frame_locals (b, frame, stream) ! 270: struct block *b; ! 271: register FRAME frame; ! 272: register FILE *stream; ! 273: { ! 274: int nsyms; ! 275: register int i; ! 276: register struct symbol *sym; ! 277: ! 278: nsyms = BLOCK_NSYMS (b); ! 279: ! 280: for (i = 0; i < nsyms; i++) ! 281: { ! 282: sym = BLOCK_SYM (b, i); ! 283: if (SYMBOL_CLASS (sym) == LOC_LOCAL ! 284: || SYMBOL_CLASS (sym) == LOC_REGISTER ! 285: || SYMBOL_CLASS (sym) == LOC_STATIC) ! 286: { ! 287: fprintf (stream, "%s = ", SYMBOL_NAME (sym)); ! 288: print_variable_value (sym, frame, stream); ! 289: fprintf (stream, "\n"); ! 290: fflush (stream); ! 291: } ! 292: } ! 293: } ! 294: ! 295: /* Print on STREAM all the local variables in frame FRAME, ! 296: including all the blocks active in that frame ! 297: at its current pc. ! 298: ! 299: Returns 1 if the job was done, ! 300: or 0 if nothing was printed because we have no info ! 301: on the function running in FRAME. */ ! 302: ! 303: static int ! 304: print_frame_local_vars (frame, stream) ! 305: register FRAME frame; ! 306: register FILE *stream; ! 307: { ! 308: register struct block *block = get_frame_block (frame); ! 309: if (block == 0) ! 310: return 0; ! 311: while (block != 0) ! 312: { ! 313: print_block_frame_locals (block, frame, stream); ! 314: /* After handling the function's top-level block, stop. ! 315: Don't continue to its superblock, the block of ! 316: per-file symbols. */ ! 317: if (BLOCK_FUNCTION (block)) ! 318: break; ! 319: block = BLOCK_SUPERBLOCK (block); ! 320: } ! 321: return 1; ! 322: } ! 323: ! 324: static void ! 325: locals_info () ! 326: { ! 327: print_frame_local_vars (selected_frame, stdout); ! 328: } ! 329: ! 330: static int ! 331: print_frame_arg_vars (frame, stream) ! 332: register FRAME frame; ! 333: register FILE *stream; ! 334: { ! 335: struct symbol *func = get_frame_function (frame); ! 336: register struct block *b; ! 337: int nsyms; ! 338: register int i; ! 339: register struct symbol *sym; ! 340: ! 341: if (func == 0) ! 342: return 0; ! 343: ! 344: b = SYMBOL_BLOCK_VALUE (func); ! 345: nsyms = BLOCK_NSYMS (b); ! 346: ! 347: for (i = 0; i < nsyms; i++) ! 348: { ! 349: sym = BLOCK_SYM (b, i); ! 350: if (SYMBOL_CLASS (sym) == LOC_ARG) ! 351: { ! 352: fprintf (stream, "%s = ", SYMBOL_NAME (sym)); ! 353: print_variable_value (sym, frame, stream); ! 354: fprintf (stream, "\n"); ! 355: fflush (stream); ! 356: } ! 357: } ! 358: ! 359: return 1; ! 360: } ! 361: ! 362: static void ! 363: args_info () ! 364: { ! 365: print_frame_arg_vars (selected_frame, stdout); ! 366: } ! 367: ! 368: /* Select frame FRAME, and note that its stack level is LEVEL. ! 369: LEVEL may be -1 if an actual level number is not known. */ ! 370: ! 371: void ! 372: select_frame (frame, level) ! 373: FRAME frame; ! 374: int level; ! 375: { ! 376: selected_frame = frame; ! 377: selected_frame_level = level; ! 378: } ! 379: ! 380: /* Store the selected frame and its level into *FRAMEP and *LEVELP. */ ! 381: ! 382: void ! 383: record_selected_frame (framep, levelp) ! 384: FRAME *framep; ! 385: int *levelp; ! 386: { ! 387: *framep = selected_frame; ! 388: *levelp = selected_frame_level; ! 389: } ! 390: ! 391: /* Return the symbol-block in which the selected frame is executing. ! 392: Can return zero under various legitimate circumstances. */ ! 393: ! 394: struct block * ! 395: get_selected_block () ! 396: { ! 397: if (!have_inferior_p () && !have_core_file_p ()) ! 398: return 0; ! 399: ! 400: if (!selected_frame) ! 401: return get_current_block (); ! 402: return get_frame_block (selected_frame); ! 403: } ! 404: ! 405: /* Find a frame a certain number of levels away from FRAME. ! 406: LEVEL_OFFSET_PTR points to an int containing the number of levels. ! 407: Positive means go to earlier frames (up); negative, the reverse. ! 408: The int that contains the number of levels is counted toward ! 409: zero as the frames for those levels are found. ! 410: If the top or bottom frame is reached, that frame is returned, ! 411: but the final value of *LEVEL_OFFSET_PTR is nonzero and indicates ! 412: how much farther the original request asked to go. */ ! 413: ! 414: FRAME ! 415: find_relative_frame (frame, level_offset_ptr) ! 416: register FRAME frame; ! 417: register int* level_offset_ptr; ! 418: { ! 419: register FRAME prev; ! 420: struct frame_info fi; ! 421: register FRAME frame1, frame2; ! 422: ! 423: /* Going up is simple: just do get_prev_frame enough times ! 424: or until initial frame is reached. */ ! 425: while (*level_offset_ptr > 0) ! 426: { ! 427: prev = get_prev_frame (frame); ! 428: if (prev == 0) ! 429: break; ! 430: (*level_offset_ptr)--; ! 431: frame = prev; ! 432: } ! 433: /* Going down could be done by iterating get_frame_info to ! 434: find the next frame, but that would be quadratic ! 435: since get_frame_info must scan all the way from the current frame. ! 436: The following algotithm is linear. */ ! 437: if (*level_offset_ptr < 0) ! 438: { ! 439: /* First put frame1 at innermost frame ! 440: and frame2 N levels up from there. */ ! 441: frame1 = get_current_frame (); ! 442: frame2 = frame1; ! 443: while (*level_offset_ptr < 0 && frame2 != frame) ! 444: { ! 445: frame2 = get_prev_frame (frame2); ! 446: (*level_offset_ptr) ++; ! 447: } ! 448: /* Then slide frame1 and frame2 up in synchrony ! 449: and when frame2 reaches our starting point ! 450: frame1 must be N levels down from there. */ ! 451: while (frame2 != frame) ! 452: { ! 453: frame1 = get_prev_frame (frame1); ! 454: frame2 = get_prev_frame (frame2); ! 455: } ! 456: return frame1; ! 457: } ! 458: return frame; ! 459: } ! 460: ! 461: /* The "frame" command. With no arg, print selected frame briefly. ! 462: With arg LEVEL, select the frame at level LEVEL and print it. ! 463: With arg larger than 100000, use it as address of frame to select. ! 464: If from command file or user-defined command, don't print anything ! 465: if we have an argument. */ ! 466: ! 467: static void ! 468: frame_command (level_exp, from_tty) ! 469: char *level_exp; ! 470: int from_tty; ! 471: { ! 472: register int i; ! 473: register FRAME frame; ! 474: unsigned int level, level1; ! 475: ! 476: if (level_exp) ! 477: { ! 478: level1 = level = parse_and_eval_address (level_exp); ! 479: if (level > 100000) ! 480: { ! 481: select_frame (level, -1); ! 482: frame_info (0); ! 483: return; ! 484: } ! 485: ! 486: frame = find_relative_frame (get_current_frame (), &level1); ! 487: if (level1 != 0) ! 488: error ("Stack level %d is out of range.", level); ! 489: select_frame (frame, level); ! 490: if (! from_tty) ! 491: return; ! 492: } ! 493: ! 494: print_stack_frame (selected_frame, selected_frame_level, 1); ! 495: } ! 496: ! 497: /* Select the frame up one or COUNT stack levels ! 498: from the previously selected frame, and print it briefly. */ ! 499: ! 500: static void ! 501: up_command (count_exp) ! 502: char *count_exp; ! 503: { ! 504: register FRAME frame; ! 505: int count = 1, count1; ! 506: if (count_exp) ! 507: count = parse_and_eval_address (count_exp); ! 508: count1 = count; ! 509: ! 510: frame = find_relative_frame (selected_frame, &count1); ! 511: if (count1 != 0 && count_exp == 0) ! 512: error ("Initial frame selected; you cannot go up."); ! 513: select_frame (frame, selected_frame_level + count - count1); ! 514: ! 515: print_stack_frame (selected_frame, selected_frame_level, 1); ! 516: } ! 517: ! 518: /* Select the frame down one or COUNT stack levels ! 519: from the previously selected frame, and print it briefly. */ ! 520: ! 521: static void ! 522: down_command (count_exp) ! 523: char *count_exp; ! 524: { ! 525: register FRAME frame; ! 526: int count = -1, count1; ! 527: if (count_exp) ! 528: count = - parse_and_eval_address (count_exp); ! 529: count1 = count; ! 530: ! 531: frame = find_relative_frame (selected_frame, &count1); ! 532: if (count1 != 0 && count_exp == 0) ! 533: error ("Bottom (i.e., innermost) frame selected; you cannot go down."); ! 534: select_frame (frame, selected_frame_level + count - count1); ! 535: ! 536: print_stack_frame (selected_frame, selected_frame_level, 1); ! 537: } ! 538: ! 539: static void ! 540: return_command (retval_exp, from_tty) ! 541: char *retval_exp; ! 542: int from_tty; ! 543: { ! 544: struct symbol *thisfun = get_frame_function (selected_frame); ! 545: ! 546: /* If interactive, require confirmation. */ ! 547: ! 548: if (from_tty) ! 549: { ! 550: if (thisfun != 0) ! 551: { ! 552: if (!query ("Make %s return now? ", SYMBOL_NAME (thisfun))) ! 553: error ("Not confirmed."); ! 554: } ! 555: else ! 556: if (!query ("Make selected stack frame return now? ")) ! 557: error ("Not confirmed."); ! 558: } ! 559: ! 560: /* Do the real work. Pop until the specified frame is current. */ ! 561: ! 562: while (selected_frame != get_current_frame ()) ! 563: POP_FRAME; ! 564: ! 565: /* Then pop that frame. */ ! 566: ! 567: POP_FRAME; ! 568: ! 569: /* Compute the return value (if any) and store in the place ! 570: for return values. */ ! 571: ! 572: if (retval_exp) ! 573: set_return_value (parse_and_eval (retval_exp)); ! 574: ! 575: /* If interactive, print the frame that is now current. */ ! 576: ! 577: if (from_tty) ! 578: frame_command ("0", 1); ! 579: } ! 580: ! 581: static ! 582: initialize () ! 583: { ! 584: add_com ("return", class_stack, return_command, ! 585: "Make selected stack frame return to its caller.\n\ ! 586: Control remains in the debugger, but when you continue\n\ ! 587: execution will resume in the frame above the one now selected.\n\ ! 588: If an argument is given, it is an expression for the value to return."); ! 589: ! 590: add_com ("up", class_stack, up_command, ! 591: "Select and print stack frame that called this one.\n\ ! 592: An argument says how many frames up to go."); ! 593: ! 594: add_com ("down", class_stack, down_command, ! 595: "Select and print stack frame called by this one.\n\ ! 596: An argument says how many frames down to go."); ! 597: add_com_alias ("do", "down", class_stack, 1); ! 598: ! 599: add_com ("frame", class_stack, frame_command, ! 600: "Select and print a stack frame.\n\ ! 601: With no argument, print the selected stack frame. (See also \"info frame\").\n\ ! 602: An argument specifies the frame to select.\n\ ! 603: It can be a stack frame number or the address of the frame.\n\ ! 604: With argument, nothing is printed if input is coming from\n\ ! 605: a command file or a user-defined command."); ! 606: ! 607: add_com_alias ("f", "frame", class_stack, 1); ! 608: ! 609: add_com ("backtrace", class_stack, backtrace_command, ! 610: "Print backtrace of all stack frames, or innermost COUNT frames."); ! 611: add_com_alias ("bt", "backtrace", class_stack, 0); ! 612: add_com_alias ("where", "backtrace", class_alias, 0); ! 613: add_info ("stack", backtrace_command, ! 614: "Backtrace of the stack, or innermost COUNT frames."); ! 615: add_info_alias ("s", "stack", 1); ! 616: add_info ("frame", frame_info, ! 617: "All about selected stack frame, or frame at ADDR."); ! 618: add_info_alias ("f", "frame", 1); ! 619: add_info ("locals", locals_info, ! 620: "Local variables of current stack frame."); ! 621: add_info ("args", args_info, ! 622: "Argument variables of current stack frame."); ! 623: } ! 624: ! 625: END_FILE
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.