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

unix.superglobalmegacorp.com

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