1*5509Slinton /* Copyright (c) 1982 Regents of the University of California */ 2*5509Slinton 3*5509Slinton static char sccsid[] = "@(#)runcont.c 1.1 01/18/82"; 4*5509Slinton 5*5509Slinton /* 6*5509Slinton * execution management 7*5509Slinton */ 8*5509Slinton 9*5509Slinton #include "defs.h" 10*5509Slinton #include <signal.h> 11*5509Slinton #include "process.h" 12*5509Slinton #include "machine.h" 13*5509Slinton #include "object.h" 14*5509Slinton #include "breakpoint.h" 15*5509Slinton #include "command.h" 16*5509Slinton #include "process.rep" 17*5509Slinton 18*5509Slinton #define MAXNARGS 10 /* maximum number of arguments to RUN */ 19*5509Slinton 20*5509Slinton typedef char *string; 21*5509Slinton 22*5509Slinton LOCAL BOOLEAN just_started; 23*5509Slinton LOCAL int argc; 24*5509Slinton LOCAL string argv[MAXNARGS]; 25*5509Slinton LOCAL string infile; 26*5509Slinton LOCAL string outfile; 27*5509Slinton 28*5509Slinton /* 29*5509Slinton * initialize the argument list 30*5509Slinton */ 31*5509Slinton 32*5509Slinton arginit() 33*5509Slinton { 34*5509Slinton infile = NIL; 35*5509Slinton outfile = NIL; 36*5509Slinton # if (isvaxpx) 37*5509Slinton argv[0] = "px"; 38*5509Slinton argv[1] = "-d"; 39*5509Slinton argv[2] = objname; 40*5509Slinton argc = 3; 41*5509Slinton # else 42*5509Slinton argv[0] = objname; 43*5509Slinton argc = 1; 44*5509Slinton # endif 45*5509Slinton } 46*5509Slinton 47*5509Slinton /* 48*5509Slinton * add an argument to the list for the debuggee 49*5509Slinton */ 50*5509Slinton 51*5509Slinton newarg(arg) 52*5509Slinton string arg; 53*5509Slinton { 54*5509Slinton if (argc >= MAXNARGS) { 55*5509Slinton error("too many arguments"); 56*5509Slinton } 57*5509Slinton argv[argc++] = arg; 58*5509Slinton } 59*5509Slinton 60*5509Slinton /* 61*5509Slinton * set the standard input for the debuggee 62*5509Slinton */ 63*5509Slinton 64*5509Slinton inarg(filename) 65*5509Slinton string filename; 66*5509Slinton { 67*5509Slinton if (infile != NIL) { 68*5509Slinton error("multiple input redirects"); 69*5509Slinton } 70*5509Slinton infile = filename; 71*5509Slinton } 72*5509Slinton 73*5509Slinton /* 74*5509Slinton * set the standard output for the debuggee 75*5509Slinton * should probably check to avoid overwriting an existing file 76*5509Slinton */ 77*5509Slinton 78*5509Slinton outarg(filename) 79*5509Slinton string filename; 80*5509Slinton { 81*5509Slinton if (outfile != NIL) { 82*5509Slinton error("multiple output redirect"); 83*5509Slinton } 84*5509Slinton outfile = filename; 85*5509Slinton } 86*5509Slinton 87*5509Slinton /* 88*5509Slinton * run starts debuggee executing 89*5509Slinton */ 90*5509Slinton 91*5509Slinton run() 92*5509Slinton { 93*5509Slinton fixbps(); 94*5509Slinton curline = 0; 95*5509Slinton start(argv, infile, outfile); 96*5509Slinton just_started = TRUE; 97*5509Slinton isstopped = FALSE; 98*5509Slinton cont(); 99*5509Slinton } 100*5509Slinton 101*5509Slinton /* 102*5509Slinton * continue execution wherever we left off 103*5509Slinton * 104*5509Slinton * Note that this routine never returns. Eventually bpact() will fail 105*5509Slinton * and we'll call printstatus or step will call it. 106*5509Slinton */ 107*5509Slinton 108*5509Slinton typedef int INTFUNC(); 109*5509Slinton 110*5509Slinton LOCAL INTFUNC *dbintr; 111*5509Slinton LOCAL intr(); 112*5509Slinton 113*5509Slinton #define succeeds == TRUE 114*5509Slinton #define fails == FALSE 115*5509Slinton 116*5509Slinton cont() 117*5509Slinton { 118*5509Slinton dbintr = signal(SIGINT, &intr); 119*5509Slinton if (just_started) { 120*5509Slinton just_started = FALSE; 121*5509Slinton } else { 122*5509Slinton if (!isstopped) { 123*5509Slinton error("can't continue execution"); 124*5509Slinton } 125*5509Slinton isstopped = FALSE; 126*5509Slinton step(); 127*5509Slinton } 128*5509Slinton for (;;) { 129*5509Slinton if (single_stepping) { 130*5509Slinton printnews(); 131*5509Slinton } else { 132*5509Slinton setallbps(); 133*5509Slinton resume(); 134*5509Slinton unsetallbps(); 135*5509Slinton if (bpact() fails) { 136*5509Slinton printstatus(); 137*5509Slinton } 138*5509Slinton } 139*5509Slinton step(); 140*5509Slinton } 141*5509Slinton /*NOTREACHED*/ 142*5509Slinton } 143*5509Slinton 144*5509Slinton /* 145*5509Slinton * This routine is called if we get an interrupt while "running" px 146*5509Slinton * but actually in the debugger. Could happen, for example, while 147*5509Slinton * processing breakpoints. 148*5509Slinton * 149*5509Slinton * We basically just want to keep going; the assumption is 150*5509Slinton * that when the process resumes it will get the interrupt 151*5509Slinton * which will then be handled. 152*5509Slinton */ 153*5509Slinton 154*5509Slinton LOCAL intr() 155*5509Slinton { 156*5509Slinton signal(SIGINT, &intr); 157*5509Slinton } 158*5509Slinton 159*5509Slinton fixintr() 160*5509Slinton { 161*5509Slinton signal(SIGINT, &dbintr); 162*5509Slinton } 163