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

1.1     ! root        1: /* Everything about breakpoints, for GDB.
        !             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 "defs.h"
        !            22: #include "initialize.h"
        !            23: #include "param.h"
        !            24: #include "symtab.h"
        !            25: #include "frame.h"
        !            26: 
        !            27: #include <stdio.h>
        !            28: 
        !            29: /* This is the sequence of bytes we insert for a breakpoint.  */
        !            30: 
        !            31: static char break_insn[] = BREAKPOINT;
        !            32: 
        !            33: /* States of enablement of breakpoint.
        !            34:    `temporary' means disable when hit.
        !            35:    `once' means delete when hit.  */
        !            36: 
        !            37: enum enable { disabled, enabled, temporary, delete};
        !            38: 
        !            39: struct breakpoint
        !            40: {
        !            41:   struct breakpoint *next;
        !            42:   /* Number assigned to distinguish breakpoints.  */
        !            43:   int number;
        !            44:   /* Address to break at.  */
        !            45:   CORE_ADDR address;
        !            46:   /* Line number of this address.  Redundant.  */
        !            47:   int line_number;
        !            48:   /* Symtab of file of this address.  Redundant.  */
        !            49:   struct symtab *symtab;
        !            50:   /* Zero means disabled; remember the info but don't break here.  */
        !            51:   enum enable enable;
        !            52:   /* Number of stops at this breakpoint that should
        !            53:      be continued automatically before really stopping.  */
        !            54:   int ignore_count;
        !            55:   /* "Real" contents of byte where breakpoint has been inserted.
        !            56:      Valid only when breakpoints are in the program.  */
        !            57:   char shadow_contents[sizeof break_insn];
        !            58:   /* Nonzero if this breakpoint is now inserted.  */
        !            59:   char inserted;
        !            60:   /* Nonzero if this is not the first breakpoint in the list
        !            61:      for the given address.  */
        !            62:   char duplicate;
        !            63:   /* Chain of command lines to execute when this breakpoint is hit.  */
        !            64:   struct command_line *commands;
        !            65:   /* Stack depth (frame).  If nonzero, break only if fp equals this.  */
        !            66:   FRAME frame;
        !            67:   /* Conditional.  Break only if this expression's value is nonzero.  */
        !            68:   struct expression *cond;
        !            69: };
        !            70: 
        !            71: #define ALL_BREAKPOINTS(b)  for (b = breakpoint_chain; b; b = b->next)
        !            72: 
        !            73: /* Chain of all breakpoints defined.  */
        !            74: 
        !            75: struct breakpoint *breakpoint_chain;
        !            76: 
        !            77: /* Number of last breakpoint made.  */
        !            78: 
        !            79: static int breakpoint_count;
        !            80: 
        !            81: /* Default address, symtab and line to put a breakpoint at
        !            82:    for "break" command with no arg.
        !            83:    if default_breakpoint_valid is zero, the other three are
        !            84:    not valid, and "break" with no arg is an error.
        !            85: 
        !            86:    This set by print_stack_frame, which calls set_default_breakpoint.  */
        !            87: 
        !            88: int default_breakpoint_valid;
        !            89: CORE_ADDR default_breakpoint_address;
        !            90: struct symtab *default_breakpoint_symtab;
        !            91: int default_breakpoint_line;
        !            92: 
        !            93: /* Remaining commands (not yet executed)
        !            94:    of last breakpoint hit.  */
        !            95: 
        !            96: struct command_line *breakpoint_commands;
        !            97: 
        !            98: START_FILE
        !            99: 
        !           100: extern char *read_line ();
        !           101: 
        !           102: static void delete_breakpoint ();
        !           103: void clear_momentary_breakpoints ();
        !           104: void breakpoint_auto_delete ();
        !           105: 
        !           106: /* condition N EXP -- set break condition of breakpoint N to EXP.  */
        !           107: 
        !           108: static void
        !           109: condition_command (arg, from_tty)
        !           110:      char *arg;
        !           111:      int from_tty;
        !           112: {
        !           113:   register struct breakpoint *b;
        !           114:   register char *p;
        !           115:   register int bnum;
        !           116:   register struct expression *expr;
        !           117: 
        !           118:   if (arg == 0)
        !           119:     error_no_arg ("breakpoint number");
        !           120: 
        !           121:   p = arg;
        !           122:   while (*p >= '0' && *p <= '9') p++;
        !           123:   bnum = atoi (arg);
        !           124: 
        !           125:   ALL_BREAKPOINTS (b)
        !           126:     if (b->number == bnum)
        !           127:       {
        !           128:        if (b->cond)
        !           129:          free (b->cond);
        !           130:        if (*p == 0)
        !           131:          {
        !           132:            b->cond = 0;
        !           133:            if (from_tty)
        !           134:              printf ("Breakpoint %d now unconditional.\n", bnum);
        !           135:          }
        !           136:        else
        !           137:          {
        !           138:            if (*p != ' ' && *p != '\t')
        !           139:              error ("Arguments must be an integer (breakpoint number) and an expression.");
        !           140: 
        !           141:            /* Find start of expression */
        !           142:            while (*p == ' ' || *p == '\t') p++;
        !           143: 
        !           144:            arg = p;
        !           145:            b->cond = (struct expression *) parse_c_1 (&arg, block_for_pc (b->address), 0);
        !           146:            if (*arg)
        !           147:              error ("Junk at end of expression");
        !           148:          }
        !           149:        return;
        !           150:       }
        !           151: 
        !           152:   error ("No breakpoint number %d.", bnum);
        !           153: }
        !           154: 
        !           155: static void
        !           156: commands_command (arg)
        !           157:      char *arg;
        !           158: {
        !           159:   register struct breakpoint *b;
        !           160:   register char *p, *p1;
        !           161:   register int bnum;
        !           162:   struct command_line *l;
        !           163: 
        !           164:   if (arg == 0)
        !           165:     error_no_arg ("breakpoint number");
        !           166: 
        !           167:   /* If we allowed this, we would have problems with when to
        !           168:      free the storage, if we change the commands currently
        !           169:      being read from.  */
        !           170: 
        !           171:   if (breakpoint_commands)
        !           172:     error ("Can't use the \"commands\" command among a breakpoint's commands.");
        !           173: 
        !           174:   p = arg;
        !           175:   if (! (*p >= '0' && *p <= '9'))
        !           176:     error ("Argument must be integer (a breakpoint number).");
        !           177: 
        !           178:   while (*p >= '0' && *p <= '9') p++;
        !           179:   if (*p)
        !           180:     error ("Unexpected extra arguments following breakpoint number.");
        !           181: 
        !           182:   bnum = atoi (arg);
        !           183: 
        !           184:   ALL_BREAKPOINTS (b)
        !           185:     if (b->number == bnum)
        !           186:       {
        !           187:        if (input_from_terminal_p ())
        !           188:          {
        !           189:            printf ("Type commands for when breakpoint %d is hit, one per line.\n\
        !           190: End with a line saying just \"end\".\n", bnum);
        !           191:            fflush (stdout);
        !           192:          }
        !           193:        l = read_command_lines ();
        !           194:        free_command_lines (&b->commands);
        !           195:        b->commands = l;
        !           196:        return;
        !           197:       }
        !           198:   error ("No breakpoint number %d.", bnum);
        !           199: }
        !           200: 
        !           201: /* Called from command loop to execute the commands
        !           202:    associated with the breakpoint we just stopped at.  */
        !           203: 
        !           204: void
        !           205: do_breakpoint_commands ()
        !           206: {
        !           207:   while (breakpoint_commands)
        !           208:     {
        !           209:       char *line = breakpoint_commands->line;
        !           210:       breakpoint_commands = breakpoint_commands->next;
        !           211:       execute_command (line, 0);
        !           212:       /* If command was "cont", breakpoint_commands is now 0,
        !           213:         of if we stopped at yet another breakpoint which has commands,
        !           214:         it is now the commands for the new breakpoint.  */
        !           215:     }
        !           216:   clear_momentary_breakpoints ();
        !           217: }
        !           218: 
        !           219: /* Used when the program is proceeded, to eliminate any remaining
        !           220:    commands attached to the previous breakpoint we stopped at.  */
        !           221: 
        !           222: void
        !           223: clear_breakpoint_commands ()
        !           224: {
        !           225:   breakpoint_commands = 0;
        !           226:   breakpoint_auto_delete (0);
        !           227: }
        !           228: 
        !           229: /* Functions to get and set the current list of pending
        !           230:    breakpoint commands.  These are used by run_stack_dummy
        !           231:    to preserve the commands around a function call.  */
        !           232: 
        !           233: struct command_line *
        !           234: get_breakpoint_commands ()
        !           235: {
        !           236:   return breakpoint_commands;
        !           237: }
        !           238: 
        !           239: void
        !           240: set_breakpoint_commands (cmds)
        !           241:      struct command_line *cmds;
        !           242: {
        !           243:   breakpoint_commands = cmds;
        !           244: }
        !           245: 
        !           246: /* insert_breakpoints is used when starting or continuing the program.
        !           247:    remove_breakpoints is used when the program stops.
        !           248:    Both return zero if successful,
        !           249:    or an `errno' value if could not write the inferior.  */
        !           250: 
        !           251: int
        !           252: insert_breakpoints ()
        !           253: {
        !           254:   register struct breakpoint *b;
        !           255:   int val;
        !           256: 
        !           257: /*   printf ("Inserting breakpoints.\n"); */
        !           258:   ALL_BREAKPOINTS (b)
        !           259:     if (b->enable != disabled && ! b->inserted && ! b->duplicate)
        !           260:       {
        !           261:        read_memory (b->address, b->shadow_contents, sizeof break_insn);
        !           262:        val = write_memory (b->address, break_insn, sizeof break_insn);
        !           263:        if (val)
        !           264:          return val;
        !           265: /*     printf ("Inserted breakpoint at 0x%x, shadow 0x%x, 0x%x.\n",
        !           266:                b->address, b->shadow_contents[0], b->shadow_contents[1]); */
        !           267:        b->inserted = 1;
        !           268:       }
        !           269:   return 0;
        !           270: }
        !           271: 
        !           272: int
        !           273: remove_breakpoints ()
        !           274: {
        !           275:   register struct breakpoint *b;
        !           276:   int val;
        !           277: 
        !           278: /*   printf ("Removing breakpoints.\n"); */
        !           279:   ALL_BREAKPOINTS (b)
        !           280:     if (b->inserted)
        !           281:       {
        !           282:        val = write_memory (b->address, b->shadow_contents, sizeof break_insn);
        !           283:        if (val)
        !           284:          return val;
        !           285:        b->inserted = 0;
        !           286: /*     printf ("Removed breakpoint at 0x%x, shadow 0x%x, 0x%x.\n",
        !           287:                b->address, b->shadow_contents[0], b->shadow_contents[1]); */
        !           288:       }
        !           289: 
        !           290:   return 0;
        !           291: }
        !           292: 
        !           293: /* Clear the "inserted" flag in all breakpoints.
        !           294:    This is done when the inferior is loaded.  */
        !           295: 
        !           296: int
        !           297: mark_breakpoints_out ()
        !           298: {
        !           299:   register struct breakpoint *b;
        !           300: 
        !           301:   ALL_BREAKPOINTS (b)
        !           302:     b->inserted = 0;
        !           303: }
        !           304: 
        !           305: /* breakpoint_here_p (PC) returns 1 if an enabled breakpoint exists at PC.
        !           306:    When continuing from a location with a breakpoint,
        !           307:    we actually single step once before calling insert_breakpoints.  */
        !           308: 
        !           309: int
        !           310: breakpoint_here_p (pc)
        !           311:      CORE_ADDR pc;
        !           312: {
        !           313:   register struct breakpoint *b;
        !           314: 
        !           315:   ALL_BREAKPOINTS (b)
        !           316:     if (b->enable != disabled && b->address == pc)
        !           317:       return 1;
        !           318: 
        !           319:   return 0;
        !           320: }
        !           321: 
        !           322: /* Evaluate the expression EXP and return 1 if value is zero.
        !           323:    This is used inside a catch_errors to evaluate the breakpoint condition.  */
        !           324: 
        !           325: int
        !           326: breakpoint_cond_eval (exp)
        !           327:      struct expression *exp;
        !           328: {
        !           329:   return value_zerop (evaluate_expression (exp));
        !           330: }
        !           331: 
        !           332: /* Return 0 if PC is not the address just after a breakpoint,
        !           333:    or -1 if breakpoint says do not stop now,
        !           334:    or -2 if breakpoint says it has deleted itself and don't stop,
        !           335:    or -3 if hit a breakpoint number -3 (delete when program stops),
        !           336:    or else the number of the breakpoint,
        !           337:    with 0x1000000 added for a silent breakpoint.  */
        !           338: 
        !           339: int
        !           340: breakpoint_stop_status (pc, frame)
        !           341:      CORE_ADDR pc;
        !           342:      FRAME frame;
        !           343: {
        !           344:   register struct breakpoint *b;
        !           345:   register int cont = 0;
        !           346: 
        !           347:   /* Get the address where the breakpoint would have been.  */
        !           348:   pc -= DECR_PC_AFTER_BREAK;
        !           349: 
        !           350:   ALL_BREAKPOINTS (b)
        !           351:     if (b->enable != disabled && b->address == pc)
        !           352:       {
        !           353:        if (b->frame && b->frame != frame)
        !           354:          cont = -1;
        !           355:        else
        !           356:          {
        !           357:            int value_zero;
        !           358:            if (b->cond)
        !           359:              {
        !           360:                value_zero
        !           361:                  = catch_errors (breakpoint_cond_eval, b->cond,
        !           362:                                  "Error occurred in testing breakpoint condition.");
        !           363:                free_all_values ();
        !           364:              }
        !           365:            if (b->cond && value_zero)
        !           366:              {
        !           367:                cont = -1;
        !           368:              }
        !           369:            else if (b->ignore_count > 0)
        !           370:              {
        !           371:                b->ignore_count--;
        !           372:                cont = -1;
        !           373:              }
        !           374:            else
        !           375:              {
        !           376:                if (b->enable == temporary)
        !           377:                  b->enable = disabled;
        !           378:                breakpoint_commands = b->commands;
        !           379:                if (breakpoint_commands
        !           380:                    && !strcmp ("silent", breakpoint_commands->line))
        !           381:                  {
        !           382:                    breakpoint_commands = breakpoint_commands->next;
        !           383:                    return 0x1000000 + b->number;
        !           384:                  }
        !           385:                return b->number;
        !           386:              }
        !           387:          }
        !           388:       }
        !           389: 
        !           390:   return cont;
        !           391: }
        !           392: 
        !           393: static void
        !           394: breakpoint_1 (bnum)
        !           395:      int bnum;
        !           396: {
        !           397:   register struct breakpoint *b;
        !           398:   register struct command_line *l;
        !           399:   register struct symbol *sym;
        !           400:   CORE_ADDR last_addr = -1;
        !           401: 
        !           402:   ALL_BREAKPOINTS (b)
        !           403:     if (bnum == -1 || bnum == b->number)
        !           404:       {
        !           405:        printf ("#%-3d %c  0x%08x ", b->number,
        !           406:                "nyod"[(int) b->enable],
        !           407:                b->address);
        !           408:        last_addr = b->address;
        !           409:        if (b->symtab)
        !           410:          {
        !           411:            sym = find_pc_function (b->address);
        !           412:            if (sym)
        !           413:              printf (" in %s (%s line %d)", SYMBOL_NAME (sym),
        !           414:                      b->symtab->filename, b->line_number);
        !           415:            else
        !           416:              printf ("%s line %d", b->symtab->filename, b->line_number);
        !           417:          }
        !           418:        printf ("\n");
        !           419: 
        !           420:        if (b->ignore_count)
        !           421:          printf ("\tignore next %d hits\n", b->ignore_count);
        !           422:        if (b->frame)
        !           423:          printf ("\tstop only in stack frame at 0x%x\n", b->frame);
        !           424:        if (b->cond)
        !           425:          {
        !           426:            printf ("\tbreak only if ");
        !           427:            print_expression (b->cond, stdout);
        !           428:            printf ("\n");
        !           429:          }
        !           430:        if (l = b->commands)
        !           431:          while (l)
        !           432:            {
        !           433:              printf ("\t%s\n", l->line);
        !           434:              l = l->next;
        !           435:            }
        !           436:       }
        !           437: 
        !           438:   if (last_addr != -1)
        !           439:     set_next_address (last_addr);
        !           440: }
        !           441: 
        !           442: static void
        !           443: breakpoints_info (bnum_exp)
        !           444:      char *bnum_exp;
        !           445: {
        !           446:   int bnum = -1;
        !           447: 
        !           448:   if (bnum_exp)
        !           449:     bnum = parse_and_eval_address (bnum_exp);
        !           450:   else if (breakpoint_chain == 0)
        !           451:     printf ("No breakpoints.\n");
        !           452:   else
        !           453:     printf ("Breakpoints:\n\
        !           454: Num Enb   Address    Where\n");
        !           455: 
        !           456:   breakpoint_1 (bnum);
        !           457: }
        !           458: 
        !           459: /* Print a message describing any breakpoints set at PC.  */
        !           460: 
        !           461: static void
        !           462: describe_other_breakpoints (pc)
        !           463:      register CORE_ADDR pc;
        !           464: {
        !           465:   register int others = 0;
        !           466:   register struct breakpoint *b;
        !           467: 
        !           468:   ALL_BREAKPOINTS (b)
        !           469:     if (b->address == pc)
        !           470:       others++;
        !           471:   if (others > 0)
        !           472:     {
        !           473:       printf ("Note: breakpoint%s ", (others > 1) ? "s" : "");
        !           474:       ALL_BREAKPOINTS (b)
        !           475:        if (b->address == pc)
        !           476:          {
        !           477:            others--;
        !           478:            printf ("%d%s%s ",
        !           479:                    b->number,
        !           480:                    (b->enable == disabled) ? " (disabled)" : "",
        !           481:                    (others > 1) ? "," : ((others == 1) ? " and" : ""));
        !           482:          }
        !           483:       printf (" also set at pc 0x%x\n", pc);
        !           484:     }
        !           485: }
        !           486: 
        !           487: /* Set the default place to put a breakpoint
        !           488:    for the `break' command with no arguments.  */
        !           489: 
        !           490: void
        !           491: set_default_breakpoint (valid, addr, symtab, line)
        !           492:      int valid;
        !           493:      CORE_ADDR addr;
        !           494:      struct symtab *symtab;
        !           495:      int line;
        !           496: {
        !           497:   default_breakpoint_valid = valid;
        !           498:   default_breakpoint_address = addr;
        !           499:   default_breakpoint_symtab = symtab;
        !           500:   default_breakpoint_line = line;
        !           501: }
        !           502: 
        !           503: /* Rescan breakpoints at address ADDRESS,
        !           504:    marking the first one as "first" and any others as "duplicates".
        !           505:    This is so that the bpt instruction is only inserted once.  */
        !           506: 
        !           507: static void
        !           508: check_duplicates (address)
        !           509:      CORE_ADDR address;
        !           510: {
        !           511:   register struct breakpoint *b;
        !           512:   register int count = 0;
        !           513: 
        !           514:   ALL_BREAKPOINTS (b)
        !           515:     if (b->enable != disabled && b->address == address)
        !           516:       {
        !           517:        count++;
        !           518:        b->duplicate = count > 1;
        !           519:       }
        !           520: }
        !           521: 
        !           522: /* Low level routine to set a breakpoint.
        !           523:    Takes as args the three things that every breakpoint must have.
        !           524:    Returns the breakpoint object so caller can set other things.
        !           525:    Does not set the breakpoint number!
        !           526:    Does not print anything.  */
        !           527: 
        !           528: static struct breakpoint *
        !           529: set_raw_breakpoint (sal)
        !           530:      struct symtab_and_line sal;
        !           531: {
        !           532:   register struct breakpoint *b, *b1;
        !           533: 
        !           534:   b = (struct breakpoint *) xmalloc (sizeof (struct breakpoint));
        !           535:   bzero (b, sizeof *b);
        !           536:   b->address = sal.pc;
        !           537:   b->symtab = sal.symtab;
        !           538:   b->line_number = sal.line;
        !           539:   b->enable = enabled;
        !           540:   b->next = 0;
        !           541: 
        !           542:   /* Add this breakpoint to the end of the chain
        !           543:      so that a list of breakpoints will come out in order
        !           544:      of increasing numbers.  */
        !           545: 
        !           546:   b1 = breakpoint_chain;
        !           547:   if (b1 == 0)
        !           548:     breakpoint_chain = b;
        !           549:   else
        !           550:     {
        !           551:       while (b1->next)
        !           552:        b1 = b1->next;
        !           553:       b1->next = b;
        !           554:     }
        !           555: 
        !           556:   check_duplicates (sal.pc);
        !           557: 
        !           558:   return b;
        !           559: }
        !           560: 
        !           561: /* Set a breakpoint that will evaporate an end of command
        !           562:    at address specified by SAL.
        !           563:    Restrict it to frame FRAME if FRAME is nonzero.  */
        !           564: 
        !           565: void
        !           566: set_momentary_breakpoint (sal, frame)
        !           567:      struct symtab_and_line sal;
        !           568:      FRAME frame;
        !           569: {
        !           570:   register struct breakpoint *b;
        !           571:   b = set_raw_breakpoint (sal);
        !           572:   b->number = -3;
        !           573:   b->enable = delete;
        !           574:   b->frame = frame;
        !           575: }
        !           576: 
        !           577: void
        !           578: clear_momentary_breakpoints ()
        !           579: {
        !           580:   register struct breakpoint *b;
        !           581:   ALL_BREAKPOINTS (b)
        !           582:     if (b->number == -3)
        !           583:       {
        !           584:        delete_breakpoint (b);
        !           585:        break;
        !           586:       }
        !           587: }
        !           588: 
        !           589: /* Set a breakpoint from a symtab and line.
        !           590:    If TEMPFLAG is nonzero, it is a temporary breakpoint.
        !           591:    Print the same confirmation messages that the breakpoint command prints.  */
        !           592: 
        !           593: void
        !           594: set_breakpoint (s, line, tempflag)
        !           595:      struct symtab *s;
        !           596:      int line;
        !           597:      int tempflag;
        !           598: {
        !           599:   register struct breakpoint *b;
        !           600:   struct symtab_and_line sal;
        !           601:   
        !           602:   sal.symtab = s;
        !           603:   sal.line = line;
        !           604:   sal.pc = find_line_pc (sal.symtab, sal.line);
        !           605:   if (sal.pc == 0)
        !           606:     error ("No line %d in file \"%s\".\n", sal.line, sal.symtab->filename);
        !           607:   else
        !           608:     {
        !           609:       describe_other_breakpoints (sal.pc);
        !           610: 
        !           611:       b = set_raw_breakpoint (sal);
        !           612:       b->number = ++breakpoint_count;
        !           613:       b->cond = 0;
        !           614:       if (tempflag)
        !           615:        b->enable = temporary;
        !           616: 
        !           617:       printf ("Breakpoint %d at 0x%x", b->number, b->address);
        !           618:       if (b->symtab)
        !           619:        printf (": file %s, line %d.", b->symtab->filename, b->line_number);
        !           620:       printf ("\n");
        !           621:     }
        !           622: }
        !           623: 
        !           624: /* Set a breakpoint according to ARG (function, linenum or *address)
        !           625:    and make it temporary if TEMPFLAG is nonzero.  */
        !           626: 
        !           627: static void
        !           628: break_command_1 (arg, tempflag, from_tty)
        !           629:      char *arg;
        !           630:      int tempflag, from_tty;
        !           631: {
        !           632:   struct symtab_and_line sal;
        !           633:   register struct expression *cond = 0;
        !           634:   register struct breakpoint *b;
        !           635: 
        !           636:   sal.pc = 0;
        !           637: 
        !           638:   if (arg)
        !           639:     {
        !           640:       sal = decode_line_1 (&arg, 1, 0, 0);
        !           641: 
        !           642:       if (sal.pc == 0 && sal.symtab != 0)
        !           643:        {
        !           644:          sal.pc = find_line_pc (sal.symtab, sal.line);
        !           645:          if (sal.pc == 0)
        !           646:            error ("No line %d in file \"%s\".",
        !           647:                   sal.line, sal.symtab->filename);
        !           648:        }
        !           649: 
        !           650:       while (*arg)
        !           651:        {
        !           652:          if (arg[0] == 'i' && arg[1] == 'f'
        !           653:              && (arg[2] == ' ' || arg[2] == '\t'))
        !           654:            cond = (struct expression *) parse_c_1 ((arg += 2, &arg),
        !           655:                                                    block_for_pc (sal.pc), 0);
        !           656:          else
        !           657:            error ("Junk at end of arguments.");
        !           658:        }
        !           659:     }
        !           660:   else if (default_breakpoint_valid)
        !           661:     {
        !           662:       sal.pc = default_breakpoint_address;
        !           663:       sal.line = default_breakpoint_line;
        !           664:       sal.symtab = default_breakpoint_symtab;
        !           665:     }
        !           666:   else
        !           667:     error ("No default breakpoint address now.");
        !           668: 
        !           669:   if (from_tty)
        !           670:     describe_other_breakpoints (sal.pc);
        !           671: 
        !           672:   b = set_raw_breakpoint (sal);
        !           673:   b->number = ++breakpoint_count;
        !           674:   b->cond = cond;
        !           675:   if (tempflag)
        !           676:     b->enable = temporary;
        !           677: 
        !           678:   printf ("Breakpoint %d at 0x%x", b->number, b->address);
        !           679:   if (b->symtab)
        !           680:     printf (": file %s, line %d.", b->symtab->filename, b->line_number);
        !           681:   printf ("\n");
        !           682: }
        !           683: 
        !           684: static void
        !           685: break_command (arg, from_tty)
        !           686:      char *arg;
        !           687:      int from_tty;
        !           688: {
        !           689:   break_command_1 (arg, 0, from_tty);
        !           690: }
        !           691: 
        !           692: static void
        !           693: tbreak_command (arg, from_tty)
        !           694:      char *arg;
        !           695:      int from_tty;
        !           696: {
        !           697:   break_command_1 (arg, 1, from_tty);
        !           698: }
        !           699: 
        !           700: static void
        !           701: clear_command (arg, from_tty)
        !           702:      char *arg;
        !           703:      int from_tty;
        !           704: {
        !           705:   register struct breakpoint *b, *b1;
        !           706:   struct symtab_and_line sal;
        !           707:   register struct breakpoint *found;
        !           708: 
        !           709:   if (arg)
        !           710:     sal = decode_line_spec (arg, 1);
        !           711:   else
        !           712:     {
        !           713:       sal.line = default_breakpoint_line;
        !           714:       sal.symtab = default_breakpoint_symtab;
        !           715:       sal.pc = 0;
        !           716:       if (sal.symtab == 0)
        !           717:        error ("No source file specified.");
        !           718:     }
        !           719: 
        !           720:   /* If exact pc given, clear bpts at that pc.
        !           721:      But if sal.pc is zero, clear all bpts on specified line.  */
        !           722: 
        !           723:   found = (struct breakpoint *) 0;
        !           724:   while (breakpoint_chain
        !           725:         && (sal.pc ? breakpoint_chain->address == sal.pc
        !           726:             : (breakpoint_chain->symtab == sal.symtab
        !           727:                && breakpoint_chain->line_number == sal.line)))
        !           728:     {
        !           729:       b1 = breakpoint_chain;
        !           730:       breakpoint_chain = b1->next;
        !           731:       b1->next = found;
        !           732:       found = b1;
        !           733:     }
        !           734: 
        !           735:   ALL_BREAKPOINTS (b)
        !           736:     while (b->next
        !           737:           && (sal.pc ? b->next->address == sal.pc
        !           738:               : (b->next->symtab == sal.symtab
        !           739:                  && b->next->line_number == sal.line)))
        !           740:       {
        !           741:        b1 = b->next;
        !           742:        b->next = b1->next;
        !           743:        b1->next = found;
        !           744:        found = b1;
        !           745:       }
        !           746: 
        !           747:   if (found == 0)
        !           748:     error ("No breakpoint at %s.", arg);
        !           749: 
        !           750:   if (found->next) from_tty = 1; /* Alwats report if deleted more than one */
        !           751:   if (from_tty) printf ("Deleted breakpoint%s ", found->next ? "s" : "");
        !           752:   while (found)
        !           753:     {
        !           754:       if (from_tty) printf ("%d ", found->number);
        !           755:       b1 = found->next;
        !           756:       delete_breakpoint (found);
        !           757:       found = b1;
        !           758:     }
        !           759:   if (from_tty) putchar ('\n');
        !           760: }
        !           761: 
        !           762: /* Delete breakpoint number BNUM if it is a `delete' breakpoint.
        !           763:    This is called after breakpoint BNUM has been hit.
        !           764:    Also delete any breakpoint numbered -3 unless there are breakpoint
        !           765:    commands to be executed.  */
        !           766: 
        !           767: void
        !           768: breakpoint_auto_delete (bnum)
        !           769:      int bnum;
        !           770: {
        !           771:   register struct breakpoint *b;
        !           772:   if (bnum != 0)
        !           773:     ALL_BREAKPOINTS (b)
        !           774:       if (b->number == bnum)
        !           775:        {
        !           776:          if (b->enable == delete)
        !           777:            delete_breakpoint (b);
        !           778:          break;
        !           779:        }
        !           780:   if (breakpoint_commands == 0)
        !           781:     clear_momentary_breakpoints ();
        !           782: }
        !           783: 
        !           784: static void
        !           785: delete_breakpoint (bpt)
        !           786:      struct breakpoint *bpt;
        !           787: {
        !           788:   register struct breakpoint *b;
        !           789: 
        !           790:   if (bpt->inserted)
        !           791:     write_memory (bpt->address, bpt->shadow_contents, sizeof break_insn);
        !           792: 
        !           793:   if (breakpoint_chain == bpt)
        !           794:     breakpoint_chain = bpt->next;
        !           795: 
        !           796:   ALL_BREAKPOINTS (b)
        !           797:     if (b->next == bpt)
        !           798:       {
        !           799:        b->next = bpt->next;
        !           800:        break;
        !           801:       }
        !           802: 
        !           803:   check_duplicates (bpt->address);
        !           804: 
        !           805:   free_command_lines (&bpt->commands);
        !           806:   if (bpt->cond)
        !           807:     free (bpt->cond);
        !           808:   free (bpt);
        !           809: }
        !           810: 
        !           811: void map_breakpoint_numbers ();
        !           812: 
        !           813: static void
        !           814: delete_command (arg, from_tty)
        !           815:      char *arg;
        !           816:      int from_tty;
        !           817: {
        !           818:   register struct breakpoint *b, *b1;
        !           819: 
        !           820:   if (arg == 0)
        !           821:     {
        !           822:       if (!from_tty || query ("Delete all breakpoints? "))
        !           823:        {
        !           824:          /* No arg; clear all breakpoints.  */
        !           825:          while (breakpoint_chain)
        !           826:            delete_breakpoint (breakpoint_chain);
        !           827:        }
        !           828:     }
        !           829:   else
        !           830:     map_breakpoint_numbers (arg, delete_breakpoint);
        !           831: }
        !           832: 
        !           833: /* Delete all breakpoints.
        !           834:    Done when new symtabs are loaded, since the break condition expressions
        !           835:    may become invalid, and the breakpoints are probably wrong anyway.  */
        !           836: 
        !           837: void
        !           838: clear_breakpoints ()
        !           839: {
        !           840:   delete_command (0, 0);
        !           841: }
        !           842: 
        !           843: /* Set ignore-count of breakpoint number BPTNUM to COUNT.
        !           844:    If from_tty is nonzero, it prints a message to that effect,
        !           845:    which ends with a period (no newline).  */
        !           846: 
        !           847: void
        !           848: set_ignore_count (bptnum, count, from_tty)
        !           849:      int bptnum, count, from_tty;
        !           850: {
        !           851:   register struct breakpoint *b;
        !           852: 
        !           853:   if (count < 0)
        !           854:     count = 0;
        !           855: 
        !           856:   ALL_BREAKPOINTS (b)
        !           857:     if (b->number == bptnum)
        !           858:       {
        !           859:        b->ignore_count = count;
        !           860:        if (!from_tty)
        !           861:          return;
        !           862:        else if (count == 0)
        !           863:          printf ("Will stop next time breakpoint %d is reached.", bptnum);
        !           864:        else if (count == 1)
        !           865:          printf ("Will ignore next crossing of breakpoint %d.", bptnum);
        !           866:        else
        !           867:          printf ("Will ignore next %d crossings of breakpoint %d.",
        !           868:                  count, bptnum);
        !           869:        return;
        !           870:       }
        !           871: 
        !           872:   error ("No breakpoint number %d.", bptnum);
        !           873: }
        !           874: 
        !           875: /* Command to set ignore-count of breakpoint N to COUNT.  */
        !           876: 
        !           877: static void
        !           878: ignore_command (args, from_tty)
        !           879:      char *args;
        !           880:      int from_tty;
        !           881: {
        !           882:   register char *p = args;
        !           883:   register int num;
        !           884: 
        !           885:   if (p == 0)
        !           886:     error_no_arg ("a breakpoint number");
        !           887:   
        !           888:   while (*p >= '0' && *p <= '9') p++;
        !           889:   if (*p && *p != ' ' && *p != '\t')
        !           890:     error ("First argument must be a breakpoint number.");
        !           891: 
        !           892:   num = atoi (args);
        !           893: 
        !           894:   if (*p == 0)
        !           895:     error ("Second argument (specified ignore-count) is missing.");
        !           896: 
        !           897:   set_ignore_count (num, parse_and_eval_address (p), from_tty);
        !           898:   printf ("\n");
        !           899: }
        !           900: 
        !           901: /* Call FUNCTION on each of the breakpoints
        !           902:    whose numbers are given in ARGS.  */
        !           903: 
        !           904: static void
        !           905: map_breakpoint_numbers (args, function)
        !           906:      char *args;
        !           907:      void (*function) ();
        !           908: {
        !           909:   register char *p = args;
        !           910:   register char *p1;
        !           911:   register int num;
        !           912:   register struct breakpoint *b;
        !           913: 
        !           914:   if (p == 0)
        !           915:     error_no_arg ("one or more breakpoint numbers");
        !           916: 
        !           917:   while (*p)
        !           918:     {
        !           919:       p1 = p;
        !           920:       while (*p1 >= '0' && *p1 <= '9') p1++;
        !           921:       if (*p1 && *p1 != ' ' && *p1 != '\t')
        !           922:        error ("Arguments must be breakpoint numbers.");
        !           923: 
        !           924:       num = atoi (p);
        !           925: 
        !           926:       ALL_BREAKPOINTS (b)
        !           927:        if (b->number == num)
        !           928:          {
        !           929:            function (b);
        !           930:            goto win;
        !           931:          }
        !           932:       printf ("No breakpoint number %d.\n", num);
        !           933:     win:
        !           934:       p = p1;
        !           935:       while (*p == ' ' || *p == '\t') p++;
        !           936:     }
        !           937: }
        !           938: 
        !           939: static void
        !           940: enable_breakpoint (bpt)
        !           941:      struct breakpoint *bpt;
        !           942: {
        !           943:   bpt->enable = enabled;
        !           944: 
        !           945:   check_duplicates (bpt->address);
        !           946: }
        !           947: 
        !           948: static void
        !           949: enable_command (args)
        !           950:      char *args;
        !           951: {
        !           952:   map_breakpoint_numbers (args, enable_breakpoint);
        !           953: }
        !           954: 
        !           955: static void
        !           956: disable_breakpoint (bpt)
        !           957:      struct breakpoint *bpt;
        !           958: {
        !           959:   bpt->enable = disabled;
        !           960: 
        !           961:   check_duplicates (bpt->address);
        !           962: }
        !           963: 
        !           964: static void
        !           965: disable_command (args)
        !           966:      char *args;
        !           967: {
        !           968:   register struct breakpoint *bpt;
        !           969:   if (args == 0)
        !           970:     ALL_BREAKPOINTS (bpt)
        !           971:       disable_breakpoint (bpt);
        !           972:   else
        !           973:     map_breakpoint_numbers (args, disable_breakpoint);
        !           974: }
        !           975: 
        !           976: static void
        !           977: enable_once_breakpoint (bpt)
        !           978:      struct breakpoint *bpt;
        !           979: {
        !           980:   bpt->enable = temporary;
        !           981: 
        !           982:   check_duplicates (bpt->address);
        !           983: }
        !           984: 
        !           985: static void
        !           986: enable_once_command (args)
        !           987:      char *args;
        !           988: {
        !           989:   map_breakpoint_numbers (args, enable_once_breakpoint);
        !           990: }
        !           991: 
        !           992: static void
        !           993: enable_delete_breakpoint (bpt)
        !           994:      struct breakpoint *bpt;
        !           995: {
        !           996:   bpt->enable = delete;
        !           997: 
        !           998:   check_duplicates (bpt->address);
        !           999: }
        !          1000: 
        !          1001: static void
        !          1002: enable_delete_command (args)
        !          1003:      char *args;
        !          1004: {
        !          1005:   map_breakpoint_numbers (args, enable_delete_breakpoint);
        !          1006: }
        !          1007: 
        !          1008: 
        !          1009: /* Chain containing all defined enable commands.  */
        !          1010: 
        !          1011: struct cmd_list_element *enablelist;
        !          1012: 
        !          1013: extern struct cmd_list_element *cmdlist;
        !          1014: 
        !          1015: static
        !          1016: initialize ()
        !          1017: {
        !          1018:   breakpoint_chain = 0;
        !          1019:   breakpoint_count = 0;
        !          1020:   enablelist = 0;
        !          1021: 
        !          1022:   add_com ("ignore", class_breakpoint, ignore_command,
        !          1023:           "Set ignore-count of breakpoint number N to COUNT.");
        !          1024: 
        !          1025:   add_com ("commands", class_breakpoint, commands_command,
        !          1026:           "Set commands to be executed when a breakpoint is hit.\n\
        !          1027: Give breakpoint number as argument after \"commands\".\n\
        !          1028: The commands themselves follow starting on the next line.\n\
        !          1029: Type a line containing \"end\" to indicate the end of them.\n\
        !          1030: Give \"silent\" as the first line to make the breakpoint silent;\n\
        !          1031: then no output is printed when it is hit, except what the commands print.");
        !          1032: 
        !          1033:   add_com ("condition", class_breakpoint, condition_command,
        !          1034:           "Specify breakpoint number N to break only if COND is true.\n\
        !          1035: N is an integer; COND is a C expression to be evaluated whenever\n\
        !          1036: breakpoint N is reached.  Actually break only when COND is nonzero.");
        !          1037: 
        !          1038:   add_com ("tbreak", class_breakpoint, tbreak_command,
        !          1039:           "Set a temporary breakpoint.  Args like \"break\" command.\n\
        !          1040: Like \"break\" except the breakpoint is only enabled temporarily,\n\
        !          1041: so it will be disabled when hit.  Equivalent to \"break\" followed\n\
        !          1042: by using \"enable once\" on the breakpoint number.");
        !          1043: 
        !          1044:   add_prefix_cmd ("enable", class_breakpoint, enable_command,
        !          1045:                  "Enable some breakpoints.  Give breakpoint numbers as arguments.\n\
        !          1046: With no subcommand, breakpoints are enabled until you command otherwise.\n\
        !          1047: This is used to cancel the effect of the \"disable\" command.\n\
        !          1048: With a subcommand you can enable temporarily.",
        !          1049:                  &enablelist, "enable ", 1, &cmdlist);
        !          1050: 
        !          1051:   add_cmd ("delete", 0, enable_delete_command,
        !          1052:           "Enable breakpoints and delete when hit.  Give breakpoint numbers.\n\
        !          1053: If a breakpoint is hit while enabled in this fashion, it is deleted.",
        !          1054:           &enablelist);
        !          1055: 
        !          1056:   add_cmd ("once", 0, enable_once_command,
        !          1057:           "Enable breakpoints for one hit.  Give breakpoint numbers.\n\
        !          1058: If a breakpoint is hit while enabled in this fashion, it becomes disabled.\n\
        !          1059: See the \"tbreak\" command which sets a breakpoint and enables it once.",
        !          1060:           &enablelist);
        !          1061: 
        !          1062:   add_com ("disable", class_breakpoint, disable_command,
        !          1063:           "Disable some breakpoints.  Give breakpoint numbers as arguments.\n\
        !          1064: With no arguments, disable all breakpoints.\n\
        !          1065: A disabled breakpoint is not forgotten,\n\
        !          1066: but it has no effect until enabled again.");
        !          1067:   add_com_alias ("dis", "disable", class_breakpoint, 1);
        !          1068: 
        !          1069:   add_com ("delete", class_breakpoint, delete_command,
        !          1070:           "Delete breakpoints, specifying breakpoint numbers; or all breakpoints.\n\
        !          1071: Arguments are breakpoint numbers with spaces in between.\n\
        !          1072: To delete all breakpoints, give no argument.");
        !          1073:   add_com_alias ("d", "delete", class_breakpoint, 1);
        !          1074: 
        !          1075:   add_com ("clear", class_breakpoint, clear_command,
        !          1076:           "Clear breakpoint at specified line or function.\n\
        !          1077: Argument may be line number, function name, or \"*\" and an address.\n\
        !          1078: If line number is specified, all breakpoints in that line are cleared.\n\
        !          1079: If function is specified, breakpoints at beginning of function are cleared.\n\
        !          1080: If an address is specified, breakpoints at that address are cleared.\n\n\
        !          1081: With no argument, clears all breakpoints in the line that the selected frame\n\
        !          1082: is executing in.\n\
        !          1083: \n\
        !          1084: See also the \"delete\" command which clears breakpoints by number.");
        !          1085: 
        !          1086:   add_com ("break", class_breakpoint, break_command,
        !          1087:           "Set breakpoint at specified line or function.\n\
        !          1088: Argument may be line number, function name, or \"*\" and an address.\n\
        !          1089: If line number is specified, break at start of code for that line.\n\
        !          1090: If function is specified, break at start of code for that function.\n\
        !          1091: If an address is specified, break at that exact address.\n\
        !          1092: With no arg, uses current execution address of selected stack frame.\n\
        !          1093: This is useful for breaking on return to a stack frame.\n\
        !          1094: \n\
        !          1095: Multiple breakpoints at one place are permitted, and useful if conditional.\n\
        !          1096: \n\
        !          1097: Do \"help breakpoints\" for info on other commands dealing with breakpoints.");
        !          1098:   add_com_alias ("b", "break", class_run, 1);
        !          1099:   add_com_alias ("br", "break", class_run, 1);
        !          1100:   add_com_alias ("bre", "break", class_run, 1);
        !          1101:   add_com_alias ("brea", "break", class_run, 1);
        !          1102: 
        !          1103:   add_info ("breakpoints", breakpoints_info,
        !          1104:            "Status of all breakpoints, or breakpoint number NUMBER.\n\
        !          1105: Second column is \"y\" for enabled breakpoint, \"n\" for disabled,\n\
        !          1106: \"o\" for enabled once (disable when hit), \"d\" for enable but delete when hit.\n\
        !          1107: Then come the address and the file/line number.\n\n\
        !          1108: Convenience variable \"$_\" and default examine address for \"x\"\n\
        !          1109: are set to the address of the last breakpoint listed.");
        !          1110: }
        !          1111: 
        !          1112: END_FILE

unix.superglobalmegacorp.com

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