ack/util/grind/run.c

741 lines
14 KiB
C
Raw Normal View History

1990-08-31 18:22:53 +00:00
/* $Header$ */
/* Running a process and communication */
#include <signal.h>
#include <stdio.h>
#include <assert.h>
#include <alloc.h>
#include "ops.h"
#include "message.h"
#include "position.h"
#include "tree.h"
#include "file.h"
#include "symbol.h"
#include "idf.h"
#include "scope.h"
1990-09-25 17:40:47 +00:00
#include "type.h"
#include "expr.h"
1990-08-31 18:22:53 +00:00
#define MAXARG 128
extern char *strncpy();
1990-09-21 16:58:20 +00:00
extern struct idf *str2idf();
1990-08-31 18:22:53 +00:00
extern char *AObj;
extern FILE *db_out;
extern int debug;
extern char *progname;
extern int child_interrupted;
extern int interrupted;
1990-10-17 17:00:03 +00:00
extern t_lineno currline;
1990-08-31 18:22:53 +00:00
static int child_pid; /* process id of child */
static int to_child, from_child; /* file descriptors for communication */
static int child_status;
static int restoring;
1990-09-21 16:58:20 +00:00
static int fild1[2], fild2[2]; /* pipe file descriptors */
1990-08-31 18:22:53 +00:00
1990-11-12 13:46:31 +00:00
int disable_intr = 1;
1990-08-31 18:22:53 +00:00
int db_ss;
1990-11-12 13:46:31 +00:00
int stack_offset;
void signal_child();
1990-08-31 18:22:53 +00:00
1990-11-12 13:46:31 +00:00
static void catch_sigpipe();
1990-08-31 18:22:53 +00:00
static int stopped();
static int uputm(), ugetm();
1990-10-01 11:44:27 +00:00
static t_addr curr_stop;
p_tree run_command;
1990-08-31 18:22:53 +00:00
1990-11-12 13:46:31 +00:00
static void
ITOBUF(p, l, sz)
register char *p;
long l;
int sz;
{
register int i;
p +=sz;
for (i = sz; i > 0; i--) {
*--p = l;
l >>= 8;
}
}
static long
BUFTOI(p, sz)
register char *p;
int sz;
{
register long l = 0;
register int i;
for (i = sz; i>0; i--) {
l = (l << 8) | (*p++ & 0377);
}
return l;
}
1990-11-12 13:46:31 +00:00
void
1990-08-31 18:22:53 +00:00
init_run()
{
/* take file descriptors so that listing cannot take them */
int i;
for (i = 3; i <= 6; i++) close(i);
1990-08-31 18:22:53 +00:00
if (pipe(fild1) < 0 ||
pipe(fild2) < 0 ||
fild1[0] != 3 ||
fild2[1] != 6) {
1990-11-12 13:46:31 +00:00
fatal("something wrong with file descriptors");
1990-08-31 18:22:53 +00:00
}
to_child = fild1[1];
from_child = fild2[0];
child_pid = 0;
if (currfile) CurrentScope = currfile->sy_file->f_scope;
1990-10-17 17:00:03 +00:00
currline = 0;
1990-08-31 18:22:53 +00:00
}
extern int errno;
1990-08-31 18:22:53 +00:00
start_child(p)
p_tree p;
{
/* start up the process to be debugged and set up communication */
char *argp[MAXARG]; /* argument list */
1990-11-12 13:46:31 +00:00
register p_tree pt = p->t_args[0], pt1 = 0;
1990-08-31 18:22:53 +00:00
unsigned int nargs = 1; /* #args */
char *in_redirect = 0; /* standard input redirected */
char *out_redirect = 0; /* standard output redirected */
signal_child(SIGKILL); /* like families in China, this debugger is only
allowed one child
*/
if (p != run_command) {
freenode(run_command);
run_command = p;
}
1990-08-31 18:22:53 +00:00
/* first check arguments and redirections and build argument list */
while (pt) {
switch(pt->t_oper) {
case OP_LINK:
pt1 = pt->t_args[1];
pt = pt->t_args[0];
continue;
case OP_NAME:
if (nargs < (MAXARG-1)) {
argp[nargs++] = pt->t_str;
}
else {
error("too many arguments");
1990-11-12 13:46:31 +00:00
return;
1990-08-31 18:22:53 +00:00
}
break;
case OP_INPUT:
if (in_redirect) {
error("input redirected twice?");
1990-11-12 13:46:31 +00:00
return;
1990-08-31 18:22:53 +00:00
}
in_redirect = pt->t_str;
break;
case OP_OUTPUT:
if (out_redirect) {
error("output redirected twice?");
1990-11-12 13:46:31 +00:00
return;
1990-08-31 18:22:53 +00:00
}
out_redirect = pt->t_str;
break;
}
if (pt != pt1) pt = pt1;
else break;
}
argp[0] = AObj;
argp[nargs] = 0;
/* create child process */
child_pid = fork();
if (child_pid < 0) {
error("could not create child");
1990-11-12 13:46:31 +00:00
return;
1990-08-31 18:22:53 +00:00
}
if (child_pid == 0) {
/* this is the child process */
close(fild1[1]);
close(fild2[0]);
signal(SIGINT, SIG_IGN);
/* I/O redirection */
if (in_redirect) {
int fd;
1990-09-25 17:40:47 +00:00
1990-08-31 18:22:53 +00:00
close(0);
1990-09-25 17:40:47 +00:00
if ((fd = open(in_redirect, 0)) < 0 ||
(fd != 0 && dup2(fd, 0) < 0)) {
perror(progname);
1990-09-25 17:40:47 +00:00
exit(1);
1990-08-31 18:22:53 +00:00
}
if (fd != 0) {
close(fd);
}
}
if (out_redirect) {
int fd;
1990-08-31 18:22:53 +00:00
close(1);
if ((fd = creat(out_redirect, 0666)) < 0 ||
1990-09-25 17:40:47 +00:00
(fd != 1 && dup2(fd, 1) < 0)) {
perror(progname);
1990-09-25 17:40:47 +00:00
exit(1);
1990-08-31 18:22:53 +00:00
}
if (fd != 1) {
close(fd);
}
}
/* and run process to be debugged */
execv(AObj, argp);
error("could not exec %s", AObj);
1990-09-25 17:40:47 +00:00
exit(1);
1990-08-31 18:22:53 +00:00
}
1990-12-11 13:53:01 +00:00
/* close fild1[0] and fild2[1]; but we want those file descriptors occupied,
so we re-occupy them.
1990-11-12 13:46:31 +00:00
*/
1990-08-31 18:22:53 +00:00
1990-12-11 13:53:01 +00:00
close(fild1[0]);
close(fild2[1]);
pipe(fild1); /* to occupy file descriptors */
1990-08-31 18:22:53 +00:00
signal(SIGPIPE, catch_sigpipe);
{
struct message_hdr m;
if (! ugetm(&m)) {
error("child not responding");
init_run();
1990-11-12 13:46:31 +00:00
return;
}
1990-12-19 11:17:06 +00:00
curr_stop = BUFTOI(m.m_buf+1, PS);
CurrentScope = get_scope_from_addr(curr_stop);
1990-08-31 18:22:53 +00:00
}
perform_items();
1990-11-12 13:46:31 +00:00
if (! restoring) {
int stop_reason = item_addr_actions(curr_stop, 1, 1);
if (! stop_reason) (void) send_cont(1);
else (void) stopped("stopped", curr_stop, stop_reason);
1990-08-31 18:22:53 +00:00
}
}
1990-11-12 13:46:31 +00:00
void
1990-08-31 18:22:53 +00:00
signal_child(sig)
{
if (child_pid) {
kill(child_pid, sig);
if (sig == SIGKILL) {
wait(&child_status);
init_run();
}
}
}
1990-11-12 13:46:31 +00:00
static void
1990-08-31 18:22:53 +00:00
catch_sigpipe()
{
child_pid = 0;
}
static int
ureceive(p, c)
char *p;
long c;
{
int i;
1990-09-26 17:32:42 +00:00
char buf[0x1000];
1990-08-31 18:22:53 +00:00
1990-10-17 17:00:03 +00:00
if (! child_pid) {
error("no process");
return 0;
}
1990-08-31 18:22:53 +00:00
1990-09-26 17:32:42 +00:00
if (! p) p = buf;
1990-08-31 18:22:53 +00:00
while (c >= 0x1000) {
i = read(from_child, p, 0x1000);
if (i <= 0) {
1990-10-17 17:00:03 +00:00
if (i == 0) {
child_pid = 0;
}
else error("read failed");
1990-08-31 18:22:53 +00:00
return 0;
}
1990-09-26 17:32:42 +00:00
if (p != buf) p += i;
1990-08-31 18:22:53 +00:00
c -= i;
}
while (c > 0) {
i = read(from_child, p, (int)c);
if (i <= 0) {
1990-10-17 17:00:03 +00:00
if (i == 0) {
child_pid = 0;
}
else error("read failed");
1990-08-31 18:22:53 +00:00
return 0;
}
p += i;
c -= i;
}
1990-10-17 17:00:03 +00:00
return 1;
1990-08-31 18:22:53 +00:00
}
static int
usend(p, c)
char *p;
long c;
{
int i;
1990-10-17 17:00:03 +00:00
if (! child_pid) {
error("no process");
return 0;
}
1990-08-31 18:22:53 +00:00
while (c >= 0x1000) {
i = write(to_child, p, 0x1000);
1990-10-17 17:00:03 +00:00
if (i < 0) {
if (child_pid) error("write failed");
return 0;
}
1990-08-31 18:22:53 +00:00
p += i;
c -= i;
}
while (c > 0) {
i = write(to_child, p, (int)c);
1990-10-17 17:00:03 +00:00
if (i < 0) {
if (child_pid) error("write failed");
return 0;
}
1990-08-31 18:22:53 +00:00
p += i;
c -= i;
}
return 1;
}
static int
ugetm(message)
struct message_hdr *message;
{
if (! ureceive((char *) message, (long) sizeof(struct message_hdr))) {
return 0;
}
if (debug) printf("Got %d\n", message->m_type);
return 1;
}
static int
uputm(message)
struct message_hdr *message;
{
if (! usend((char *) message, (long) sizeof(struct message_hdr))) {
return 0;
}
if (debug) printf("Sent %d\n", message->m_type);
return 1;
}
static struct message_hdr answer;
static int single_stepping;
static int
1990-11-12 13:46:31 +00:00
stopped(s, a, stop_reason)
char *s; /* stop message */
t_addr a; /* address where stopped */
int stop_reason; /* status entry causing the stop */
1990-08-31 18:22:53 +00:00
{
p_position pos;
if (s && a) {
1990-08-31 18:22:53 +00:00
fprintf(db_out, "%s ", s);
1990-10-01 11:44:27 +00:00
pos = print_position(a, 1);
1990-10-17 17:00:03 +00:00
if (stop_reason) {
fprintf(db_out, " (status entry %d)", stop_reason);
}
1990-08-31 18:22:53 +00:00
fputs("\n", db_out);
1990-09-21 16:58:20 +00:00
list_position(pos);
handle_displays();
1990-08-31 18:22:53 +00:00
}
1990-10-01 11:44:27 +00:00
curr_stop = a;
1990-10-17 17:00:03 +00:00
CurrentScope = get_scope_from_addr(a);
1990-08-31 18:22:53 +00:00
return 1;
}
static int
could_send(m, stop_message)
struct message_hdr *m;
{
int type;
t_addr a;
static int level = 0;
1990-10-17 17:00:03 +00:00
int child_dead = 0;
1990-11-12 13:46:31 +00:00
int stop_reason;
level++;
1990-08-31 18:22:53 +00:00
for (;;) {
1990-11-12 13:46:31 +00:00
stop_reason = 0;
1990-10-17 17:00:03 +00:00
if (! child_pid) {
error("no process");
return 0;
}
if (m->m_type & M_DB_RUN) {
1990-10-17 17:00:03 +00:00
disable_intr = 0;
1990-11-06 12:23:41 +00:00
stack_offset = 0;
1990-10-17 17:00:03 +00:00
}
if (!child_interrupted && (! uputm(m) || ! ugetm(&answer))) {
child_dead = 1;
}
disable_intr = 1;
if ((interrupted || child_interrupted) && ! child_dead) {
while (child_interrupted && answer.m_type != M_INTR) {
1990-10-17 17:00:03 +00:00
if (! ugetm(&answer)) {
child_dead = 1;
break;
1990-08-31 18:22:53 +00:00
}
}
1990-10-17 17:00:03 +00:00
if (interrupted && ! child_dead) {
level--;
1990-10-17 17:00:03 +00:00
if (! level) {
child_interrupted = 0;
interrupted = 0;
1990-12-19 11:17:06 +00:00
return stopped("interrupted", (t_addr) BUFTOI(answer.m_buf+1, PS), 0);
1990-10-17 17:00:03 +00:00
}
1990-08-31 18:22:53 +00:00
return 1;
}
1990-10-17 17:00:03 +00:00
}
if (child_dead) {
wait(&child_status);
if (child_status & 0177) {
fprintf(db_out,
"child died with signal %d\n",
child_status & 0177);
1990-08-31 18:22:53 +00:00
}
1990-10-17 17:00:03 +00:00
else {
fprintf(db_out,
"child terminated, exit status %d\n",
child_status >> 8);
1990-09-20 17:51:14 +00:00
}
1990-10-17 17:00:03 +00:00
init_run();
level--;
1990-10-17 17:00:03 +00:00
return 1;
}
1990-12-19 11:17:06 +00:00
a = BUFTOI(answer.m_buf+1, PS);
type = answer.m_type & 0377;
1990-11-12 13:46:31 +00:00
if (type == M_END_SS) type = 0;
else if (type == M_OK || type == M_DB_SS) type = 1;
else type = 2;
if (m->m_type & M_DB_RUN) {
1990-10-17 17:00:03 +00:00
/* run command */
CurrentScope = get_scope_from_addr((t_addr) a);
1990-11-12 13:46:31 +00:00
if (!(stop_reason = item_addr_actions(a, type, stop_message))
&& (type == 1)) {
1990-10-17 17:00:03 +00:00
/* no explicit breakpoints at this position.
Also, child did not stop because of
SETSS or SETSSF, otherwise we would
have gotten END_SS.
So, continue.
*/
if ((m->m_type & 0177) != M_CONT) {
m->m_type = M_CONT | (m->m_type & M_DB_SS);
1990-10-17 17:00:03 +00:00
}
continue;
}
1990-11-12 13:46:31 +00:00
if (type != 0 && single_stepping) {
m->m_type = M_CLRSS;
1990-10-17 17:00:03 +00:00
if (! uputm(m) || ! ugetm(&answer)) return 0;
}
single_stepping = 0;
}
1990-11-12 13:46:31 +00:00
level--;
1990-10-17 17:00:03 +00:00
if (stop_message) {
1990-11-12 13:46:31 +00:00
return stopped("stopped", a, stop_reason);
1990-08-31 18:22:53 +00:00
}
1990-10-17 17:00:03 +00:00
return 1;
1990-08-31 18:22:53 +00:00
}
/*NOTREACHED*/
}
static int
1990-11-06 12:23:41 +00:00
getbytes(size, from, to, kind, errmess)
1990-08-31 18:22:53 +00:00
long size;
t_addr from;
char *to;
1990-11-06 12:23:41 +00:00
int kind;
int errmess;
1990-08-31 18:22:53 +00:00
{
struct message_hdr m;
m.m_type = kind;
1990-12-19 11:17:06 +00:00
ITOBUF(m.m_buf+1, size, LS);
ITOBUF(m.m_buf+LS+1, (long)from, PS);
1990-08-31 18:22:53 +00:00
if (! could_send(&m, 0)) {
return 0;
}
1990-10-17 17:00:03 +00:00
switch(answer.m_type) {
case M_FAIL:
1990-11-06 12:23:41 +00:00
if (errmess) error("could not get value");
1990-09-19 14:31:12 +00:00
return 0;
case M_INTR:
1990-11-06 12:23:41 +00:00
if (errmess) error("interrupted");
1990-10-17 17:00:03 +00:00
return 0;
case M_DATA:
1990-12-19 11:17:06 +00:00
return ureceive(to, BUFTOI(answer.m_buf+1, LS));
1990-10-17 17:00:03 +00:00
default:
assert(0);
1990-09-19 14:31:12 +00:00
}
1990-10-17 17:00:03 +00:00
/*NOTREACHED*/
1990-08-31 18:22:53 +00:00
}
int
get_bytes(size, from, to)
long size;
t_addr from;
char *to;
{
1990-11-06 12:23:41 +00:00
return getbytes(size, from, to, M_GETBYTES, 1);
}
int
get_string(size, from, to)
long size;
t_addr from;
char *to;
{
1990-11-06 12:23:41 +00:00
int retval = getbytes(size, from, to, M_GETSTR, 0);
1990-12-19 11:17:06 +00:00
to[(int)BUFTOI(answer.m_buf+1, LS)] = 0;
return retval;
}
1990-11-12 13:46:31 +00:00
void
1990-09-19 14:31:12 +00:00
set_bytes(size, from, to)
long size;
char *from;
t_addr to;
{
struct message_hdr m;
m.m_type = M_SETBYTES;
1990-12-19 11:17:06 +00:00
ITOBUF(m.m_buf+1, size, LS);
ITOBUF(m.m_buf+LS+1, (long) to, PS);
1990-09-19 14:31:12 +00:00
1990-10-17 17:00:03 +00:00
if (! uputm(&m) || ! usend(from, size) || ! ugetm(&m)) {
return;
}
switch(answer.m_type) {
case M_FAIL:
1990-10-17 17:00:03 +00:00
error("could not handle this SET request");
break;
case M_INTR:
1990-10-17 17:00:03 +00:00
error("interrupted");
break;
case M_OK:
1990-10-17 17:00:03 +00:00
break;
default:
assert(0);
}
1990-09-19 14:31:12 +00:00
}
t_addr
1990-11-12 13:46:31 +00:00
get_dump(globbuf, stackbuf)
1990-08-31 18:22:53 +00:00
char **globbuf, **stackbuf;
{
struct message_hdr m;
1990-11-12 13:46:31 +00:00
struct message_hdr *globm, *stackm;
long sz;
1990-08-31 18:22:53 +00:00
m.m_type = M_DUMP;
1990-08-31 18:22:53 +00:00
if (! could_send(&m, 0)) {
return 0;
}
1990-10-17 17:00:03 +00:00
switch(answer.m_type) {
case M_FAIL:
1990-10-17 17:00:03 +00:00
error("request for DUMP failed");
return 0;
case M_INTR:
1990-10-17 17:00:03 +00:00
error("interrupted");
return 0;
case M_DGLOB:
1990-10-17 17:00:03 +00:00
break;
default:
assert(0);
}
1990-12-19 11:17:06 +00:00
sz = BUFTOI(answer.m_buf+1, LS);
1990-11-12 13:46:31 +00:00
*globbuf = malloc((unsigned) (sz+sizeof(struct message_hdr)));
if (! *globbuf
|| ! ureceive(*globbuf+sizeof(struct message_hdr), sz)
|| ! ugetm(&m)) {
1990-09-26 17:32:42 +00:00
if (*globbuf) free(*globbuf);
1990-11-12 13:46:31 +00:00
else error("could not allocate enougn memory");
1990-08-31 18:22:53 +00:00
return 0;
}
1990-11-12 13:46:31 +00:00
globm = (struct message_hdr *) *globbuf;
*globm = answer;
assert(m.m_type == M_DSTACK);
1990-12-19 11:17:06 +00:00
sz = BUFTOI(m.m_buf+1, LS);
1990-11-12 13:46:31 +00:00
*stackbuf = malloc((unsigned) sz+sizeof(struct message_hdr));
if (! *stackbuf || ! ureceive(*stackbuf+sizeof(struct message_hdr), sz)) {
free(*globbuf);
1990-09-26 17:32:42 +00:00
if (*stackbuf) free(*stackbuf);
1990-11-12 13:46:31 +00:00
else error("could not allocate enougn memory");
1990-09-26 17:32:42 +00:00
return 0;
}
1990-11-12 13:46:31 +00:00
stackm = (struct message_hdr *) *stackbuf;
*stackm = m;
1990-12-19 11:17:06 +00:00
ITOBUF(globm->m_buf+SP_OFF, BUFTOI(stackm->m_buf+SP_OFF, PS), PS);
return BUFTOI(globm->m_buf+PC_OFF, PS);
1990-08-31 18:22:53 +00:00
}
int
1990-11-12 13:46:31 +00:00
put_dump(globbuf, stackbuf)
1990-08-31 18:22:53 +00:00
char *globbuf, *stackbuf;
{
struct message_hdr m;
1990-11-12 13:46:31 +00:00
struct message_hdr *globm = (struct message_hdr *) globbuf,
*stackm = (struct message_hdr *) stackbuf;
1990-08-31 18:22:53 +00:00
1990-11-12 13:46:31 +00:00
stackbuf += sizeof(struct message_hdr);
globbuf += sizeof(struct message_hdr);
1990-08-31 18:22:53 +00:00
if (! child_pid) {
restoring = 1;
start_child(run_command);
restoring = 0;
}
1990-11-12 13:46:31 +00:00
return uputm(globm)
1990-12-19 11:17:06 +00:00
&& usend(globbuf, BUFTOI(globm->m_buf+1, LS))
1990-11-12 13:46:31 +00:00
&& uputm(stackm)
1990-12-19 11:17:06 +00:00
&& usend(stackbuf, BUFTOI(stackm->m_buf+1, LS))
&& ugetm(&m)
1990-12-19 11:17:06 +00:00
&& stopped("restored", BUFTOI(m.m_buf+1, PS), 0);
1990-08-31 18:22:53 +00:00
}
t_addr *
get_EM_regs(level)
int level;
{
struct message_hdr m;
static t_addr buf[5];
register t_addr *to = &buf[0];
m.m_type = M_GETEMREGS;
1990-12-19 11:17:06 +00:00
ITOBUF(m.m_buf+1, (long) level, LS);
1990-08-31 18:22:53 +00:00
if (! could_send(&m, 0)) {
return 0;
}
1990-10-17 17:00:03 +00:00
switch(answer.m_type) {
case M_FAIL:
1990-10-17 17:00:03 +00:00
error("request for registers failed");
return 0;
case M_INTR:
1990-10-17 17:00:03 +00:00
error("interrupted");
return 0;
case M_GETEMREGS:
1990-10-17 17:00:03 +00:00
break;
default:
assert(0);
}
1990-12-19 11:17:06 +00:00
*to++ = (t_addr) BUFTOI(answer.m_buf+LB_OFF, PS);
*to++ = (t_addr) BUFTOI(answer.m_buf+AB_OFF, PS);
*to++ = (t_addr) BUFTOI(answer.m_buf+PC_OFF, PS);
*to++ = (t_addr) BUFTOI(answer.m_buf+HP_OFF, PS);
*to++ = (t_addr) BUFTOI(answer.m_buf+PC_OFF, PS);
1990-08-31 18:22:53 +00:00
return buf;
}
int
set_pc(PC)
t_addr PC;
{
struct message_hdr m;
m.m_type = M_SETEMREGS;
1990-12-19 11:17:06 +00:00
ITOBUF(m.m_buf+PC_OFF, (long)PC, PS);
1990-10-17 17:00:03 +00:00
if (! could_send(&m, 0)) return 0;
switch(answer.m_type) {
case M_FAIL:
1990-10-17 17:00:03 +00:00
error("could not set PC to %lx", (long) PC);
return 0;
case M_INTR:
1990-10-17 17:00:03 +00:00
error("interrupted");
return 0;
case M_OK:
1990-10-17 17:00:03 +00:00
return 1;
default:
assert(0);
}
/*NOTREACHED*/
1990-08-31 18:22:53 +00:00
}
int
send_cont(stop_message)
int stop_message;
{
struct message_hdr m;
m.m_type = (M_CONT | (db_ss ? M_DB_SS : 0));
1990-10-17 17:00:03 +00:00
return could_send(&m, stop_message) && child_pid;
1990-08-31 18:22:53 +00:00
}
int
singlestep(type, count)
1990-08-31 18:22:53 +00:00
int type;
long count;
{
struct message_hdr m;
1990-11-12 13:46:31 +00:00
m.m_type = (type ? M_SETSSF : M_SETSS) | (db_ss ? M_DB_SS : 0);
1990-12-19 11:17:06 +00:00
ITOBUF(m.m_buf+1, count, LS);
1990-08-31 18:22:53 +00:00
single_stepping = 1;
1990-10-17 17:00:03 +00:00
if (could_send(&m, 1) && child_pid) return 1;
1990-08-31 18:22:53 +00:00
single_stepping = 0;
return 0;
}
int
set_or_clear_breakpoint(a, type)
t_addr a;
int type;
{
struct message_hdr m;
1990-11-12 13:46:31 +00:00
m.m_type = type ? M_SETBP : M_CLRBP;
1990-12-19 11:17:06 +00:00
ITOBUF(m.m_buf+1, (long) a, PS);
1990-11-12 13:46:31 +00:00
if (debug) printf("%s breakpoint at 0x%lx\n", type ? "setting" : "clearing", (long) a);
1990-10-17 17:00:03 +00:00
if (child_pid && ! could_send(&m, 0)) {
}
1990-08-31 18:22:53 +00:00
return 1;
}
int
set_or_clear_trace(start, end, type)
t_addr start, end;
int type;
{
struct message_hdr m;
1990-11-12 13:46:31 +00:00
m.m_type = type ? M_SETTRACE : M_CLRTRACE;
1990-12-19 11:17:06 +00:00
ITOBUF(m.m_buf+1, (long)start, PS);
ITOBUF(m.m_buf+PS+1, (long)end, PS);
1990-11-12 13:46:31 +00:00
if (debug) printf("%s trace at [0x%lx,0x%lx]\n", type ? "setting" : "clearing", (long) start, (long) end);
1990-10-17 17:00:03 +00:00
if (child_pid && ! could_send(&m, 0)) {
return 0;
}
1990-08-31 18:22:53 +00:00
return 1;
}