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

1.1     ! root        1: /* Start and stop the inferior process, for GDB.
        !             2:    Copyright (C) 1986, 1987, 1988 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: #include "inferior.h"
        !            27: #include "wait.h"
        !            28: 
        !            29: #include <stdio.h>
        !            30: #include <signal.h>
        !            31: #include <a.out.h>
        !            32: #include <sys/file.h>
        !            33: 
        !            34: #ifdef UMAX_PTRACE
        !            35: #include <sys/param.h>
        !            36: #include <sys/ptrace.h>
        !            37: #endif UMAX_PTRACE
        !            38: 
        !            39: extern char *sys_siglist[];
        !            40: extern int errno;
        !            41: 
        !            42: /* Tables of how to react to signals; the user sets them.  */
        !            43: 
        !            44: static char signal_stop[NSIG];
        !            45: static char signal_print[NSIG];
        !            46: static char signal_program[NSIG];
        !            47: 
        !            48: /* Nonzero if breakpoints are now inserted in the inferior.  */
        !            49: 
        !            50: static int breakpoints_inserted;
        !            51: 
        !            52: /* Function inferior was in as of last step command.  */
        !            53: 
        !            54: static struct symbol *step_start_function;
        !            55: 
        !            56: /* This is the sequence of bytes we insert for a breakpoint.  */
        !            57: 
        !            58: static char break_insn[] = BREAKPOINT;
        !            59: 
        !            60: /* Nonzero => address for special breakpoint for resuming stepping.  */ 
        !            61: 
        !            62: static CORE_ADDR step_resume_break_address;
        !            63: 
        !            64: /* Original contents of the byte where the special breakpoint is.  */
        !            65: 
        !            66: static char step_resume_break_shadow[sizeof break_insn];
        !            67: 
        !            68: /* Nonzero means the special breakpoint is a duplicate
        !            69:    so it has not itself been inserted.  */
        !            70: 
        !            71: static int step_resume_break_duplicate;
        !            72: 
        !            73: /* Nonzero if we are expecting a trace trap and should proceed from it.
        !            74:    2 means expecting 2 trace traps and should continue both times.
        !            75:    That occurs when we tell sh to exec the program: we will get
        !            76:    a trap after the exec of sh and a second when the program is exec'd.  */
        !            77: 
        !            78: static int trap_expected;
        !            79: 
        !            80: /* Nonzero if the next time we try to continue the inferior, it will
        !            81:    step one instruction and generate a spurious trace trap.
        !            82:    This is used to compensate for a bug in HP-UX.  */
        !            83: 
        !            84: static int trap_expected_after_continue;
        !            85: 
        !            86: /* Nonzero means expecting a trace trap
        !            87:    and should stop the inferior and return silently when it happens.  */
        !            88: 
        !            89: static int stop_after_trap;
        !            90: 
        !            91: /* Nonzero means expecting a trace trap due to attaching to a process.  */
        !            92: 
        !            93: static int stop_after_attach;
        !            94: 
        !            95: /* Nonzero if pc has been changed by the debugger
        !            96:    since the inferior stopped.  */
        !            97: 
        !            98: int pc_changed;
        !            99: 
        !           100: /* Nonzero if debugging a remote machine via a serial link or ethernet.  */
        !           101: 
        !           102: int remote_debugging;
        !           103: 
        !           104: /* Save register contents here when about to pop a stack dummy frame.  */
        !           105: 
        !           106: char stop_registers[REGISTER_BYTES];
        !           107: 
        !           108: /* Nonzero if program stopped due to error trying to insert breakpoints.  */
        !           109: 
        !           110: static int breakpoints_failed;
        !           111: 
        !           112: /* Nonzero if inferior is in sh before our program got exec'd.  */
        !           113: 
        !           114: static int running_in_shell;
        !           115: 
        !           116: /* Nonzero after stop if current stack frame should be printed.  */
        !           117: 
        !           118: static int stop_print_frame;
        !           119: 
        !           120: static void insert_step_breakpoint ();
        !           121: static void remove_step_breakpoint ();
        !           122: static void wait_for_inferior ();
        !           123: static void normal_stop ();
        !           124: 
        !           125: START_FILE
        !           126: 
        !           127: /* Clear out all variables saying what to do when inferior is continued.
        !           128:    First do this, then set the ones you want, then call `proceed'.  */
        !           129: 
        !           130: void
        !           131: clear_proceed_status ()
        !           132: {
        !           133:   trap_expected = 0;
        !           134:   step_range_start = 0;
        !           135:   step_range_end = 0;
        !           136:   step_frame = 0;
        !           137:   step_over_calls = -1;
        !           138:   step_resume_break_address = 0;
        !           139:   stop_after_trap = 0;
        !           140:   stop_after_attach = 0;
        !           141: 
        !           142:   /* Discard any remaining commands left by breakpoint we had stopped at.  */
        !           143:   clear_breakpoint_commands ();
        !           144: }
        !           145: 
        !           146: /* Basic routine for continuing the program in various fashions.
        !           147: 
        !           148:    ADDR is the address to resume at, or -1 for resume where stopped.
        !           149:    SIGNAL is the signal to give it, or 0 for none,
        !           150:      or -1 for act according to how it stopped.
        !           151:    STEP is nonzero if should trap after one instruction.
        !           152:      -1 means return after that and print nothing.
        !           153:      You should probably set various step_... variables
        !           154:      before calling here, if you are stepping.
        !           155: 
        !           156:    You should call clear_proceed_status before calling proceed.  */
        !           157: 
        !           158: void
        !           159: proceed (addr, signal, step)
        !           160:      CORE_ADDR addr;
        !           161:      int signal;
        !           162:      int step;
        !           163: {
        !           164:   int oneproc = 0;
        !           165: 
        !           166:   if (step > 0)
        !           167:     step_start_function = find_pc_function (read_pc ());
        !           168:   if (step < 0)
        !           169:     stop_after_trap = 1;
        !           170: 
        !           171:   if (addr == -1)
        !           172:     {
        !           173:       /* If there is a breakpoint at the address we will resume at,
        !           174:         step one instruction before inserting breakpoints
        !           175:         so that we do not stop right away.  */
        !           176: 
        !           177:       if (!pc_changed && breakpoint_here_p (read_pc ()))
        !           178:        oneproc = 1;
        !           179:     }
        !           180:   else
        !           181:     write_register (PC_REGNUM, addr);
        !           182: 
        !           183:   if (trap_expected_after_continue)
        !           184:     {
        !           185:       /* If (step == 0), a trap will be automatically generated after
        !           186:         the first instruction is executed.  Force step one
        !           187:         instruction to clear this condition.  This should not occur
        !           188:         if step is nonzero, but it is harmless in that case.  */
        !           189:       oneproc = 1;
        !           190:       trap_expected_after_continue = 0;
        !           191:     }
        !           192: 
        !           193:   if (oneproc)
        !           194:     /* We will get a trace trap after one instruction.
        !           195:        Continue it automatically and insert breakpoints then.  */
        !           196:     trap_expected = 1;
        !           197:   else
        !           198:     {
        !           199:       int temp = insert_breakpoints ();
        !           200:       if (temp)
        !           201:        {
        !           202:          print_sys_errmsg ("ptrace", temp);
        !           203:          error ("Cannot insert breakpoints.\n\
        !           204: The same program may be running in another process.");
        !           205:        }
        !           206:       breakpoints_inserted = 1;
        !           207:     }
        !           208: 
        !           209:   /* Install inferior's terminal modes.  */
        !           210:   terminal_inferior ();
        !           211: 
        !           212:   if (signal >= 0)
        !           213:     stop_signal = signal;
        !           214:   /* If this signal should not be seen by program,
        !           215:      give it zero.  Used for debugging signals.  */
        !           216:   else if (stop_signal < NSIG && !signal_program[stop_signal])
        !           217:     stop_signal= 0;
        !           218: 
        !           219:   /* Resume inferior.  */
        !           220:   resume (oneproc || step, stop_signal);
        !           221: 
        !           222:   /* Wait for it to stop (if not standalone)
        !           223:      and in any case decode why it stopped, and act accordingly.  */
        !           224: 
        !           225:   wait_for_inferior ();
        !           226:   normal_stop ();
        !           227: }
        !           228: 
        !           229: /* Writing the inferior pc as a register calls this function
        !           230:    to inform infrun that the pc has been set in the debugger.  */
        !           231: 
        !           232: writing_pc (val)
        !           233:      CORE_ADDR val;
        !           234: {
        !           235:   stop_pc = val;
        !           236:   pc_changed = 1;
        !           237: }
        !           238: 
        !           239: /* Start an inferior process for the first time.
        !           240:    Actually it was started by the fork that created it,
        !           241:    but it will have stopped one instruction after execing sh.
        !           242:    Here we must get it up to actual execution of the real program.  */
        !           243: 
        !           244: start_inferior ()
        !           245: {
        !           246:   /* We will get a trace trap after one instruction.
        !           247:      Continue it automatically.  Eventually (after shell does an exec)
        !           248:      it will get another trace trap.  Then insert breakpoints and continue.  */
        !           249:   trap_expected = 2;
        !           250:   running_in_shell = 0;                /* Set to 1 at first SIGTRAP, 0 at second.  */
        !           251:   trap_expected_after_continue = 0;
        !           252:   breakpoints_inserted = 0;
        !           253:   mark_breakpoints_out ();
        !           254: 
        !           255:   /* Set up the "saved terminal modes" of the inferior
        !           256:      based on what modes we are starting it with.  */
        !           257:   terminal_init_inferior ();
        !           258: 
        !           259:   /* Install inferior's terminal modes.  */
        !           260:   terminal_inferior ();
        !           261: 
        !           262:   if (remote_debugging)
        !           263:     {
        !           264:       trap_expected = 0;
        !           265:       fetch_inferior_registers();
        !           266:       set_current_frame (read_register(FP_REGNUM));
        !           267:       stop_frame = get_current_frame();
        !           268:       inferior_pid = 3;
        !           269:       if (insert_breakpoints())
        !           270:        fatal("Can't insert breakpoints");
        !           271:       breakpoints_inserted = 1;
        !           272:       proceed(-1, -1, 0);
        !           273:     }
        !           274:   else
        !           275:     {
        !           276:       wait_for_inferior ();
        !           277:       normal_stop ();
        !           278:     }
        !           279: }
        !           280: 
        !           281: /* Start remote-debugging of a machine over a serial link.  */
        !           282: 
        !           283: void
        !           284: start_remote ()
        !           285: {
        !           286:   clear_proceed_status ();
        !           287:   running_in_shell = 0;
        !           288:   trap_expected = 0;
        !           289:   inferior_pid = 3;
        !           290:   breakpoints_inserted = 0;
        !           291:   mark_breakpoints_out ();
        !           292:   wait_for_inferior ();
        !           293:   normal_stop();
        !           294: }
        !           295: 
        !           296: #ifdef ATTACH_DETACH
        !           297: 
        !           298: /* Attach to process PID, then initialize for debugging it
        !           299:    and wait for the trace-trap that results from attaching.  */
        !           300: 
        !           301: void
        !           302: attach_program (pid)
        !           303:      int pid;
        !           304: {
        !           305:   attach (pid);
        !           306:   inferior_pid = pid;
        !           307: 
        !           308:   mark_breakpoints_out ();
        !           309:   terminal_init_inferior ();
        !           310:   clear_proceed_status ();
        !           311:   stop_after_attach = 1;
        !           312:   /*proceed (-1, 0, -2);*/
        !           313:   wait_for_inferior ();
        !           314:   normal_stop ();
        !           315: }
        !           316: #endif /* ATTACH_DETACH */
        !           317: 
        !           318: /* Wait for control to return from inferior to debugger.
        !           319:    If inferior gets a signal, we may decide to start it up again
        !           320:    instead of returning.  That is why there is a loop in this function.
        !           321:    When this function actually returns it means the inferior
        !           322:    should be left stopped and GDB should read more commands.  */
        !           323: 
        !           324: static void
        !           325: wait_for_inferior ()
        !           326: {
        !           327:   register int pid;
        !           328:   WAITTYPE w;
        !           329:   CORE_ADDR pc;
        !           330:   int tem;
        !           331:   int another_trap;
        !           332:   int random_signal;
        !           333:   CORE_ADDR stop_sp;
        !           334:   int stop_step_resume_break;
        !           335:   int newmisc;
        !           336:   int newfun_pc;
        !           337:   struct symbol *newfun;
        !           338:   struct symtab_and_line sal;
        !           339:   int prev_pc;
        !           340: 
        !           341:   prev_pc = read_pc ();
        !           342: 
        !           343:   while (1)
        !           344:     {
        !           345:       if (remote_debugging)
        !           346:        remote_wait (&w);
        !           347:       else
        !           348:        {
        !           349:          pid = wait (&w);
        !           350:          if (pid != inferior_pid)
        !           351:            continue;
        !           352:        }
        !           353: 
        !           354:       pc_changed = 0;
        !           355:       fetch_inferior_registers ();
        !           356:       stop_pc = read_pc ();
        !           357:       set_current_frame (read_register (FP_REGNUM));
        !           358:       stop_frame = get_current_frame ();
        !           359:       stop_sp = read_register (SP_REGNUM);
        !           360:       another_trap = 0;
        !           361:       stop_breakpoint = 0;
        !           362:       stop_step = 0;
        !           363:       stop_stack_dummy = 0;
        !           364:       stop_print_frame = 1;
        !           365:       stop_step_resume_break = 0;
        !           366:       random_signal = 0;
        !           367:       breakpoints_failed = 0;
        !           368: 
        !           369:       /* Look at the cause of the stop, and decide what to do.
        !           370:         The alternatives are:
        !           371:         1) break; to really stop and return to the debugger,
        !           372:         2) drop through to start up again
        !           373:           (set another_trap to 1 to single step once)
        !           374:         3) set random_signal to 1, and the decision between 1 and 2 
        !           375:           will be made according to the signal handling tables.  */
        !           376: 
        !           377:       if (WIFEXITED (w))
        !           378:        {
        !           379:          terminal_ours_for_output ();
        !           380:          if (WRETCODE (w))
        !           381:            printf ("\nProgram exited with code 0%o.\n", WRETCODE (w));
        !           382:          else
        !           383:            printf ("\nProgram exited normally.\n");
        !           384:          fflush (stdout);
        !           385:          inferior_died ();
        !           386:          stop_print_frame = 0;
        !           387:          break;
        !           388:        }
        !           389:       else if (!WIFSTOPPED (w))
        !           390:        {
        !           391:          kill_inferior ();
        !           392:          stop_print_frame = 0;
        !           393:          stop_signal = WTERMSIG (w);
        !           394:          terminal_ours_for_output ();
        !           395:          printf ("\nProgram terminated with signal %d, %s\n",
        !           396:                  stop_signal,
        !           397:                  stop_signal < NSIG
        !           398:                  ? sys_siglist[stop_signal]
        !           399:                  : "(undocumented)");
        !           400:          printf ("The inferior process no longer exists.\n");
        !           401:          fflush (stdout);
        !           402:          break;
        !           403:        }
        !           404:       else
        !           405:        {
        !           406:          stop_signal = WSTOPSIG (w);
        !           407: 
        !           408:          /* First, distinguish signals caused by the debugger from signals
        !           409:             that have to do with the program's own actions.
        !           410:             Note that breakpoint insns may cause SIGTRAP or SIGILL
        !           411:             or SIGEMT, depending on the operating system version.
        !           412:             Here we detect when a SIGILL or SIGEMT is really a breakpoint
        !           413:             and change it to SIGTRAP.  */
        !           414: 
        !           415:          if (stop_signal == SIGTRAP
        !           416:              || (breakpoints_inserted &&
        !           417:                  (stop_signal == SIGILL
        !           418:                   || stop_signal == SIGEMT))
        !           419:              || stop_after_attach)
        !           420:            {
        !           421:              if (stop_signal == SIGTRAP && stop_after_trap)
        !           422:                {
        !           423:                  stop_print_frame = 0;
        !           424:                  break;
        !           425:                }
        !           426:              if (stop_after_attach)
        !           427:                break;
        !           428:              /* Don't even think about breakpoints
        !           429:                 if still running the shell that will exec the program
        !           430:                 or if just proceeded over a breakpoint.  */
        !           431:              if (stop_signal == SIGTRAP && trap_expected)
        !           432:                stop_breakpoint = 0;
        !           433:              else
        !           434:                /* See if there is a breakpoint at the current PC.  */
        !           435: #if DECR_PC_AFTER_BREAK
        !           436:                /* Notice the case of stepping through a jump
        !           437:                   that leads just after a breakpoint.
        !           438:                   Don't confuse that with hitting the breakpoint.
        !           439:                   What we check for is that 1) stepping is going on
        !           440:                   and 2) the pc before the last insn does not match
        !           441:                   the address of the breakpoint before the current pc.  */
        !           442:                if (!(prev_pc != stop_pc - DECR_PC_AFTER_BREAK
        !           443:                      && step_range_end && !step_resume_break_address))
        !           444: #endif /* DECR_PC_AFTER_BREAK not zero */
        !           445:                  {
        !           446:                    select_frame (stop_frame, 0); /* For condition exprs. */
        !           447:                    stop_breakpoint = breakpoint_stop_status (stop_pc, stop_frame);
        !           448:                    /* Following in case break condition called a function.  */
        !           449:                    stop_print_frame = 1;
        !           450:                    if (stop_breakpoint && DECR_PC_AFTER_BREAK)
        !           451:                      {
        !           452:                        stop_pc -= DECR_PC_AFTER_BREAK;
        !           453:                        write_register (PC_REGNUM, stop_pc);
        !           454:                        pc_changed = 0;
        !           455:                      }
        !           456:                  }
        !           457:              /* See if we stopped at the special breakpoint for
        !           458:                 stepping over a subroutine call.  */
        !           459:              if (stop_pc - DECR_PC_AFTER_BREAK == step_resume_break_address)
        !           460:                {
        !           461:                  stop_step_resume_break = 1;
        !           462:                  if (DECR_PC_AFTER_BREAK)
        !           463:                    {
        !           464:                      stop_pc -= DECR_PC_AFTER_BREAK;
        !           465:                      write_register (PC_REGNUM, stop_pc);
        !           466:                      pc_changed = 0;
        !           467:                    }
        !           468:                }
        !           469: 
        !           470:              if (stop_signal == SIGTRAP)
        !           471:                random_signal
        !           472:                  = !(stop_breakpoint || trap_expected
        !           473:                      || stop_step_resume_break
        !           474:                      || (stop_sp INNER_THAN stop_pc && stop_pc INNER_THAN stop_frame)
        !           475:                      || (step_range_end && !step_resume_break_address));
        !           476:              else
        !           477:                {
        !           478:                  random_signal
        !           479:                    = !(stop_breakpoint || stop_step_resume_break);
        !           480:                  if (!random_signal)
        !           481:                    stop_signal = SIGTRAP;
        !           482:                }
        !           483:            }
        !           484:          else
        !           485:            random_signal = 1;
        !           486: 
        !           487:          /* For the program's own signals, act according to
        !           488:             the signal handling tables.  */
        !           489: 
        !           490:          if (random_signal
        !           491:              && !(running_in_shell && stop_signal == SIGSEGV))
        !           492:            {
        !           493:              /* Signal not for debugging purposes.  */
        !           494:              int printed = 0;
        !           495: 
        !           496:              if (stop_signal >= NSIG
        !           497:                  || signal_print[stop_signal])
        !           498:                {
        !           499:                  printed = 1;
        !           500:                  terminal_ours_for_output ();
        !           501:                  printf ("\nProgram received signal %d, %s\n",
        !           502:                          stop_signal,
        !           503:                          stop_signal < NSIG
        !           504:                           ? sys_siglist[stop_signal]
        !           505:                           : "(undocumented)");
        !           506:                  fflush (stdout);
        !           507:                }
        !           508:              if (stop_signal >= NSIG
        !           509:                  || signal_stop[stop_signal])
        !           510:                break;
        !           511:              /* If not going to stop, give terminal back
        !           512:                 if we took it away.  */
        !           513:              else if (printed)
        !           514:                terminal_inferior ();
        !           515:            }
        !           516: 
        !           517:          /* Handle cases caused by hitting a breakpoint.  */
        !           518: 
        !           519:          if (!random_signal
        !           520:              && (stop_breakpoint || stop_step_resume_break))
        !           521:            {
        !           522:              /* Does a breakpoint want us to stop?  */
        !           523:              if (stop_breakpoint && stop_breakpoint != -1)
        !           524:                {
        !           525:                  /* 0x1000000 is set in stop_breakpoint as returned by
        !           526:                     breakpoint_status_p to indicate a silent breakpoint.  */
        !           527:                  if (stop_breakpoint > 0 && stop_breakpoint & 0x1000000)
        !           528:                    {
        !           529:                      stop_breakpoint &= ~0x1000000;
        !           530:                      stop_print_frame = 0;
        !           531:                    }
        !           532:                  break;
        !           533:                }
        !           534:              /* But if we have hit the step-resumption breakpoint,
        !           535:                 remove it.  It has done its job getting us here.  */
        !           536:              if (stop_step_resume_break
        !           537:                  && (step_frame == 0 || stop_frame == step_frame))
        !           538:                {
        !           539:                  remove_step_breakpoint ();
        !           540:                  step_resume_break_address = 0;
        !           541:                }
        !           542:              /* Otherwise, must remove breakpoints and single-step
        !           543:                 to get us past the one we hit.  */
        !           544:              else
        !           545:                {
        !           546:                  remove_breakpoints ();
        !           547:                  remove_step_breakpoint ();
        !           548:                  breakpoints_inserted = 0;
        !           549:                  another_trap = 1;
        !           550:                }
        !           551: 
        !           552:              /* We come here if we hit a breakpoint but should not
        !           553:                 stop for it.  Possibly we also were stepping
        !           554:                 and should stop for that.  So fall through and
        !           555:                 test for stepping.  But, if not stepping,
        !           556:                 do not stop.  */
        !           557:            }
        !           558: 
        !           559:          /* If this is the breakpoint at the end of a stack dummy,
        !           560:             just stop silently.  */
        !           561:          if (stop_sp INNER_THAN stop_pc && stop_pc INNER_THAN stop_frame)
        !           562:            {
        !           563:              stop_print_frame = 0;
        !           564:              stop_stack_dummy = 1;
        !           565: #ifdef HP9K320
        !           566:              trap_expected_after_continue = 1;
        !           567: #endif
        !           568:              break;
        !           569:            }
        !           570: 
        !           571:          if (step_resume_break_address)
        !           572:            /* Having a step-resume breakpoint overrides anything
        !           573:               else having to do with stepping commands until
        !           574:               that breakpoint is reached.  */
        !           575:            ;
        !           576:          /* If stepping through a line, keep going if still within it.  */
        !           577:          else if (!random_signal
        !           578:                   && step_range_end
        !           579:                   && stop_pc >= step_range_start
        !           580:                   && stop_pc < step_range_end)
        !           581:            {
        !           582:              /* Don't step through the return from a function
        !           583:                 unless that is the first instruction stepped through.  */
        !           584:              if (ABOUT_TO_RETURN (stop_pc))
        !           585:                {
        !           586:                  stop_step = 1;
        !           587:                  break;
        !           588:                }
        !           589:            }
        !           590: 
        !           591:          /* We stepped out of the stepping range.  See if that was due
        !           592:             to a subroutine call that we should proceed to the end of.  */
        !           593:          else if (!random_signal && step_range_end)
        !           594:            {
        !           595:              newfun = find_pc_function (stop_pc);
        !           596:              newmisc = -1;
        !           597:              if (newfun)
        !           598:                {
        !           599:                  newfun_pc = BLOCK_START (SYMBOL_BLOCK_VALUE (newfun))
        !           600:                    + FUNCTION_START_OFFSET;
        !           601:                }
        !           602:              else
        !           603:                {
        !           604:                  newmisc = find_pc_misc_function (stop_pc);
        !           605:                  if (newmisc >= 0)
        !           606:                    newfun_pc = misc_function_vector[newmisc].address
        !           607:                      + FUNCTION_START_OFFSET;
        !           608:                  else newfun_pc = 0;
        !           609:                }
        !           610:              if (stop_pc == newfun_pc
        !           611:                  && (step_over_calls > 0 || (step_over_calls && newfun == 0)))
        !           612:                {
        !           613:                  /* A subroutine call has happened.  */
        !           614:                  /* Set a special breakpoint after the return */
        !           615:                  step_resume_break_address = SAVED_PC_AFTER_CALL (stop_frame);
        !           616:                  step_resume_break_duplicate
        !           617:                    = breakpoint_here_p (step_resume_break_address);
        !           618:                  if (breakpoints_inserted)
        !           619:                    insert_step_breakpoint ();
        !           620:                }
        !           621:              /* Subroutine call with source code we should not step over.
        !           622:                 Do step to the first line of code in it.  */
        !           623:              else if (stop_pc == newfun_pc && step_over_calls)
        !           624:                {
        !           625:                  SKIP_PROLOGUE (newfun_pc);
        !           626:                  sal = find_pc_line (newfun_pc, 0);
        !           627:                  /* Use the step_resume_break to step until
        !           628:                     the end of the prologue, even if that involves jumps
        !           629:                     (as it seems to on the vax under 4.2).  */
        !           630:                  /* If the prologue ends in the middle of a source line,
        !           631:                     continue to the end of that source line.
        !           632:                     Otherwise, just go to end of prologue.  */
        !           633:                  if (sal.end && sal.pc != newfun_pc)
        !           634:                    newfun_pc = sal.end;
        !           635: 
        !           636:                  if (newfun_pc == stop_pc)
        !           637:                    /* We are already there: stop now.  */
        !           638:                    stop_step = 1;
        !           639:                  else
        !           640:                    /* Put the step-breakpoint there and go until there.  */
        !           641:                    {
        !           642:                      step_resume_break_address = newfun_pc;
        !           643: 
        !           644:                      step_resume_break_duplicate
        !           645:                        = breakpoint_here_p (step_resume_break_address);
        !           646:                      if (breakpoints_inserted)
        !           647:                        insert_step_breakpoint ();
        !           648:                      /* Do not specify what the fp should be when we stop
        !           649:                         since on some machines the prologue
        !           650:                         is where the new fp value is established.  */
        !           651:                      step_frame = 0;
        !           652:                      /* And make sure stepping stops right away then.  */
        !           653:                      step_range_end = step_range_start;
        !           654:                    }
        !           655:                }
        !           656:              /* No subroutince call; stop now.  */
        !           657:              else
        !           658:                {
        !           659:                  stop_step = 1;
        !           660:                  break;
        !           661:                }
        !           662:            }
        !           663:        }
        !           664: 
        !           665:       /* Save the pc before execution, to compare with pc after stop.  */
        !           666:       prev_pc = read_pc ();
        !           667: 
        !           668:       /* If we did not do break;, it means we should keep
        !           669:         running the inferior and not return to debugger.  */
        !           670: 
        !           671:       /* If trap_expected is 2, it means continue once more
        !           672:         and insert breakpoints at the next trap.
        !           673:         If trap_expected is 1 and the signal was SIGSEGV, it means
        !           674:         the shell is doing some memory allocation--just resume it
        !           675:         with SIGSEGV.
        !           676:         Otherwise insert breakpoints now, and possibly single step.  */
        !           677: 
        !           678:       if (trap_expected > 1)
        !           679:        {
        !           680:          trap_expected--;
        !           681:          running_in_shell = 1;
        !           682:          resume (0, 0);
        !           683:        }
        !           684:       else if (running_in_shell && stop_signal == SIGSEGV)
        !           685:        {
        !           686:          resume (0, SIGSEGV);
        !           687:        }
        !           688:       else
        !           689:        {
        !           690:          /* Here, we are not awaiting another exec to get
        !           691:             the program we really want to debug.
        !           692:             Insert breakpoints now, unless we are trying
        !           693:             to one-proceed past a breakpoint.  */
        !           694:          running_in_shell = 0;
        !           695:          if (!breakpoints_inserted && !another_trap)
        !           696:            {
        !           697:              insert_step_breakpoint ();
        !           698:              breakpoints_failed = insert_breakpoints ();
        !           699:              if (breakpoints_failed)
        !           700:                break;
        !           701:              breakpoints_inserted = 1;
        !           702:            }
        !           703: 
        !           704:          trap_expected = another_trap;
        !           705: 
        !           706:          if (stop_signal == SIGTRAP)
        !           707:            stop_signal = 0;
        !           708: 
        !           709:          resume ((step_range_end && !step_resume_break_address)
        !           710:                  || trap_expected,
        !           711:                  stop_signal);
        !           712:        }
        !           713:     }
        !           714: }
        !           715: 
        !           716: /* Here to return control to GDB when the inferior stops for real.
        !           717:    Print appropriate messages, remove breakpoints, give terminal our modes.
        !           718: 
        !           719:    RUNNING_IN_SHELL nonzero means the shell got a signal before
        !           720:    exec'ing the program we wanted to run.
        !           721:    STOP_PRINT_FRAME nonzero means print the executing frame
        !           722:    (pc, function, args, file, line number and line text).
        !           723:    BREAKPOINTS_FAILED nonzero means stop was due to error
        !           724:    attempting to insert breakpoints.  */
        !           725: 
        !           726: static void
        !           727: normal_stop ()
        !           728: {
        !           729:   if (breakpoints_failed)
        !           730:     {
        !           731:       terminal_ours_for_output ();
        !           732:       print_sys_errmsg ("ptrace", breakpoints_failed);
        !           733:       printf ("Stopped; cannot insert breakpoints.\n\
        !           734: The same program may be running in another process.\n");
        !           735:     }
        !           736: 
        !           737:   if (inferior_pid)
        !           738:     remove_step_breakpoint ();
        !           739: 
        !           740:   if (inferior_pid && breakpoints_inserted)
        !           741:     if (remove_breakpoints ())
        !           742:       {
        !           743:        terminal_ours_for_output ();
        !           744:        printf ("Cannot remove breakpoints because program is no longer writable.\n\
        !           745: It must be running in another process.\n\
        !           746: Further execution is probably impossible.\n");
        !           747:       }
        !           748: 
        !           749:   breakpoints_inserted = 0;
        !           750: 
        !           751:   /* Delete the breakpoint we stopped at, if it wants to be deleted.
        !           752:      Delete any breakpoint that is to be deleted at the next stop.  */
        !           753: 
        !           754:   breakpoint_auto_delete (stop_breakpoint);
        !           755: 
        !           756:   /* If an auto-display called a function and that got a signal,
        !           757:      delete that auto-display to avoid an infinite recursion.  */
        !           758: 
        !           759:   delete_current_display ();
        !           760: 
        !           761:   if (step_multi && stop_step)
        !           762:     return;
        !           763: 
        !           764:   terminal_ours ();
        !           765: 
        !           766:   if (running_in_shell)
        !           767:     {
        !           768:       if (stop_signal == SIGSEGV)
        !           769:        {
        !           770:          char *exec_file = (char *) get_exec_file (1);
        !           771: 
        !           772:          if (access (exec_file, X_OK) != 0)
        !           773:            printf ("The file \"%s\" is not executable.\n", exec_file);
        !           774:          else
        !           775:            printf ("\
        !           776: You have just encountered a bug in \"sh\".  GDB starts your program\n\
        !           777: by running \"sh\" with a command to exec your program.\n\
        !           778: This is so that \"sh\" will process wildcards and I/O redirection.\n\
        !           779: This time, \"sh\" crashed.\n\
        !           780: \n\
        !           781: One known bug in \"sh\" bites when the environment takes up a lot of space.\n\
        !           782: Try \"info env\" to see the environment; then use \"unset-env\" to kill\n\
        !           783: some variables whose values are large; then do \"run\" again.\n\
        !           784: \n\
        !           785: If that works, you might want to put those \"unset-env\" commands\n\
        !           786: into a \".gdbinit\" file in this directory so they will happen every time.\n");
        !           787:        }
        !           788:       /* Don't confuse user with his program's symbols on sh's data.  */
        !           789:       stop_print_frame = 0;
        !           790:     }
        !           791: 
        !           792:   if (inferior_pid == 0)
        !           793:     return;
        !           794: 
        !           795:   /* Select innermost stack frame except on return from a stack dummy routine,
        !           796:      or if the program has exited.  */
        !           797:   if (!stop_stack_dummy)
        !           798:     {
        !           799:       select_frame (stop_frame, 0);
        !           800: 
        !           801:       if (stop_print_frame)
        !           802:        {
        !           803:          if (stop_breakpoint > 0)
        !           804:            printf ("\nBpt %d, ", stop_breakpoint);
        !           805:          print_sel_frame (stop_step
        !           806:                           && step_frame == stop_frame
        !           807:                           && step_start_function == find_pc_function (stop_pc));
        !           808:          /* Display the auto-display expressions.  */
        !           809:          do_displays ();
        !           810:        }
        !           811:     }
        !           812: 
        !           813:   /* Save the function value return registers
        !           814:      We might be about to restore their previous contents.  */
        !           815:   read_register_bytes (0, stop_registers, REGISTER_BYTES);
        !           816: 
        !           817:   if (stop_stack_dummy)
        !           818:     {
        !           819:       /* Pop the empty frame that contains the stack dummy.  */
        !           820:       POP_FRAME;
        !           821:       select_frame (read_register (FP_REGNUM), 0);
        !           822:     }
        !           823: }
        !           824: 
        !           825: static void
        !           826: insert_step_breakpoint ()
        !           827: {
        !           828:   if (step_resume_break_address && !step_resume_break_duplicate)
        !           829:     {
        !           830:       read_memory (step_resume_break_address,
        !           831:                   step_resume_break_shadow, sizeof break_insn);
        !           832:       write_memory (step_resume_break_address,
        !           833:                    break_insn, sizeof break_insn);
        !           834:     }
        !           835: }
        !           836: 
        !           837: static void
        !           838: remove_step_breakpoint ()
        !           839: {
        !           840:   if (step_resume_break_address && !step_resume_break_duplicate)
        !           841:     write_memory (step_resume_break_address, step_resume_break_shadow,
        !           842:                  sizeof break_insn);
        !           843: }
        !           844: 
        !           845: /* Specify how various signals in the inferior should be handled.  */
        !           846: 
        !           847: static void
        !           848: handle_command (args, from_tty)
        !           849:      char *args;
        !           850:      int from_tty;
        !           851: {
        !           852:   register char *p = args;
        !           853:   int signum;
        !           854:   register int digits, wordlen;
        !           855: 
        !           856:   if (!args)
        !           857:     error_no_arg ("signal to handle");
        !           858: 
        !           859:   while (*p)
        !           860:     {
        !           861:       /* Find the end of the next word in the args.  */
        !           862:       for (wordlen = 0; p[wordlen] && p[wordlen] != ' ' && p[wordlen] != '\t';
        !           863:           wordlen++);
        !           864:       for (digits = 0; p[digits] >= '0' && p[digits] <= '9'; digits++);
        !           865: 
        !           866:       /* If it is all digits, it is signal number to operate on.  */
        !           867:       if (digits == wordlen)
        !           868:        {
        !           869:          signum = atoi (p);
        !           870:          if (signum == SIGTRAP || signum == SIGINT)
        !           871:            {
        !           872:              if (!query ("Signal %d is used by the debugger.\nAre you sure you want to change it? ", signum))
        !           873:                error ("Not confirmed.");
        !           874:            }
        !           875:        }
        !           876:       else if (signum == 0)
        !           877:        error ("First argument is not a signal number.");
        !           878: 
        !           879:       /* Else, if already got a signal number, look for flag words
        !           880:         saying what to do for it.  */
        !           881:       else if (!strncmp (p, "stop", wordlen))
        !           882:        {
        !           883:          signal_stop[signum] = 1;
        !           884:          signal_print[signum] = 1;
        !           885:        }
        !           886:       else if (wordlen >= 2 && !strncmp (p, "print", wordlen))
        !           887:        signal_print[signum] = 1;
        !           888:       else if (wordlen >= 2 && !strncmp (p, "pass", wordlen))
        !           889:        signal_program[signum] = 1;
        !           890:       else if (!strncmp (p, "ignore", wordlen))
        !           891:        signal_program[signum] = 0;
        !           892:       else if (wordlen >= 3 && !strncmp (p, "nostop", wordlen))
        !           893:        signal_stop[signum] = 0;
        !           894:       else if (wordlen >= 4 && !strncmp (p, "noprint", wordlen))
        !           895:        {
        !           896:          signal_print[signum] = 0;
        !           897:          signal_stop[signum] = 0;
        !           898:        }
        !           899:       else if (wordlen >= 4 && !strncmp (p, "nopass", wordlen))
        !           900:        signal_program[signum] = 0;
        !           901:       else if (wordlen >= 3 && !strncmp (p, "noignore", wordlen))
        !           902:        signal_program[signum] = 1;
        !           903:       /* Not a number and not a recognized flag word => complain.  */
        !           904:       else
        !           905:        {
        !           906:          p[wordlen] = 0;
        !           907:          error ("Unrecognized flag word: \"%s\".", p);
        !           908:        }
        !           909: 
        !           910:       /* Find start of next word.  */
        !           911:       p += wordlen;
        !           912:       while (*p == ' ' || *p == '\t') p++;
        !           913:     }
        !           914: 
        !           915:   if (from_tty)
        !           916:     {
        !           917:       /* Show the results.  */
        !           918:       printf ("Number\tStop\tPrint\tPass to program\tDescription\n");
        !           919:       printf ("%d\t", signum);
        !           920:       printf ("%s\t", signal_stop[signum] ? "Yes" : "No");
        !           921:       printf ("%s\t", signal_print[signum] ? "Yes" : "No");
        !           922:       printf ("%s\t\t", signal_program[signum] ? "Yes" : "No");
        !           923:       printf ("%s\n", sys_siglist[signum]);
        !           924:     }
        !           925: }
        !           926: 
        !           927: /* Print current contents of the tables set by the handle command.  */
        !           928: 
        !           929: static void
        !           930: signals_info (signum_exp)
        !           931:      char *signum_exp;
        !           932: {
        !           933:   register int i;
        !           934:   printf ("Number\tStop\tPrint\tPass to program\tDescription\n");
        !           935: 
        !           936:   if (signum_exp)
        !           937:     {
        !           938:       i = parse_and_eval_address (signum_exp);
        !           939:       printf ("%d\t", i);
        !           940:       printf ("%s\t", signal_stop[i] ? "Yes" : "No");
        !           941:       printf ("%s\t", signal_print[i] ? "Yes" : "No");
        !           942:       printf ("%s\t\t", signal_program[i] ? "Yes" : "No");
        !           943:       printf ("%s\n", sys_siglist[i]);
        !           944:       return;
        !           945:     }
        !           946: 
        !           947:   printf ("\n");
        !           948:   for (i = 0; i < NSIG; i++)
        !           949:     {
        !           950:       QUIT;
        !           951:       if (i > 0 && i % 16 == 0)
        !           952:        {
        !           953:          printf ("[Type Return to see more]");
        !           954:          fflush (stdout);
        !           955:          read_line ();
        !           956:        }
        !           957:       printf ("%d\t", i);
        !           958:       printf ("%s\t", signal_stop[i] ? "Yes" : "No");
        !           959:       printf ("%s\t", signal_print[i] ? "Yes" : "No");
        !           960:       printf ("%s\t\t", signal_program[i] ? "Yes" : "No");
        !           961:       printf ("%s\n", sys_siglist[i]);
        !           962:     }
        !           963: 
        !           964:   printf ("\nUse the \"handle\" command to change these tables.\n");
        !           965: }
        !           966: 
        !           967: static
        !           968: initialize ()
        !           969: {
        !           970:   register int i;
        !           971: 
        !           972:   add_info ("signals", signals_info,
        !           973:            "What debugger does when program gets various signals.\n\
        !           974: Specify a signal number as argument to print info on that signal only.");
        !           975: 
        !           976:   add_com ("handle", class_run, handle_command,
        !           977:           "Specify how to handle a signal.\n\
        !           978: Args are signal number followed by flags.\n\
        !           979: Flags allowed are \"stop\", \"print\", \"pass\",\n\
        !           980:  \"nostop\", \"noprint\" or \"nopass\".\n\
        !           981: Print means print a message if this signal happens.\n\
        !           982: Stop means reenter debugger if this signal happens (implies print).\n\
        !           983: Pass means let program see this signal; otherwise program doesn't know.\n\
        !           984: Pass and Stop may be combined.");
        !           985: 
        !           986:   for (i = 0; i < NSIG; i++)
        !           987:     {
        !           988:       signal_stop[i] = 1;
        !           989:       signal_print[i] = 1;
        !           990:       signal_program[i] = 1;
        !           991:     }
        !           992: 
        !           993:   /* Signals caused by debugger's own actions
        !           994:      should not be given to the program afterwards.  */
        !           995:   signal_program[SIGTRAP] = 0;
        !           996:   signal_program[SIGINT] = 0;
        !           997: 
        !           998:   /* Signals that are not errors should not normally enter the debugger.  */
        !           999: #ifdef SIGALRM
        !          1000:   signal_stop[SIGALRM] = 0;
        !          1001:   signal_print[SIGALRM] = 0;
        !          1002: #endif /* SIGALRM */
        !          1003: #ifdef SIGVTALRM
        !          1004:   signal_stop[SIGVTALRM] = 0;
        !          1005:   signal_print[SIGVTALRM] = 0;
        !          1006: #endif /* SIGVTALRM */
        !          1007: #ifdef SIGPROF
        !          1008:   signal_stop[SIGPROF] = 0;
        !          1009:   signal_print[SIGPROF] = 0;
        !          1010: #endif /* SIGPROF */
        !          1011: #ifdef SIGCHLD
        !          1012:   signal_stop[SIGCHLD] = 0;
        !          1013:   signal_print[SIGCHLD] = 0;
        !          1014: #endif /* SIGCHLD */
        !          1015: #ifdef SIGCLD
        !          1016:   signal_stop[SIGCLD] = 0;
        !          1017:   signal_print[SIGCLD] = 0;
        !          1018: #endif /* SIGCLD */
        !          1019: #ifdef SIGIO
        !          1020:   signal_stop[SIGIO] = 0;
        !          1021:   signal_print[SIGIO] = 0;
        !          1022: #endif /* SIGIO */
        !          1023: #ifdef SIGURG
        !          1024:   signal_stop[SIGURG] = 0;
        !          1025:   signal_print[SIGURG] = 0;
        !          1026: #endif /* SIGURG */
        !          1027: }
        !          1028: 
        !          1029: END_FILE

unix.superglobalmegacorp.com

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