7b4ac7e1 |
1 | /* Print and select stack frames for GDB, the GNU debugger. |
e91b87a3 |
2 | Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. |
7b4ac7e1 |
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" |
7b4ac7e1 |
24 | #include "param.h" |
25 | #include "symtab.h" |
26 | #include "frame.h" |
e91b87a3 |
27 | #include "inferior.h" |
28 | #include "gdbcore.h" |
7b4ac7e1 |
29 | |
7b4ac7e1 |
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 | |
e91b87a3 |
42 | /* Error message when selected_frame is zero when it's needed */ |
43 | char no_sel_frame[] = "There is no current stack frame."; |
44 | |
632ea0cc |
45 | /* Nonzero means print the full filename and linenumber |
46 | when a frame is printed, and do so in a format programs can parse. */ |
47 | |
48 | int frame_file_full_name = 0; |
49 | |
7b4ac7e1 |
50 | static void select_calling_frame (); |
51 | |
52 | void print_frame_info (); |
53 | \f |
54 | /* Print a stack frame briefly. FRAME should be the frame address |
55 | and LEVEL should be its level in the stack (or -1 for level not defined). |
56 | This prints the level, the function executing, the arguments, |
57 | and the file name and line number. |
58 | If the pc is not at the beginning of the source line, |
59 | the actual pc is printed at the beginning. |
60 | |
61 | If SOURCE is 1, print the source line as well. |
62 | If SOURCE is -1, print ONLY the source line. */ |
63 | |
e91b87a3 |
64 | /* FIXME, the argument "frame" is always "selected_frame". This is why |
65 | we can say "No selected frame" if it == 0. Probably shouldn't be an |
66 | argument anymore... */ |
67 | |
7b4ac7e1 |
68 | static void |
69 | print_stack_frame (frame, level, source) |
70 | FRAME frame; |
71 | int level; |
72 | int source; |
73 | { |
e91b87a3 |
74 | struct frame_info *fi; |
7b4ac7e1 |
75 | |
e91b87a3 |
76 | if (frame == 0) |
77 | error (no_sel_frame); |
7b4ac7e1 |
78 | fi = get_frame_info (frame); |
79 | |
e91b87a3 |
80 | print_frame_info (fi, level, source, 1); |
7b4ac7e1 |
81 | } |
82 | |
83 | void |
84 | print_frame_info (fi, level, source, args) |
85 | struct frame_info *fi; |
86 | register int level; |
87 | int source; |
88 | int args; |
89 | { |
7b4ac7e1 |
90 | struct symtab_and_line sal; |
91 | struct symbol *func; |
92 | register char *funname = 0; |
93 | int numargs; |
94 | |
95 | sal = find_pc_line (fi->pc, fi->next_frame); |
e91b87a3 |
96 | func = find_pc_function (fi->pc); |
7b4ac7e1 |
97 | if (func) |
98 | funname = SYMBOL_NAME (func); |
99 | else |
100 | { |
101 | register int misc_index = find_pc_misc_function (fi->pc); |
102 | if (misc_index >= 0) |
103 | funname = misc_function_vector[misc_index].name; |
104 | } |
105 | |
106 | if (source >= 0 || !sal.symtab) |
107 | { |
7b4ac7e1 |
108 | if (level >= 0) |
109 | printf ("#%-2d ", level); |
110 | if (fi->pc != sal.pc || !sal.symtab) |
111 | printf ("0x%x in ", fi->pc); |
112 | printf ("%s (", funname ? funname : "??"); |
113 | if (args) |
114 | { |
e91b87a3 |
115 | FRAME_NUM_ARGS (numargs, fi); |
116 | print_frame_args (func, fi, numargs, stdout); |
7b4ac7e1 |
117 | } |
118 | printf (")"); |
119 | if (sal.symtab) |
120 | printf (" (%s line %d)", sal.symtab->filename, sal.line); |
121 | printf ("\n"); |
122 | } |
123 | |
124 | if (source != 0 && sal.symtab) |
125 | { |
632ea0cc |
126 | int done = 0; |
3bf57d21 |
127 | int mid_statement = source < 0 && fi->pc != sal.pc; |
632ea0cc |
128 | if (frame_file_full_name) |
3bf57d21 |
129 | done = identify_source_line (sal.symtab, sal.line, mid_statement); |
632ea0cc |
130 | if (!done) |
3bf57d21 |
131 | { |
132 | if (mid_statement) |
133 | printf ("0x%x\t", fi->pc); |
134 | print_source_lines (sal.symtab, sal.line, sal.line + 1, 1); |
135 | } |
7b4ac7e1 |
136 | current_source_line = max (sal.line - 5, 1); |
137 | } |
138 | if (source != 0) |
139 | set_default_breakpoint (1, fi->pc, sal.symtab, sal.line); |
140 | |
141 | fflush (stdout); |
142 | } |
143 | |
144 | /* Call here to print info on selected frame, after a trap. */ |
145 | |
146 | void |
147 | print_sel_frame (just_source) |
148 | int just_source; |
149 | { |
150 | print_stack_frame (selected_frame, -1, just_source ? -1 : 1); |
151 | } |
152 | |
153 | /* Print info on the selected frame, including level number |
154 | but not source. */ |
155 | |
e91b87a3 |
156 | void |
7b4ac7e1 |
157 | print_selected_frame () |
158 | { |
159 | print_stack_frame (selected_frame, selected_frame_level, 0); |
160 | } |
161 | |
e91b87a3 |
162 | void flush_cached_frames (); /* FIXME, never called! */ |
163 | |
164 | #ifdef FRAME_SPECIFICATION_DYADIC |
165 | extern FRAME setup_arbitrary_frame (); |
166 | #endif |
167 | |
168 | /* |
169 | * Read a frame specification in whatever the appropriate format is. |
170 | */ |
171 | static FRAME |
172 | parse_frame_specification (frame_exp) |
173 | char *frame_exp; |
174 | { |
175 | int numargs = 0; |
176 | int arg1, arg2; |
177 | |
178 | if (frame_exp) |
179 | { |
180 | char *addr_string, *p; |
181 | struct cleanup *tmp_cleanup; |
182 | struct frame_info *fci; |
183 | |
184 | while (*frame_exp == ' ') frame_exp++; |
185 | for (p = frame_exp; *p && *p != ' '; p++) |
186 | ; |
187 | |
188 | if (*frame_exp) |
189 | { |
190 | numargs = 1; |
191 | addr_string = savestring(frame_exp, p - frame_exp); |
192 | |
193 | { |
194 | tmp_cleanup = make_cleanup (free, addr_string); |
195 | arg1 = parse_and_eval_address (addr_string); |
196 | do_cleanups (tmp_cleanup); |
197 | } |
198 | |
199 | while (*p == ' ') p++; |
200 | |
201 | if (*p) |
202 | { |
203 | numargs = 2; |
204 | arg2 = parse_and_eval_address (p); |
205 | } |
206 | } |
207 | } |
208 | |
209 | switch (numargs) |
210 | { |
211 | case 0: |
212 | if (selected_frame == 0) |
213 | error (no_sel_frame); |
214 | return selected_frame; |
215 | /* NOTREACHED */ |
216 | case 1: |
217 | { |
218 | int level = arg1; |
219 | FRAME fid = find_relative_frame (get_current_frame (), &level); |
220 | FRAME tfid; |
221 | |
222 | if (level == 0) |
223 | /* find_relative_frame was successful */ |
224 | return fid; |
225 | |
226 | /* If (s)he specifies the frame with an address, he deserves what |
227 | (s)he gets. Still, give the highest one that matches. */ |
228 | |
229 | for (fid = get_current_frame (); |
230 | fid && FRAME_FP (fid) != arg1; |
231 | fid = get_prev_frame (fid)) |
232 | ; |
233 | |
234 | if (fid) |
235 | while ((tfid = get_prev_frame (fid)) && |
236 | (FRAME_FP (tfid) == arg1)) |
237 | fid = tfid; |
238 | |
239 | #ifdef FRAME_SPECIFICATION_DYADIC |
240 | if (!fid) |
241 | error ("Incorrect number of args in frame specification"); |
242 | |
243 | return fid; |
244 | #else |
245 | return create_new_frame (arg1, 0); |
246 | #endif |
247 | } |
248 | /* NOTREACHED */ |
249 | case 2: |
250 | /* Must be addresses */ |
251 | #ifndef FRAME_SPECIFICATION_DYADIC |
252 | error ("Incorrect number of args in frame specification"); |
253 | #else |
254 | return setup_arbitrary_frame (arg1, arg2); |
255 | #endif |
256 | /* NOTREACHED */ |
257 | } |
258 | fatal ("Internal: Error in parsing in parse_frame_specification"); |
259 | /* NOTREACHED */ |
260 | } |
261 | |
7b4ac7e1 |
262 | /* Print verbosely the selected frame or the frame at address ADDR. |
263 | This means absolutely all information in the frame is printed. */ |
264 | |
265 | static void |
266 | frame_info (addr_exp) |
267 | char *addr_exp; |
268 | { |
e91b87a3 |
269 | FRAME frame; |
270 | struct frame_info *fi; |
7b4ac7e1 |
271 | struct frame_saved_regs fsr; |
272 | struct symtab_and_line sal; |
273 | struct symbol *func; |
274 | FRAME calling_frame; |
275 | int i, count; |
276 | char *funname = 0; |
277 | int numargs; |
278 | |
e91b87a3 |
279 | frame = parse_frame_specification (addr_exp); |
280 | |
7b4ac7e1 |
281 | fi = get_frame_info (frame); |
e91b87a3 |
282 | get_frame_saved_regs (fi, &fsr); |
283 | sal = find_pc_line (fi->pc, fi->next_frame); |
7b4ac7e1 |
284 | func = get_frame_function (frame); |
285 | if (func) |
286 | funname = SYMBOL_NAME (func); |
287 | else |
288 | { |
e91b87a3 |
289 | register int misc_index = find_pc_misc_function (fi->pc); |
7b4ac7e1 |
290 | if (misc_index >= 0) |
291 | funname = misc_function_vector[misc_index].name; |
292 | } |
293 | calling_frame = get_prev_frame (frame); |
294 | |
295 | if (!addr_exp && selected_frame_level >= 0) |
296 | printf ("Stack level %d, frame at 0x%x:\n pc = 0x%x", |
e91b87a3 |
297 | selected_frame_level, FRAME_FP(frame), fi->pc); |
7b4ac7e1 |
298 | else |
299 | printf ("Stack frame at 0x%x:\n pc = 0x%x", |
e91b87a3 |
300 | FRAME_FP(frame), fi->pc); |
7b4ac7e1 |
301 | |
302 | if (funname) |
303 | printf (" in %s", funname); |
304 | if (sal.symtab) |
305 | printf (" (%s line %d)", sal.symtab->filename, sal.line); |
e91b87a3 |
306 | printf ("; saved pc 0x%x\n", FRAME_SAVED_PC (frame)); |
7b4ac7e1 |
307 | if (calling_frame) |
e91b87a3 |
308 | printf (" called by frame at 0x%x", FRAME_FP (calling_frame)); |
309 | if (fi->next_frame && calling_frame) |
7b4ac7e1 |
310 | printf (","); |
e91b87a3 |
311 | if (fi->next_frame) |
312 | printf (" caller of frame at 0x%x", fi->next_frame); |
313 | if (fi->next_frame || calling_frame) |
7b4ac7e1 |
314 | printf ("\n"); |
315 | printf (" Arglist at 0x%x,", FRAME_ARGS_ADDRESS (fi)); |
316 | FRAME_NUM_ARGS (i, fi); |
317 | if (i < 0) |
318 | printf (" args: "); |
319 | else if (i == 0) |
320 | printf (" no args."); |
321 | else if (i == 1) |
322 | printf (" 1 arg: "); |
323 | else |
324 | printf (" %d args: ", i); |
325 | |
326 | FRAME_NUM_ARGS (numargs, fi); |
e91b87a3 |
327 | print_frame_args (func, fi, numargs, stdout); |
7b4ac7e1 |
328 | printf ("\n"); |
329 | count = 0; |
330 | for (i = 0; i < NUM_REGS; i++) |
331 | if (fsr.regs[i]) |
332 | { |
333 | if (count % 4 != 0) |
334 | printf (", "); |
335 | else |
336 | { |
337 | if (count == 0) |
338 | printf (" Saved registers:"); |
339 | printf ("\n "); |
340 | } |
341 | printf ("%s at 0x%x", reg_names[i], fsr.regs[i]); |
342 | count++; |
343 | } |
344 | if (count) |
345 | printf ("\n"); |
346 | } |
347 | |
e91b87a3 |
348 | #if 0 |
349 | /* Set a limit on the number of frames printed by default in a |
350 | backtrace. */ |
351 | |
352 | static int backtrace_limit; |
353 | |
354 | static void |
355 | set_backtrace_limit_command (count_exp, from_tty) |
356 | char *count_exp; |
357 | int from_tty; |
358 | { |
359 | int count = parse_and_eval_address (count_exp); |
360 | |
361 | if (count < 0) |
362 | error ("Negative argument not meaningful as backtrace limit."); |
363 | |
364 | backtrace_limit = count; |
365 | } |
366 | |
367 | static void |
368 | backtrace_limit_info (arg, from_tty) |
369 | char *arg; |
370 | int from_tty; |
371 | { |
372 | if (arg) |
373 | error ("\"Info backtrace-limit\" takes no arguments."); |
374 | |
375 | printf ("Backtrace limit: %d.\n", backtrace_limit); |
376 | } |
377 | #endif |
378 | |
7b4ac7e1 |
379 | /* Print briefly all stack frames or just the innermost COUNT frames. */ |
380 | |
381 | static void |
382 | backtrace_command (count_exp) |
383 | char *count_exp; |
384 | { |
e91b87a3 |
385 | struct frame_info *fi; |
7b4ac7e1 |
386 | register int count; |
387 | register FRAME frame; |
388 | register int i; |
e91b87a3 |
389 | register FRAME trailing; |
390 | register int trailing_level; |
391 | |
392 | if (have_inferior_p () == 0 && corefile == 0) |
393 | error ("There is no running program or core file."); |
394 | |
395 | /* The following code must do two things. First, it must |
396 | set the variable TRAILING to the frame from which we should start |
397 | printing. Second, it must set the variable count to the number |
398 | of frames which we should print, or -1 if all of them. */ |
399 | trailing = get_current_frame (); |
400 | trailing_level = 0; |
7b4ac7e1 |
401 | if (count_exp) |
e91b87a3 |
402 | { |
403 | count = parse_and_eval_address (count_exp); |
404 | if (count < 0) |
405 | { |
406 | FRAME current; |
407 | |
408 | count = -count; |
409 | |
410 | current = trailing; |
411 | while (current && count--) |
412 | current = get_prev_frame (current); |
413 | |
414 | /* Will stop when CURRENT reaches the top of the stack. TRAILING |
415 | will be COUNT below it. */ |
416 | while (current) |
417 | { |
418 | trailing = get_prev_frame (trailing); |
419 | current = get_prev_frame (current); |
420 | trailing_level++; |
421 | } |
422 | |
423 | count = -1; |
424 | } |
425 | } |
7b4ac7e1 |
426 | else |
e91b87a3 |
427 | #if 0 |
428 | count = backtrace_limit; |
429 | #else |
7b4ac7e1 |
430 | count = -1; |
e91b87a3 |
431 | #endif |
7b4ac7e1 |
432 | |
e91b87a3 |
433 | for (i = 0, frame = trailing; |
7b4ac7e1 |
434 | frame && count--; |
e91b87a3 |
435 | i++, frame = get_prev_frame (frame)) |
7b4ac7e1 |
436 | { |
437 | QUIT; |
e91b87a3 |
438 | fi = get_frame_info (frame); |
439 | print_frame_info (fi, trailing_level + i, 0, 1); |
7b4ac7e1 |
440 | } |
e91b87a3 |
441 | |
442 | /* If we've stopped before the end, mention that. */ |
443 | if (frame) |
444 | printf ("(More stack frames follow...)\n"); |
7b4ac7e1 |
445 | } |
446 | \f |
447 | /* Print the local variables of a block B active in FRAME. */ |
448 | |
449 | static void |
450 | print_block_frame_locals (b, frame, stream) |
451 | struct block *b; |
452 | register FRAME frame; |
453 | register FILE *stream; |
454 | { |
455 | int nsyms; |
456 | register int i; |
457 | register struct symbol *sym; |
458 | |
459 | nsyms = BLOCK_NSYMS (b); |
460 | |
461 | for (i = 0; i < nsyms; i++) |
462 | { |
463 | sym = BLOCK_SYM (b, i); |
464 | if (SYMBOL_CLASS (sym) == LOC_LOCAL |
3bf57d21 |
465 | || SYMBOL_CLASS (sym) == LOC_REGISTER |
466 | || SYMBOL_CLASS (sym) == LOC_STATIC) |
7b4ac7e1 |
467 | { |
468 | fprintf (stream, "%s = ", SYMBOL_NAME (sym)); |
469 | print_variable_value (sym, frame, stream); |
470 | fprintf (stream, "\n"); |
471 | fflush (stream); |
472 | } |
473 | } |
474 | } |
475 | |
476 | /* Print on STREAM all the local variables in frame FRAME, |
477 | including all the blocks active in that frame |
478 | at its current pc. |
479 | |
480 | Returns 1 if the job was done, |
481 | or 0 if nothing was printed because we have no info |
482 | on the function running in FRAME. */ |
483 | |
484 | static int |
485 | print_frame_local_vars (frame, stream) |
486 | register FRAME frame; |
487 | register FILE *stream; |
488 | { |
e91b87a3 |
489 | register struct block *block; |
490 | |
491 | block = get_frame_block (frame); |
7b4ac7e1 |
492 | if (block == 0) |
493 | return 0; |
494 | while (block != 0) |
495 | { |
496 | print_block_frame_locals (block, frame, stream); |
497 | /* After handling the function's top-level block, stop. |
498 | Don't continue to its superblock, the block of |
499 | per-file symbols. */ |
500 | if (BLOCK_FUNCTION (block)) |
501 | break; |
502 | block = BLOCK_SUPERBLOCK (block); |
503 | } |
504 | return 1; |
505 | } |
506 | |
507 | static void |
508 | locals_info () |
509 | { |
e91b87a3 |
510 | if (selected_frame == 0) |
511 | error(no_sel_frame); |
7b4ac7e1 |
512 | print_frame_local_vars (selected_frame, stdout); |
513 | } |
514 | |
515 | static int |
516 | print_frame_arg_vars (frame, stream) |
517 | register FRAME frame; |
518 | register FILE *stream; |
519 | { |
e91b87a3 |
520 | struct symbol *func; |
7b4ac7e1 |
521 | register struct block *b; |
522 | int nsyms; |
523 | register int i; |
524 | register struct symbol *sym; |
525 | |
e91b87a3 |
526 | func = get_frame_function (frame); |
7b4ac7e1 |
527 | if (func == 0) |
528 | return 0; |
529 | |
530 | b = SYMBOL_BLOCK_VALUE (func); |
531 | nsyms = BLOCK_NSYMS (b); |
532 | |
533 | for (i = 0; i < nsyms; i++) |
534 | { |
535 | sym = BLOCK_SYM (b, i); |
bb7592f0 |
536 | if (SYMBOL_CLASS (sym) == LOC_ARG || SYMBOL_CLASS (sym) == LOC_REGPARM) |
7b4ac7e1 |
537 | { |
538 | fprintf (stream, "%s = ", SYMBOL_NAME (sym)); |
539 | print_variable_value (sym, frame, stream); |
540 | fprintf (stream, "\n"); |
541 | fflush (stream); |
542 | } |
543 | } |
544 | |
545 | return 1; |
546 | } |
547 | |
548 | static void |
549 | args_info () |
550 | { |
e91b87a3 |
551 | if (selected_frame == 0) |
552 | error(no_sel_frame); |
7b4ac7e1 |
553 | print_frame_arg_vars (selected_frame, stdout); |
554 | } |
555 | \f |
556 | /* Select frame FRAME, and note that its stack level is LEVEL. |
557 | LEVEL may be -1 if an actual level number is not known. */ |
558 | |
559 | void |
560 | select_frame (frame, level) |
561 | FRAME frame; |
562 | int level; |
563 | { |
564 | selected_frame = frame; |
565 | selected_frame_level = level; |
566 | } |
567 | |
568 | /* Store the selected frame and its level into *FRAMEP and *LEVELP. */ |
569 | |
570 | void |
e91b87a3 |
571 | record_selected_frame (frameaddrp, levelp) |
572 | FRAME_ADDR *frameaddrp; |
7b4ac7e1 |
573 | int *levelp; |
574 | { |
e91b87a3 |
575 | *frameaddrp = FRAME_FP (selected_frame); |
7b4ac7e1 |
576 | *levelp = selected_frame_level; |
577 | } |
578 | |
579 | /* Return the symbol-block in which the selected frame is executing. |
580 | Can return zero under various legitimate circumstances. */ |
581 | |
582 | struct block * |
583 | get_selected_block () |
584 | { |
585 | if (!have_inferior_p () && !have_core_file_p ()) |
586 | return 0; |
587 | |
588 | if (!selected_frame) |
589 | return get_current_block (); |
590 | return get_frame_block (selected_frame); |
591 | } |
592 | |
593 | /* Find a frame a certain number of levels away from FRAME. |
594 | LEVEL_OFFSET_PTR points to an int containing the number of levels. |
595 | Positive means go to earlier frames (up); negative, the reverse. |
596 | The int that contains the number of levels is counted toward |
597 | zero as the frames for those levels are found. |
598 | If the top or bottom frame is reached, that frame is returned, |
599 | but the final value of *LEVEL_OFFSET_PTR is nonzero and indicates |
600 | how much farther the original request asked to go. */ |
601 | |
602 | FRAME |
603 | find_relative_frame (frame, level_offset_ptr) |
604 | register FRAME frame; |
605 | register int* level_offset_ptr; |
606 | { |
607 | register FRAME prev; |
7b4ac7e1 |
608 | register FRAME frame1, frame2; |
609 | |
e91b87a3 |
610 | if (frame == 0) |
611 | error (no_sel_frame); |
7b4ac7e1 |
612 | /* Going up is simple: just do get_prev_frame enough times |
613 | or until initial frame is reached. */ |
614 | while (*level_offset_ptr > 0) |
615 | { |
616 | prev = get_prev_frame (frame); |
617 | if (prev == 0) |
618 | break; |
619 | (*level_offset_ptr)--; |
620 | frame = prev; |
621 | } |
622 | /* Going down could be done by iterating get_frame_info to |
623 | find the next frame, but that would be quadratic |
624 | since get_frame_info must scan all the way from the current frame. |
bb7592f0 |
625 | The following algorithm is linear. */ |
7b4ac7e1 |
626 | if (*level_offset_ptr < 0) |
627 | { |
628 | /* First put frame1 at innermost frame |
629 | and frame2 N levels up from there. */ |
630 | frame1 = get_current_frame (); |
631 | frame2 = frame1; |
632 | while (*level_offset_ptr < 0 && frame2 != frame) |
633 | { |
634 | frame2 = get_prev_frame (frame2); |
635 | (*level_offset_ptr) ++; |
636 | } |
637 | /* Then slide frame1 and frame2 up in synchrony |
638 | and when frame2 reaches our starting point |
639 | frame1 must be N levels down from there. */ |
640 | while (frame2 != frame) |
641 | { |
642 | frame1 = get_prev_frame (frame1); |
643 | frame2 = get_prev_frame (frame2); |
644 | } |
645 | return frame1; |
646 | } |
647 | return frame; |
648 | } |
649 | |
650 | /* The "frame" command. With no arg, print selected frame briefly. |
e91b87a3 |
651 | With arg LEVEL_EXP, select the frame at level LEVEL if it is a |
652 | valid level. Otherwise, treat level_exp as an address expression |
653 | and print it. See parse_frame_specification for more info on proper |
654 | frame expressions. */ |
7b4ac7e1 |
655 | |
656 | static void |
657 | frame_command (level_exp, from_tty) |
658 | char *level_exp; |
659 | int from_tty; |
660 | { |
e91b87a3 |
661 | register FRAME frame, frame1; |
662 | unsigned int level = 0; |
7b4ac7e1 |
663 | |
e91b87a3 |
664 | frame = parse_frame_specification (level_exp); |
7b4ac7e1 |
665 | |
e91b87a3 |
666 | for (frame1 = get_prev_frame (0); |
667 | frame1 && frame1 != frame; |
668 | frame1 = get_prev_frame (frame1)) |
669 | level++; |
670 | |
671 | if (!frame1) |
672 | level = 0; |
673 | |
674 | select_frame (frame, level); |
675 | |
676 | if (!from_tty) |
677 | return; |
7b4ac7e1 |
678 | |
679 | print_stack_frame (selected_frame, selected_frame_level, 1); |
680 | } |
681 | |
682 | /* Select the frame up one or COUNT stack levels |
683 | from the previously selected frame, and print it briefly. */ |
684 | |
685 | static void |
686 | up_command (count_exp) |
687 | char *count_exp; |
688 | { |
689 | register FRAME frame; |
690 | int count = 1, count1; |
691 | if (count_exp) |
692 | count = parse_and_eval_address (count_exp); |
693 | count1 = count; |
694 | |
695 | frame = find_relative_frame (selected_frame, &count1); |
696 | if (count1 != 0 && count_exp == 0) |
697 | error ("Initial frame selected; you cannot go up."); |
698 | select_frame (frame, selected_frame_level + count - count1); |
699 | |
700 | print_stack_frame (selected_frame, selected_frame_level, 1); |
701 | } |
702 | |
703 | /* Select the frame down one or COUNT stack levels |
704 | from the previously selected frame, and print it briefly. */ |
705 | |
706 | static void |
707 | down_command (count_exp) |
708 | char *count_exp; |
709 | { |
710 | register FRAME frame; |
711 | int count = -1, count1; |
712 | if (count_exp) |
713 | count = - parse_and_eval_address (count_exp); |
714 | count1 = count; |
715 | |
716 | frame = find_relative_frame (selected_frame, &count1); |
717 | if (count1 != 0 && count_exp == 0) |
718 | error ("Bottom (i.e., innermost) frame selected; you cannot go down."); |
719 | select_frame (frame, selected_frame_level + count - count1); |
720 | |
721 | print_stack_frame (selected_frame, selected_frame_level, 1); |
722 | } |
723 | \f |
724 | static void |
725 | return_command (retval_exp, from_tty) |
726 | char *retval_exp; |
727 | int from_tty; |
728 | { |
729 | struct symbol *thisfun = get_frame_function (selected_frame); |
730 | |
731 | /* If interactive, require confirmation. */ |
732 | |
733 | if (from_tty) |
734 | { |
735 | if (thisfun != 0) |
736 | { |
737 | if (!query ("Make %s return now? ", SYMBOL_NAME (thisfun))) |
738 | error ("Not confirmed."); |
739 | } |
740 | else |
741 | if (!query ("Make selected stack frame return now? ")) |
742 | error ("Not confirmed."); |
743 | } |
744 | |
745 | /* Do the real work. Pop until the specified frame is current. */ |
746 | |
747 | while (selected_frame != get_current_frame ()) |
748 | POP_FRAME; |
749 | |
750 | /* Then pop that frame. */ |
751 | |
752 | POP_FRAME; |
753 | |
754 | /* Compute the return value (if any) and store in the place |
755 | for return values. */ |
756 | |
757 | if (retval_exp) |
758 | set_return_value (parse_and_eval (retval_exp)); |
759 | |
760 | /* If interactive, print the frame that is now current. */ |
761 | |
762 | if (from_tty) |
763 | frame_command ("0", 1); |
764 | } |
765 | \f |
e91b87a3 |
766 | extern struct cmd_list_element *setlist; |
767 | |
768 | void |
769 | _initialize_stack () |
7b4ac7e1 |
770 | { |
e91b87a3 |
771 | #if 0 |
772 | backtrace_limit = 30; |
773 | #endif |
774 | |
7b4ac7e1 |
775 | add_com ("return", class_stack, return_command, |
776 | "Make selected stack frame return to its caller.\n\ |
777 | Control remains in the debugger, but when you continue\n\ |
778 | execution will resume in the frame above the one now selected.\n\ |
779 | If an argument is given, it is an expression for the value to return."); |
780 | |
781 | add_com ("up", class_stack, up_command, |
782 | "Select and print stack frame that called this one.\n\ |
783 | An argument says how many frames up to go."); |
784 | |
785 | add_com ("down", class_stack, down_command, |
786 | "Select and print stack frame called by this one.\n\ |
787 | An argument says how many frames down to go."); |
788 | add_com_alias ("do", "down", class_stack, 1); |
789 | |
790 | add_com ("frame", class_stack, frame_command, |
791 | "Select and print a stack frame.\n\ |
792 | With no argument, print the selected stack frame. (See also \"info frame\").\n\ |
793 | An argument specifies the frame to select.\n\ |
794 | It can be a stack frame number or the address of the frame.\n\ |
795 | With argument, nothing is printed if input is coming from\n\ |
796 | a command file or a user-defined command."); |
797 | |
798 | add_com_alias ("f", "frame", class_stack, 1); |
799 | |
800 | add_com ("backtrace", class_stack, backtrace_command, |
e91b87a3 |
801 | "Print backtrace of all stack frames, or innermost COUNT frames.\n\ |
802 | With a negative argument, print outermost -COUNT frames."); |
7b4ac7e1 |
803 | add_com_alias ("bt", "backtrace", class_stack, 0); |
804 | add_com_alias ("where", "backtrace", class_alias, 0); |
805 | add_info ("stack", backtrace_command, |
806 | "Backtrace of the stack, or innermost COUNT frames."); |
807 | add_info_alias ("s", "stack", 1); |
808 | add_info ("frame", frame_info, |
809 | "All about selected stack frame, or frame at ADDR."); |
810 | add_info_alias ("f", "frame", 1); |
811 | add_info ("locals", locals_info, |
812 | "Local variables of current stack frame."); |
813 | add_info ("args", args_info, |
814 | "Argument variables of current stack frame."); |
e91b87a3 |
815 | |
816 | #if 0 |
817 | add_cmd ("backtrace-limit", class_stack, set_backtrace_limit_command, |
818 | "Specify maximum number of frames for \"backtrace\" to print by default.", |
819 | &setlist); |
820 | add_info ("backtrace-limit", backtrace_limit_info, |
821 | "The maximum number of frames for \"backtrace\" to print by default."); |
822 | #endif |
7b4ac7e1 |
823 | } |
824 | |