15509Slinton /* Copyright (c) 1982 Regents of the University of California */ 25509Slinton 3*6073Slinton static char sccsid[] = "@(#)runcont.c 1.3 03/08/82"; 45509Slinton 55509Slinton /* 65652Slinton * Execution management. 75509Slinton */ 85509Slinton 95509Slinton #include "defs.h" 105509Slinton #include <signal.h> 115509Slinton #include "process.h" 125509Slinton #include "machine.h" 135509Slinton #include "object.h" 145652Slinton #include "main.h" 155509Slinton #include "breakpoint.h" 165509Slinton #include "command.h" 175509Slinton #include "process.rep" 185509Slinton 19*6073Slinton #define MAXNARGS 100 /* maximum number of arguments to RUN */ 205509Slinton 215652Slinton typedef char *String; 225509Slinton 235509Slinton LOCAL BOOLEAN just_started; 245509Slinton LOCAL int argc; 255652Slinton LOCAL String argv[MAXNARGS]; 265652Slinton LOCAL String infile; 275652Slinton LOCAL String outfile; 28*6073Slinton LOCAL PROCESS pbuf; 295509Slinton 305509Slinton /* 315652Slinton * This is a px-related kludge to deal with the possibility 325652Slinton * of object code magically coming from a tmp file. 335509Slinton */ 345509Slinton 355652Slinton LOCAL String mode; 365652Slinton LOCAL String realname; 375652Slinton 385652Slinton setargs(m, r) 395652Slinton char *m, *r; 405652Slinton { 41*6073Slinton mode = m; 42*6073Slinton realname = r; 435652Slinton } 445652Slinton 455652Slinton /* 465652Slinton * Initialize the argument list. 475652Slinton */ 485652Slinton 495509Slinton arginit() 505509Slinton { 51*6073Slinton infile = NIL; 52*6073Slinton outfile = NIL; 53*6073Slinton # if (isvaxpx) 54*6073Slinton argv[0] = mode; 55*6073Slinton argv[1] = objname; 56*6073Slinton if (option('t') && realname == NIL) { 57*6073Slinton argc = 2; 58*6073Slinton } else { 59*6073Slinton argv[2] = realname; 60*6073Slinton argc = 3; 61*6073Slinton } 62*6073Slinton # else 63*6073Slinton argv[0] = objname; 64*6073Slinton argc = 1; 65*6073Slinton # endif 665509Slinton } 675509Slinton 685509Slinton /* 695652Slinton * Add an argument to the list for the debuggee. 705509Slinton */ 715509Slinton 725509Slinton newarg(arg) 735652Slinton String arg; 745509Slinton { 75*6073Slinton if (argc >= MAXNARGS) { 76*6073Slinton error("too many arguments to run"); 77*6073Slinton } 78*6073Slinton argv[argc++] = arg; 795509Slinton } 805509Slinton 815509Slinton /* 825652Slinton * Set the standard input for the debuggee. 835509Slinton */ 845509Slinton 855509Slinton inarg(filename) 865652Slinton String filename; 875509Slinton { 88*6073Slinton if (infile != NIL) { 89*6073Slinton error("multiple input redirects"); 90*6073Slinton } 91*6073Slinton infile = filename; 925509Slinton } 935509Slinton 945509Slinton /* 955652Slinton * Set the standard output for the debuggee. 965652Slinton * Probably should check to avoid overwriting an existing file. 975509Slinton */ 985509Slinton 995509Slinton outarg(filename) 1005652Slinton String filename; 1015509Slinton { 102*6073Slinton if (outfile != NIL) { 103*6073Slinton error("multiple output redirect"); 104*6073Slinton } 105*6073Slinton outfile = filename; 1065509Slinton } 1075509Slinton 1085509Slinton /* 1095652Slinton * Initial start of the process. The idea is to get it to the point 1105652Slinton * where the object code has been loaded but execution has not begun. 1115509Slinton */ 1125509Slinton 1135652Slinton initstart() 1145652Slinton { 115*6073Slinton arginit(); 116*6073Slinton argv[argc] = NIL; 117*6073Slinton process = &pbuf; 118*6073Slinton initcache(process); 119*6073Slinton start(argv, infile, outfile); 1205652Slinton } 1215652Slinton 1225652Slinton /* 1235652Slinton * Run starts debuggee executing. 1245652Slinton */ 1255652Slinton 1265509Slinton run() 1275509Slinton { 128*6073Slinton fixbps(); 129*6073Slinton curline = 0; 130*6073Slinton argv[argc] = NIL; 131*6073Slinton start(argv, infile, outfile); 132*6073Slinton just_started = TRUE; 133*6073Slinton isstopped = FALSE; 134*6073Slinton cont(); 1355509Slinton } 1365509Slinton 1375509Slinton /* 1385652Slinton * Continue execution wherever we left off. 1395509Slinton * 1405509Slinton * Note that this routine never returns. Eventually bpact() will fail 1415509Slinton * and we'll call printstatus or step will call it. 1425509Slinton */ 1435509Slinton 1445509Slinton typedef int INTFUNC(); 1455509Slinton 1465509Slinton LOCAL INTFUNC *dbintr; 1475509Slinton LOCAL intr(); 1485509Slinton 149*6073Slinton #define succeeds == TRUE 150*6073Slinton #define fails == FALSE 1515509Slinton 1525509Slinton cont() 1535509Slinton { 154*6073Slinton dbintr = signal(SIGINT, intr); 155*6073Slinton if (just_started) { 156*6073Slinton just_started = FALSE; 157*6073Slinton } else { 158*6073Slinton if (!isstopped) { 159*6073Slinton error("can't continue execution"); 160*6073Slinton } 161*6073Slinton isstopped = FALSE; 162*6073Slinton step(); 163*6073Slinton } 164*6073Slinton for (;;) { 165*6073Slinton if (single_stepping) { 166*6073Slinton printnews(); 1675509Slinton } else { 168*6073Slinton setallbps(); 169*6073Slinton resume(); 170*6073Slinton unsetallbps(); 171*6073Slinton if (bpact() fails) { 172*6073Slinton printstatus(); 173*6073Slinton } 1745509Slinton } 175*6073Slinton step(); 176*6073Slinton } 177*6073Slinton /* NOTREACHED */ 1785509Slinton } 1795509Slinton 1805509Slinton /* 1815509Slinton * This routine is called if we get an interrupt while "running" px 1825509Slinton * but actually in the debugger. Could happen, for example, while 1835509Slinton * processing breakpoints. 1845509Slinton * 1855509Slinton * We basically just want to keep going; the assumption is 1865509Slinton * that when the process resumes it will get the interrupt 1875509Slinton * which will then be handled. 1885509Slinton */ 1895509Slinton 1905509Slinton LOCAL intr() 1915509Slinton { 192*6073Slinton signal(SIGINT, intr); 1935509Slinton } 1945509Slinton 1955509Slinton fixintr() 1965509Slinton { 197*6073Slinton signal(SIGINT, dbintr); 1985509Slinton } 199