Commit | Line | Data |
---|---|---|
af359dea C |
1 | /*- |
2 | * This code is derived from software copyrighted by the Free Software | |
3 | * Foundation. | |
4 | * | |
5 | * Modified 1991 by Donn Seeley at UUNET Technologies, Inc. | |
6 | * Modified 1990 by Van Jacobson at Lawrence Berkeley Laboratory. | |
7 | */ | |
8 | ||
9 | #ifndef lint | |
10 | static char sccsid[] = "@(#)stack.c 6.3 (Berkeley) 5/8/91"; | |
11 | #endif /* not lint */ | |
12 | ||
13 | /* Print and select stack frames for GDB, the GNU debugger. | |
14 | Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. | |
15 | ||
16 | This file is part of GDB. | |
17 | ||
18 | GDB is free software; you can redistribute it and/or modify | |
19 | it under the terms of the GNU General Public License as published by | |
20 | the Free Software Foundation; either version 1, or (at your option) | |
21 | any later version. | |
22 | ||
23 | GDB is distributed in the hope that it will be useful, | |
24 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
25 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
26 | GNU General Public License for more details. | |
27 | ||
28 | You should have received a copy of the GNU General Public License | |
29 | along with GDB; see the file COPYING. If not, write to | |
30 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
31 | ||
32 | /* modified by rjc Thu Nov 1 16:46:57 1990, fixed return_command so that | |
33 | it can return values, it still has problems when running on pmax, | |
34 | cannot write register 65 */ | |
35 | ||
36 | #include <stdio.h> | |
37 | ||
38 | #include "defs.h" | |
39 | #include "param.h" | |
40 | #include "symtab.h" | |
41 | #include "frame.h" | |
42 | #include "value.h" | |
43 | ||
44 | ||
45 | /* Thie "selected" stack frame is used by default for local and arg access. | |
46 | May be zero, for no selected frame. */ | |
47 | ||
48 | FRAME selected_frame; | |
49 | ||
50 | /* Level of the selected frame: | |
51 | 0 for innermost, 1 for its caller, ... | |
52 | or -1 for frame specified by address with no defined level. */ | |
53 | ||
54 | int selected_frame_level; | |
55 | ||
56 | /* Nonzero means print the full filename and linenumber | |
57 | when a frame is printed, and do so in a format programs can parse. */ | |
58 | ||
59 | int frame_file_full_name = 0; | |
60 | ||
61 | static void select_calling_frame (); | |
62 | ||
63 | void print_frame_info (); | |
64 | \f | |
65 | /* Print a stack frame briefly. FRAME should be the frame id | |
66 | and LEVEL should be its level in the stack (or -1 for level not defined). | |
67 | This prints the level, the function executing, the arguments, | |
68 | and the file name and line number. | |
69 | If the pc is not at the beginning of the source line, | |
70 | the actual pc is printed at the beginning. | |
71 | ||
72 | If SOURCE is 1, print the source line as well. | |
73 | If SOURCE is -1, print ONLY the source line. */ | |
74 | ||
75 | static void | |
76 | print_stack_frame (frame, level, source) | |
77 | FRAME frame; | |
78 | int level; | |
79 | int source; | |
80 | { | |
81 | struct frame_info *fi; | |
82 | ||
83 | fi = get_frame_info (frame); | |
84 | ||
85 | print_frame_info (fi, level, source, 1); | |
86 | } | |
87 | ||
88 | /* Flag which will indicate when the frame has been changed | |
89 | by and "up" or "down" command. */ | |
90 | static int frame_changed; | |
91 | ||
92 | void | |
93 | print_frame_info (fi, level, source, args) | |
94 | struct frame_info *fi; | |
95 | register int level; | |
96 | int source; | |
97 | int args; | |
98 | { | |
99 | struct symtab_and_line sal; | |
100 | struct symbol *func; | |
101 | register char *funname = 0; | |
102 | int numargs; | |
103 | struct partial_symtab *pst; | |
104 | ||
105 | /* Don't give very much information if we haven't readin the | |
106 | symbol table yet. */ | |
107 | pst = find_pc_psymtab (fi->pc); | |
108 | if (pst && !pst->readin) | |
109 | { | |
110 | /* Abbreviated information. */ | |
111 | char *fname; | |
112 | ||
113 | if (!find_pc_partial_function (fi->pc, &fname, 0)) | |
114 | fname = "??"; | |
115 | ||
116 | printf_filtered ("#%-2d ", level); | |
117 | printf_filtered ("0x%x in ", fi->pc); | |
118 | ||
119 | fputs_demangled(fname, stdout, -1); | |
120 | fputs_filtered(" (...)\n", stdout); | |
121 | ||
122 | return; | |
123 | } | |
124 | ||
125 | sal = find_pc_line (fi->pc, fi->next_frame); | |
126 | func = find_pc_function (fi->pc); | |
127 | if (func) | |
128 | { | |
129 | /* In certain pathological cases, the symtabs give the wrong | |
130 | function (when we are in the first function in a file which | |
131 | is compiled without debugging symbols, the previous function | |
132 | is compiled with debugging symbols, and the "foo.o" symbol | |
133 | that is supposed to tell us where the file with debugging symbols | |
134 | ends has been truncated by ar because it is longer than 15 | |
135 | characters). | |
136 | ||
137 | So look in the misc_function_vector as well, and if it comes | |
138 | up with a larger address for the function use that instead. | |
139 | I don't think this can ever cause any problems; | |
140 | there shouldn't be any | |
141 | misc_function_vector symbols in the middle of a function. */ | |
142 | int misc_index = find_pc_misc_function (fi->pc); | |
143 | if (misc_index >= 0 | |
144 | && (misc_function_vector[misc_index].address | |
145 | > BLOCK_START (SYMBOL_BLOCK_VALUE (func)))) | |
146 | { | |
147 | /* In this case we have no way of knowing the source file | |
148 | and line number, so don't print them. */ | |
149 | sal.symtab = 0; | |
150 | /* We also don't know anything about the function besides | |
151 | its address and name. */ | |
152 | func = 0; | |
153 | funname = misc_function_vector[misc_index].name; | |
154 | } | |
155 | else | |
156 | funname = SYMBOL_NAME (func); | |
157 | } | |
158 | else | |
159 | { | |
160 | register int misc_index = find_pc_misc_function (fi->pc); | |
161 | if (misc_index >= 0) | |
162 | funname = misc_function_vector[misc_index].name; | |
163 | } | |
164 | ||
165 | if (frame_changed || source >= 0 || !sal.symtab) | |
166 | { | |
167 | if (level >= 0) | |
168 | printf_filtered ("#%-2d ", level); | |
169 | else if (frame_changed) | |
170 | printf ("#%-2d ", 0); | |
171 | if (fi->pc != sal.pc || !sal.symtab) | |
172 | printf_filtered ("0x%x in ", fi->pc); | |
173 | fputs_demangled(funname ? funname : "??", stdout, -1); | |
174 | printf_filtered(" ("); | |
175 | if (args) | |
176 | { | |
177 | if (func) | |
178 | numargs = -1; | |
179 | else | |
180 | FRAME_NUM_ARGS (numargs, fi); | |
181 | ||
182 | print_frame_args (func, fi, numargs, stdout); | |
183 | } | |
184 | printf_filtered (")"); | |
185 | if (sal.symtab) | |
186 | printf_filtered (" (%s line %d)", sal.symtab->filename, sal.line); | |
187 | printf_filtered ("\n"); | |
188 | } | |
189 | ||
190 | if ((frame_changed || source != 0) && sal.symtab) | |
191 | { | |
192 | int done = 0; | |
193 | int mid_statement = source < 0 && fi->pc != sal.pc; | |
194 | if (frame_file_full_name) | |
195 | done = identify_source_line (sal.symtab, sal.line, mid_statement); | |
196 | if (!done) | |
197 | { | |
198 | if (mid_statement) | |
199 | printf_filtered ("0x%x\t", fi->pc); | |
200 | print_source_lines (sal.symtab, sal.line, sal.line + 1, 1); | |
201 | } | |
202 | current_source_line = max (sal.line - 5, 1); | |
203 | } | |
204 | frame_changed = 0; | |
205 | if (source != 0) | |
206 | set_default_breakpoint (1, fi->pc, sal.symtab, sal.line); | |
207 | ||
208 | fflush (stdout); | |
209 | } | |
210 | ||
211 | /* Call here to print info on selected frame, after a trap. */ | |
212 | ||
213 | void | |
214 | print_sel_frame (just_source) | |
215 | int just_source; | |
216 | { | |
217 | print_stack_frame (selected_frame, -1, just_source ? -1 : 1); | |
218 | } | |
219 | ||
220 | /* Print info on the selected frame, including level number | |
221 | but not source. */ | |
222 | ||
223 | void | |
224 | print_selected_frame () | |
225 | { | |
226 | print_stack_frame (selected_frame, selected_frame_level, 0); | |
227 | } | |
228 | ||
229 | void flush_cached_frames (); | |
230 | ||
231 | #ifdef FRAME_SPECIFICATION_DYADIC | |
232 | extern FRAME setup_arbitrary_frame (); | |
233 | #endif | |
234 | ||
235 | /* | |
236 | * Read a frame specification in whatever the appropriate format is. | |
237 | */ | |
238 | static FRAME | |
239 | parse_frame_specification (frame_exp) | |
240 | char *frame_exp; | |
241 | { | |
242 | int numargs = 0; | |
243 | int arg1, arg2; | |
244 | ||
245 | if (frame_exp) | |
246 | { | |
247 | char *addr_string, *p; | |
248 | struct cleanup *tmp_cleanup; | |
249 | struct frame_info *fci; | |
250 | ||
251 | while (*frame_exp == ' ') frame_exp++; | |
252 | for (p = frame_exp; *p && *p != ' '; p++) | |
253 | ; | |
254 | ||
255 | if (*frame_exp) | |
256 | { | |
257 | numargs = 1; | |
258 | addr_string = savestring(frame_exp, p - frame_exp); | |
259 | ||
260 | { | |
261 | tmp_cleanup = make_cleanup (free, addr_string); | |
262 | arg1 = parse_and_eval_address (addr_string); | |
263 | do_cleanups (tmp_cleanup); | |
264 | } | |
265 | ||
266 | while (*p == ' ') p++; | |
267 | ||
268 | if (*p) | |
269 | { | |
270 | numargs = 2; | |
271 | arg2 = parse_and_eval_address (p); | |
272 | } | |
273 | } | |
274 | } | |
275 | ||
276 | switch (numargs) | |
277 | { | |
278 | case 0: | |
279 | return selected_frame; | |
280 | /* NOTREACHED */ | |
281 | case 1: | |
282 | { | |
283 | int level = arg1; | |
284 | FRAME fid = find_relative_frame (get_current_frame (), &level); | |
285 | FRAME tfid; | |
286 | ||
287 | if (level == 0) | |
288 | /* find_relative_frame was successful */ | |
289 | return fid; | |
290 | ||
291 | /* If (s)he specifies the frame with an address, he deserves what | |
292 | (s)he gets. Still, give the highest one that matches. */ | |
293 | ||
294 | for (fid = get_current_frame (); | |
295 | fid && FRAME_FP (fid) != arg1; | |
296 | fid = get_prev_frame (fid)) | |
297 | ; | |
298 | ||
299 | if (fid) | |
300 | while ((tfid = get_prev_frame (fid)) && | |
301 | (FRAME_FP (tfid) == arg1)) | |
302 | fid = tfid; | |
303 | ||
304 | #ifdef FRAME_SPECIFICATION_DYADIC | |
305 | if (!fid) | |
306 | error ("Incorrect number of args in frame specification"); | |
307 | ||
308 | return fid; | |
309 | #else | |
310 | return create_new_frame (arg1, 0); | |
311 | #endif | |
312 | } | |
313 | /* NOTREACHED */ | |
314 | case 2: | |
315 | /* Must be addresses */ | |
316 | #ifndef FRAME_SPECIFICATION_DYADIC | |
317 | error ("Incorrect number of args in frame specification"); | |
318 | #else | |
319 | return setup_arbitrary_frame (arg1, arg2); | |
320 | #endif | |
321 | /* NOTREACHED */ | |
322 | } | |
323 | fatal ("Internal: Error in parsing in parse_frame_specification"); | |
324 | /* NOTREACHED */ | |
325 | } | |
326 | ||
327 | /* FRAME_ARGS_ADDRESS_CORRECT is just like FRAME_ARGS_ADDRESS except | |
328 | that if it is unsure about the answer, it returns Frame_unknown | |
329 | instead of guessing (this happens on the VAX, for example). | |
330 | ||
331 | On most machines, we never have to guess about the args address, | |
332 | so FRAME_ARGS_ADDRESS{,_CORRECT} are the same. */ | |
333 | #if !defined (FRAME_ARGS_ADDRESS_CORRECT) | |
334 | #define FRAME_ARGS_ADDRESS_CORRECT FRAME_ARGS_ADDRESS | |
335 | #endif | |
336 | ||
337 | /* Print verbosely the selected frame or the frame at address ADDR. | |
338 | This means absolutely all information in the frame is printed. */ | |
339 | ||
340 | static void | |
341 | frame_info (addr_exp) | |
342 | char *addr_exp; | |
343 | { | |
344 | FRAME frame; | |
345 | struct frame_info *fi; | |
346 | struct frame_saved_regs fsr; | |
347 | struct symtab_and_line sal; | |
348 | struct symbol *func; | |
349 | FRAME calling_frame; | |
350 | int i, count; | |
351 | char *funname = 0; | |
352 | ||
353 | if (!(have_inferior_p () || have_core_file_p ())) | |
354 | error ("No inferior or core file."); | |
355 | ||
356 | frame = parse_frame_specification (addr_exp); | |
357 | if (!frame) | |
358 | error ("Invalid frame specified."); | |
359 | ||
360 | fi = get_frame_info (frame); | |
361 | get_frame_saved_regs (fi, &fsr); | |
362 | sal = find_pc_line (fi->pc, fi->next_frame); | |
363 | func = get_frame_function (frame); | |
364 | if (func) | |
365 | funname = SYMBOL_NAME (func); | |
366 | else | |
367 | { | |
368 | register int misc_index = find_pc_misc_function (fi->pc); | |
369 | if (misc_index >= 0) | |
370 | funname = misc_function_vector[misc_index].name; | |
371 | } | |
372 | calling_frame = get_prev_frame (frame); | |
373 | ||
374 | if (!addr_exp && selected_frame_level >= 0) | |
375 | printf ("Stack level %d, frame at 0x%x:\n pc = 0x%x", | |
376 | selected_frame_level, FRAME_FP(frame), fi->pc); | |
377 | else | |
378 | printf ("Stack frame at 0x%x:\n pc = 0x%x", | |
379 | FRAME_FP(frame), fi->pc); | |
380 | ||
381 | if (funname) | |
382 | printf (" in %s", funname); | |
383 | if (sal.symtab) | |
384 | printf (" (%s line %d)", sal.symtab->filename, sal.line); | |
385 | printf ("; saved pc 0x%x\n", FRAME_SAVED_PC (frame)); | |
386 | if (calling_frame) | |
387 | printf (" called by frame at 0x%x", FRAME_FP (calling_frame)); | |
388 | if (fi->next_frame && calling_frame) | |
389 | printf (","); | |
390 | if (fi->next_frame) | |
391 | printf (" caller of frame at 0x%x", fi->next_frame); | |
392 | if (fi->next_frame || calling_frame) | |
393 | printf ("\n"); | |
394 | ||
395 | { | |
396 | /* Address of the argument list for this frame, or Frame_unknown. */ | |
397 | CORE_ADDR arg_list = FRAME_ARGS_ADDRESS_CORRECT (fi); | |
398 | /* Number of args for this frame, or -1 if unknown. */ | |
399 | int numargs; | |
400 | ||
401 | if (arg_list != Frame_unknown) | |
402 | { | |
403 | printf (" Arglist at 0x%x,", arg_list); | |
404 | ||
405 | FRAME_NUM_ARGS (numargs, fi); | |
406 | if (numargs < 0) | |
407 | printf (" args: "); | |
408 | else if (numargs == 0) | |
409 | printf (" no args."); | |
410 | else if (numargs == 1) | |
411 | printf (" 1 arg: "); | |
412 | else | |
413 | printf (" %d args: ", numargs); | |
414 | print_frame_args (func, fi, numargs, stdout); | |
415 | printf ("\n"); | |
416 | } | |
417 | } | |
418 | ||
419 | /* The sp is special; what's returned isn't the save address, but | |
420 | actually the value of the previous frame's sp. */ | |
421 | printf (" Previous frame's sp is 0x%x\n", fsr.regs[SP_REGNUM]); | |
422 | count = 0; | |
423 | for (i = 0; i < NUM_REGS; i++) | |
424 | if (fsr.regs[i] && i != SP_REGNUM) | |
425 | { | |
426 | if (count % 4 != 0) | |
427 | printf (", "); | |
428 | else | |
429 | { | |
430 | if (count == 0) | |
431 | printf (" Saved registers:"); | |
432 | printf ("\n "); | |
433 | } | |
434 | printf ("%s at 0x%x", reg_names[i], fsr.regs[i]); | |
435 | count++; | |
436 | } | |
437 | if (count) | |
438 | printf ("\n"); | |
439 | } | |
440 | ||
441 | #if 0 | |
442 | /* Set a limit on the number of frames printed by default in a | |
443 | backtrace. */ | |
444 | ||
445 | static int backtrace_limit; | |
446 | ||
447 | static void | |
448 | set_backtrace_limit_command (count_exp, from_tty) | |
449 | char *count_exp; | |
450 | int from_tty; | |
451 | { | |
452 | int count = parse_and_eval_address (count_exp); | |
453 | ||
454 | if (count < 0) | |
455 | error ("Negative argument not meaningful as backtrace limit."); | |
456 | ||
457 | backtrace_limit = count; | |
458 | } | |
459 | ||
460 | static void | |
461 | backtrace_limit_info (arg, from_tty) | |
462 | char *arg; | |
463 | int from_tty; | |
464 | { | |
465 | if (arg) | |
466 | error ("\"Info backtrace-limit\" takes no arguments."); | |
467 | ||
468 | printf ("Backtrace limit: %d.\n", backtrace_limit); | |
469 | } | |
470 | #endif | |
471 | ||
472 | /* Print briefly all stack frames or just the innermost COUNT frames. */ | |
473 | ||
474 | static void | |
475 | backtrace_command (count_exp) | |
476 | char *count_exp; | |
477 | { | |
478 | struct frame_info *fi; | |
479 | register int count; | |
480 | register FRAME frame; | |
481 | register int i; | |
482 | register FRAME trailing; | |
483 | register int trailing_level; | |
484 | ||
485 | /* The following code must do two things. First, it must | |
486 | set the variable TRAILING to the frame from which we should start | |
487 | printing. Second, it must set the variable count to the number | |
488 | of frames which we should print, or -1 if all of them. */ | |
489 | trailing = get_current_frame (); | |
490 | trailing_level = 0; | |
491 | if (count_exp) | |
492 | { | |
493 | count = parse_and_eval_address (count_exp); | |
494 | if (count < 0) | |
495 | { | |
496 | FRAME current; | |
497 | ||
498 | count = -count; | |
499 | ||
500 | current = trailing; | |
501 | while (current && count--) | |
502 | current = get_prev_frame (current); | |
503 | ||
504 | /* Will stop when CURRENT reaches the top of the stack. TRAILING | |
505 | will be COUNT below it. */ | |
506 | while (current) | |
507 | { | |
508 | trailing = get_prev_frame (trailing); | |
509 | current = get_prev_frame (current); | |
510 | trailing_level++; | |
511 | } | |
512 | ||
513 | count = -1; | |
514 | } | |
515 | } | |
516 | else | |
517 | count = -1; | |
518 | ||
519 | for (i = 0, frame = trailing; | |
520 | frame && count--; | |
521 | i++, frame = get_prev_frame (frame)) | |
522 | { | |
523 | QUIT; | |
524 | fi = get_frame_info (frame); | |
525 | print_frame_info (fi, trailing_level + i, 0, 1); | |
526 | } | |
527 | ||
528 | /* If we've stopped before the end, mention that. */ | |
529 | if (frame) | |
530 | printf_filtered ("(More stack frames follow...)\n"); | |
531 | } | |
532 | \f | |
533 | /* Print the local variables of a block B active in FRAME. | |
534 | Return 1 if any variables were printed; 0 otherwise. */ | |
535 | ||
536 | static int | |
537 | print_block_frame_locals (b, frame, stream) | |
538 | struct block *b; | |
539 | register FRAME frame; | |
540 | register FILE *stream; | |
541 | { | |
542 | int nsyms; | |
543 | register int i; | |
544 | register struct symbol *sym; | |
545 | register int values_printed = 0; | |
546 | ||
547 | nsyms = BLOCK_NSYMS (b); | |
548 | ||
549 | for (i = 0; i < nsyms; i++) | |
550 | { | |
551 | sym = BLOCK_SYM (b, i); | |
552 | if (SYMBOL_CLASS (sym) == LOC_LOCAL | |
553 | || SYMBOL_CLASS (sym) == LOC_REGISTER | |
554 | || SYMBOL_CLASS (sym) == LOC_STATIC) | |
555 | { | |
556 | values_printed = 1; | |
557 | fputs_filtered (SYMBOL_NAME (sym), stream); | |
558 | fputs_filtered (" = ", stream); | |
559 | print_variable_value (sym, frame, stream); | |
560 | fprintf_filtered (stream, "\n"); | |
561 | fflush (stream); | |
562 | } | |
563 | } | |
564 | return values_printed; | |
565 | } | |
566 | ||
567 | /* Print on STREAM all the local variables in frame FRAME, | |
568 | including all the blocks active in that frame | |
569 | at its current pc. | |
570 | ||
571 | Returns 1 if the job was done, | |
572 | or 0 if nothing was printed because we have no info | |
573 | on the function running in FRAME. */ | |
574 | ||
575 | static int | |
576 | print_frame_local_vars (frame, stream) | |
577 | register FRAME frame; | |
578 | register FILE *stream; | |
579 | { | |
580 | register struct block *block = get_frame_block (frame); | |
581 | register int values_printed = 0; | |
582 | ||
583 | if (block == 0) | |
584 | { | |
585 | fprintf_filtered (stream, "No symbol table info available.\n"); | |
586 | fflush (stream); | |
587 | return 0; | |
588 | } | |
589 | ||
590 | while (block != 0) | |
591 | { | |
592 | if (print_block_frame_locals (block, frame, stream)) | |
593 | values_printed = 1; | |
594 | /* After handling the function's top-level block, stop. | |
595 | Don't continue to its superblock, the block of | |
596 | per-file symbols. */ | |
597 | if (BLOCK_FUNCTION (block)) | |
598 | break; | |
599 | block = BLOCK_SUPERBLOCK (block); | |
600 | } | |
601 | ||
602 | if (!values_printed) | |
603 | { | |
604 | fprintf_filtered (stream, "No locals.\n"); | |
605 | fflush (stream); | |
606 | } | |
607 | ||
608 | return 1; | |
609 | } | |
610 | ||
611 | static void | |
612 | locals_info () | |
613 | { | |
614 | if (!have_inferior_p () && !have_core_file_p ()) | |
615 | error ("No inferior or core file."); | |
616 | ||
617 | print_frame_local_vars (selected_frame, stdout); | |
618 | } | |
619 | ||
620 | static int | |
621 | print_frame_arg_vars (frame, stream) | |
622 | register FRAME frame; | |
623 | register FILE *stream; | |
624 | { | |
625 | struct symbol *func = get_frame_function (frame); | |
626 | register struct block *b; | |
627 | int nsyms; | |
628 | register int i; | |
629 | register struct symbol *sym; | |
630 | register int values_printed = 0; | |
631 | ||
632 | if (func == 0) | |
633 | { | |
634 | fprintf_filtered (stream, "No symbol table info available.\n"); | |
635 | fflush (stream); | |
636 | return 0; | |
637 | } | |
638 | ||
639 | b = SYMBOL_BLOCK_VALUE (func); | |
640 | nsyms = BLOCK_NSYMS (b); | |
641 | ||
642 | for (i = 0; i < nsyms; i++) | |
643 | { | |
644 | sym = BLOCK_SYM (b, i); | |
645 | if (SYMBOL_CLASS (sym) == LOC_ARG | |
646 | || SYMBOL_CLASS (sym) == LOC_REF_ARG | |
647 | || SYMBOL_CLASS (sym) == LOC_REGPARM) | |
648 | { | |
649 | values_printed = 1; | |
650 | fputs_filtered (SYMBOL_NAME (sym), stream); | |
651 | fputs_filtered (" = ", stream); | |
652 | print_variable_value (sym, frame, stream); | |
653 | fprintf_filtered (stream, "\n"); | |
654 | fflush (stream); | |
655 | } | |
656 | } | |
657 | ||
658 | if (!values_printed) | |
659 | { | |
660 | fprintf_filtered (stream, "No arguments.\n"); | |
661 | fflush (stream); | |
662 | } | |
663 | ||
664 | return 1; | |
665 | } | |
666 | ||
667 | static void | |
668 | args_info () | |
669 | { | |
670 | if (!have_inferior_p () && !have_core_file_p ()) | |
671 | error ("No inferior or core file."); | |
672 | print_frame_arg_vars (selected_frame, stdout); | |
673 | } | |
674 | \f | |
675 | /* Select frame FRAME, and note that its stack level is LEVEL. | |
676 | LEVEL may be -1 if an actual level number is not known. */ | |
677 | ||
678 | void | |
679 | select_frame (frame, level) | |
680 | FRAME frame; | |
681 | int level; | |
682 | { | |
683 | selected_frame = frame; | |
684 | selected_frame_level = level; | |
685 | /* Ensure that symbols for this frame are readin. */ | |
686 | if (frame) | |
687 | find_pc_symtab (get_frame_info (frame)->pc); | |
688 | } | |
689 | ||
690 | /* Store the selected frame and its level into *FRAMEP and *LEVELP. */ | |
691 | ||
692 | void | |
693 | record_selected_frame (frameaddrp, levelp) | |
694 | FRAME_ADDR *frameaddrp; | |
695 | int *levelp; | |
696 | { | |
697 | *frameaddrp = FRAME_FP (selected_frame); | |
698 | *levelp = selected_frame_level; | |
699 | } | |
700 | ||
701 | /* Return the symbol-block in which the selected frame is executing. | |
702 | Can return zero under various legitimate circumstances. */ | |
703 | ||
704 | struct block * | |
705 | get_selected_block () | |
706 | { | |
707 | if (!have_inferior_p () && !have_core_file_p ()) | |
708 | return 0; | |
709 | ||
710 | if (!selected_frame) | |
711 | return get_current_block (); | |
712 | return get_frame_block (selected_frame); | |
713 | } | |
714 | ||
715 | /* Find a frame a certain number of levels away from FRAME. | |
716 | LEVEL_OFFSET_PTR points to an int containing the number of levels. | |
717 | Positive means go to earlier frames (up); negative, the reverse. | |
718 | The int that contains the number of levels is counted toward | |
719 | zero as the frames for those levels are found. | |
720 | If the top or bottom frame is reached, that frame is returned, | |
721 | but the final value of *LEVEL_OFFSET_PTR is nonzero and indicates | |
722 | how much farther the original request asked to go. */ | |
723 | ||
724 | FRAME | |
725 | find_relative_frame (frame, level_offset_ptr) | |
726 | register FRAME frame; | |
727 | register int* level_offset_ptr; | |
728 | { | |
729 | register FRAME prev; | |
730 | register FRAME frame1, frame2; | |
731 | ||
732 | /* Going up is simple: just do get_prev_frame enough times | |
733 | or until initial frame is reached. */ | |
734 | while (*level_offset_ptr > 0) | |
735 | { | |
736 | prev = get_prev_frame (frame); | |
737 | if (prev == 0) | |
738 | break; | |
739 | (*level_offset_ptr)--; | |
740 | frame = prev; | |
741 | } | |
742 | /* Going down could be done by iterating get_frame_info to | |
743 | find the next frame, but that would be quadratic | |
744 | since get_frame_info must scan all the way from the current frame. | |
745 | The following algorithm is linear. */ | |
746 | if (*level_offset_ptr < 0) | |
747 | { | |
748 | /* First put frame1 at innermost frame | |
749 | and frame2 N levels up from there. */ | |
750 | frame1 = get_current_frame (); | |
751 | frame2 = frame1; | |
752 | while (*level_offset_ptr < 0 && frame2 != frame) | |
753 | { | |
754 | frame2 = get_prev_frame (frame2); | |
755 | (*level_offset_ptr) ++; | |
756 | } | |
757 | /* Then slide frame1 and frame2 up in synchrony | |
758 | and when frame2 reaches our starting point | |
759 | frame1 must be N levels down from there. */ | |
760 | while (frame2 != frame) | |
761 | { | |
762 | frame1 = get_prev_frame (frame1); | |
763 | frame2 = get_prev_frame (frame2); | |
764 | } | |
765 | return frame1; | |
766 | } | |
767 | return frame; | |
768 | } | |
769 | ||
770 | /* The "frame" command. With no arg, print selected frame briefly. | |
771 | With arg LEVEL_EXP, select the frame at level LEVEL if it is a | |
772 | valid level. Otherwise, treat level_exp as an address expression | |
773 | and print it. See parse_frame_specification for more info on proper | |
774 | frame expressions. */ | |
775 | ||
776 | static void | |
777 | frame_command (level_exp, from_tty) | |
778 | char *level_exp; | |
779 | int from_tty; | |
780 | { | |
781 | register FRAME frame, frame1; | |
782 | unsigned int level = 0; | |
783 | ||
784 | if (!have_inferior_p () && ! have_core_file_p ()) | |
785 | error ("No inferior or core file."); | |
786 | ||
787 | frame = parse_frame_specification (level_exp); | |
788 | ||
789 | for (frame1 = get_prev_frame (0); | |
790 | frame1 && frame1 != frame; | |
791 | frame1 = get_prev_frame (frame1)) | |
792 | level++; | |
793 | ||
794 | if (!frame1) | |
795 | level = 0; | |
796 | ||
797 | frame_changed = level; | |
798 | select_frame (frame, level); | |
799 | ||
800 | if (!from_tty) | |
801 | return; | |
802 | ||
803 | print_stack_frame (selected_frame, selected_frame_level, 1); | |
804 | } | |
805 | ||
806 | /* Select the frame up one or COUNT stack levels | |
807 | from the previously selected frame, and print it briefly. */ | |
808 | ||
809 | static void | |
810 | up_command (count_exp) | |
811 | char *count_exp; | |
812 | { | |
813 | register FRAME frame; | |
814 | int count = 1, count1; | |
815 | if (count_exp) | |
816 | count = parse_and_eval_address (count_exp); | |
817 | count1 = count; | |
818 | ||
819 | if (!have_inferior_p () && !have_core_file_p ()) | |
820 | error ("No inferior or core file."); | |
821 | ||
822 | frame = find_relative_frame (selected_frame, &count1); | |
823 | if (count1 != 0 && count_exp == 0) | |
824 | error ("Initial frame selected; you cannot go up."); | |
825 | select_frame (frame, selected_frame_level + count - count1); | |
826 | ||
827 | print_stack_frame (selected_frame, selected_frame_level, 1); | |
828 | frame_changed++; | |
829 | } | |
830 | ||
831 | /* Select the frame down one or COUNT stack levels | |
832 | from the previously selected frame, and print it briefly. */ | |
833 | ||
834 | static void | |
835 | down_command (count_exp) | |
836 | char *count_exp; | |
837 | { | |
838 | register FRAME frame; | |
839 | int count = -1, count1; | |
840 | if (count_exp) | |
841 | count = - parse_and_eval_address (count_exp); | |
842 | count1 = count; | |
843 | ||
844 | frame = find_relative_frame (selected_frame, &count1); | |
845 | if (count1 != 0 && count_exp == 0) | |
846 | error ("Bottom (i.e., innermost) frame selected; you cannot go down."); | |
847 | select_frame (frame, selected_frame_level + count - count1); | |
848 | ||
849 | print_stack_frame (selected_frame, selected_frame_level, 1); | |
850 | frame_changed--; | |
851 | } | |
852 | \f | |
853 | static void | |
854 | return_command (retval_exp, from_tty) | |
855 | char *retval_exp; | |
856 | int from_tty; | |
857 | { | |
858 | value return_value; | |
859 | struct symbol *thisfun = get_frame_function (selected_frame); | |
860 | FRAME_ADDR selected_frame_addr = FRAME_FP (selected_frame); | |
861 | ||
862 | /* If interactive, require confirmation. */ | |
863 | ||
864 | if (from_tty) | |
865 | { | |
866 | if (thisfun != 0) | |
867 | { | |
868 | if (!query ("Make %s return now? ", SYMBOL_NAME (thisfun))) | |
869 | error ("Not confirmed."); | |
870 | } | |
871 | else | |
872 | if (!query ("Make selected stack frame return now? ")) | |
873 | error ("Not confirmed."); | |
874 | } | |
875 | ||
876 | /* Do the real work. Pop until the specified frame is current. We | |
877 | use this method because the selected_frame is not valid after | |
878 | a POP_FRAME. Note that this will not work if the selected frame | |
879 | shares it's fp with another frame. */ | |
880 | ||
881 | while (selected_frame_addr != FRAME_FP (get_current_frame())) | |
882 | POP_FRAME; | |
883 | ||
884 | /* get the return value while still in this frame */ | |
885 | if (retval_exp) | |
886 | return_value = parse_and_eval (retval_exp); | |
887 | ||
888 | /* Then pop that frame. */ | |
889 | POP_FRAME; | |
890 | ||
891 | /* Store the return value if there was one */ | |
892 | ||
893 | if (retval_exp) | |
894 | set_return_value (return_value); | |
895 | ||
896 | /* If interactive, print the frame that is now current. */ | |
897 | ||
898 | if (from_tty) | |
899 | frame_command ("0", 1); | |
900 | } | |
901 | \f | |
902 | extern struct cmd_list_element *setlist; | |
903 | ||
904 | void | |
905 | _initialize_stack () | |
906 | { | |
907 | #if 0 | |
908 | backtrace_limit = 30; | |
909 | #endif | |
910 | ||
911 | add_com ("return", class_stack, return_command, | |
912 | "Make selected stack frame return to its caller.\n\ | |
913 | Control remains in the debugger, but when you continue\n\ | |
914 | execution will resume in the frame above the one now selected.\n\ | |
915 | If an argument is given, it is an expression for the value to return."); | |
916 | ||
917 | add_com ("up", class_stack, up_command, | |
918 | "Select and print stack frame that called this one.\n\ | |
919 | An argument says how many frames up to go."); | |
920 | ||
921 | add_com ("down", class_stack, down_command, | |
922 | "Select and print stack frame called by this one.\n\ | |
923 | An argument says how many frames down to go."); | |
924 | add_com_alias ("do", "down", class_stack, 1); | |
925 | ||
926 | add_com ("frame", class_stack, frame_command, | |
927 | "Select and print a stack frame.\n\ | |
928 | With no argument, print the selected stack frame. (See also \"info frame\").\n\ | |
929 | An argument specifies the frame to select.\n\ | |
930 | It can be a stack frame number or the address of the frame.\n\ | |
931 | With argument, nothing is printed if input is coming from\n\ | |
932 | a command file or a user-defined command."); | |
933 | ||
934 | add_com_alias ("f", "frame", class_stack, 1); | |
935 | ||
936 | add_com ("backtrace", class_stack, backtrace_command, | |
937 | "Print backtrace of all stack frames, or innermost COUNT frames.\n\ | |
938 | With a negative argument, print outermost -COUNT frames."); | |
939 | add_com_alias ("bt", "backtrace", class_stack, 0); | |
940 | add_com_alias ("where", "backtrace", class_alias, 0); | |
941 | add_info ("stack", backtrace_command, | |
942 | "Backtrace of the stack, or innermost COUNT frames."); | |
943 | add_info_alias ("s", "stack", 1); | |
944 | add_info ("frame", frame_info, | |
945 | "All about selected stack frame, or frame at ADDR."); | |
946 | add_info_alias ("f", "frame", 1); | |
947 | add_info ("locals", locals_info, | |
948 | "Local variables of current stack frame."); | |
949 | add_info ("args", args_info, | |
950 | "Argument variables of current stack frame."); | |
951 | ||
952 | #if 0 | |
953 | add_cmd ("backtrace-limit", class_stack, set_backtrace_limit_command, | |
954 | "Specify maximum number of frames for \"backtrace\" to print by default.", | |
955 | &setlist); | |
956 | add_info ("backtrace-limit", backtrace_limit_info, | |
957 | "The maximum number of frames for \"backtrace\" to print by default."); | |
958 | #endif | |
959 | } | |
960 |