1*22513Sdist /* 2*22513Sdist * Copyright (c) 1980 Regents of the University of California. 3*22513Sdist * All rights reserved. The Berkeley software License Agreement 4*22513Sdist * specifies the terms and conditions for redistribution. 5*22513Sdist */ 65509Slinton 7*22513Sdist #ifndef lint 8*22513Sdist static char sccsid[] = "@(#)runcont.c 5.1 (Berkeley) 06/06/85"; 9*22513Sdist #endif not lint 105509Slinton 115509Slinton /* 125652Slinton * Execution management. 135509Slinton */ 145509Slinton 155509Slinton #include "defs.h" 165509Slinton #include <signal.h> 175509Slinton #include "process.h" 185509Slinton #include "machine.h" 195509Slinton #include "object.h" 205652Slinton #include "main.h" 215509Slinton #include "breakpoint.h" 225509Slinton #include "command.h" 235509Slinton #include "process.rep" 245509Slinton 256073Slinton #define MAXNARGS 100 /* maximum number of arguments to RUN */ 265509Slinton 275652Slinton typedef char *String; 285509Slinton 295509Slinton LOCAL BOOLEAN just_started; 305509Slinton LOCAL int argc; 315652Slinton LOCAL String argv[MAXNARGS]; 325652Slinton LOCAL String infile; 335652Slinton LOCAL String outfile; 346073Slinton LOCAL PROCESS pbuf; 356240Slinton PROCESS *process = &pbuf; 365509Slinton 375509Slinton /* 385652Slinton * This is a px-related kludge to deal with the possibility 395652Slinton * of object code magically coming from a tmp file. 405509Slinton */ 415509Slinton 425652Slinton LOCAL String mode; 435652Slinton LOCAL String realname; 445652Slinton 455652Slinton setargs(m, r) 465652Slinton char *m, *r; 475652Slinton { 486073Slinton mode = m; 496073Slinton realname = r; 505652Slinton } 515652Slinton 525652Slinton /* 535652Slinton * Initialize the argument list. 545652Slinton */ 555652Slinton 565509Slinton arginit() 575509Slinton { 586073Slinton infile = NIL; 596073Slinton outfile = NIL; 606073Slinton # if (isvaxpx) 616073Slinton argv[0] = mode; 626073Slinton argv[1] = objname; 636073Slinton if (option('t') && realname == NIL) { 646073Slinton argc = 2; 656073Slinton } else { 666073Slinton argv[2] = realname; 676073Slinton argc = 3; 686073Slinton } 696073Slinton # else 706073Slinton argv[0] = objname; 716073Slinton argc = 1; 726073Slinton # endif 735509Slinton } 745509Slinton 755509Slinton /* 765652Slinton * Add an argument to the list for the debuggee. 775509Slinton */ 785509Slinton 795509Slinton newarg(arg) 805652Slinton String arg; 815509Slinton { 826073Slinton if (argc >= MAXNARGS) { 836073Slinton error("too many arguments to run"); 846073Slinton } 856073Slinton argv[argc++] = arg; 865509Slinton } 875509Slinton 885509Slinton /* 895652Slinton * Set the standard input for the debuggee. 905509Slinton */ 915509Slinton 925509Slinton inarg(filename) 935652Slinton String filename; 945509Slinton { 956073Slinton if (infile != NIL) { 966073Slinton error("multiple input redirects"); 976073Slinton } 986073Slinton infile = filename; 995509Slinton } 1005509Slinton 1015509Slinton /* 1025652Slinton * Set the standard output for the debuggee. 1035652Slinton * Probably should check to avoid overwriting an existing file. 1045509Slinton */ 1055509Slinton 1065509Slinton outarg(filename) 1075652Slinton String filename; 1085509Slinton { 1096073Slinton if (outfile != NIL) { 1106073Slinton error("multiple output redirect"); 1116073Slinton } 1126073Slinton outfile = filename; 1135509Slinton } 1145509Slinton 1155509Slinton /* 1165652Slinton * Initial start of the process. The idea is to get it to the point 1175652Slinton * where the object code has been loaded but execution has not begun. 1185509Slinton */ 1195509Slinton 1205652Slinton initstart() 1215652Slinton { 1226073Slinton arginit(); 1236073Slinton argv[argc] = NIL; 1246073Slinton initcache(process); 1256073Slinton start(argv, infile, outfile); 1266081Slinton if (process->status != STOPPED) { 1276081Slinton panic("could not start program"); 1286081Slinton } 1295652Slinton } 1305652Slinton 1315652Slinton /* 1325652Slinton * Run starts debuggee executing. 1335652Slinton */ 1345652Slinton 1355509Slinton run() 1365509Slinton { 1376073Slinton fixbps(); 1386073Slinton curline = 0; 1396073Slinton argv[argc] = NIL; 1406073Slinton start(argv, infile, outfile); 1416081Slinton if (process->status == STOPPED) { 1426081Slinton just_started = TRUE; 1436081Slinton isstopped = FALSE; 1446081Slinton cont(); 1456081Slinton } else if (option('r')) { 1466081Slinton panic("could not start program"); 1476081Slinton } 1485509Slinton } 1495509Slinton 1505509Slinton /* 1515652Slinton * Continue execution wherever we left off. 1525509Slinton * 1535509Slinton * Note that this routine never returns. Eventually bpact() will fail 1545509Slinton * and we'll call printstatus or step will call it. 1555509Slinton */ 1565509Slinton 1575509Slinton typedef int INTFUNC(); 1585509Slinton 1595509Slinton LOCAL INTFUNC *dbintr; 1605509Slinton LOCAL intr(); 1615509Slinton 1626073Slinton #define succeeds == TRUE 1636073Slinton #define fails == FALSE 1645509Slinton 1655509Slinton cont() 1665509Slinton { 1676073Slinton dbintr = signal(SIGINT, intr); 1686073Slinton if (just_started) { 1696073Slinton just_started = FALSE; 1706073Slinton } else { 1716073Slinton if (!isstopped) { 1726073Slinton error("can't continue execution"); 1736073Slinton } 1746073Slinton isstopped = FALSE; 1756073Slinton step(); 1766073Slinton } 1776073Slinton for (;;) { 1786073Slinton if (single_stepping) { 1796073Slinton printnews(); 1805509Slinton } else { 1816073Slinton setallbps(); 1826073Slinton resume(); 1836073Slinton unsetallbps(); 1846073Slinton if (bpact() fails) { 1856073Slinton printstatus(); 1866073Slinton } 1875509Slinton } 1886073Slinton step(); 1896073Slinton } 1906073Slinton /* NOTREACHED */ 1915509Slinton } 1925509Slinton 1935509Slinton /* 1945509Slinton * This routine is called if we get an interrupt while "running" px 1955509Slinton * but actually in the debugger. Could happen, for example, while 1965509Slinton * processing breakpoints. 1975509Slinton * 1985509Slinton * We basically just want to keep going; the assumption is 1995509Slinton * that when the process resumes it will get the interrupt 2005509Slinton * which will then be handled. 2015509Slinton */ 2025509Slinton 2035509Slinton LOCAL intr() 2045509Slinton { 2056073Slinton signal(SIGINT, intr); 2065509Slinton } 2075509Slinton 2085509Slinton fixintr() 2095509Slinton { 2106073Slinton signal(SIGINT, dbintr); 2115509Slinton } 212