Annotation of 43BSDReno/contrib/emacs-18.55/gdb/stack.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.