|
|
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.