|
@@ -30,6 +30,8 @@ extern long pointer_size;
|
|
|
extern char *progname;
|
|
|
extern int child_interrupted;
|
|
|
extern int interrupted;
|
|
|
+extern int stop_reason;
|
|
|
+extern t_lineno currline;
|
|
|
|
|
|
static int child_pid; /* process id of child */
|
|
|
static int to_child, from_child; /* file descriptors for communication */
|
|
@@ -39,7 +41,6 @@ static int fild1[2], fild2[2]; /* pipe file descriptors */
|
|
|
int disable_intr = 1;
|
|
|
|
|
|
int db_ss;
|
|
|
-t_lineno currline;
|
|
|
|
|
|
static int catch_sigpipe();
|
|
|
static int stopped();
|
|
@@ -64,6 +65,7 @@ init_run()
|
|
|
from_child = fild2[0];
|
|
|
child_pid = 0;
|
|
|
if (currfile) CurrentScope = currfile->sy_file->f_scope;
|
|
|
+ currline = 0;
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
@@ -191,7 +193,7 @@ start_child(p)
|
|
|
CurrentScope = get_scope_from_addr(curr_stop);
|
|
|
}
|
|
|
do_items();
|
|
|
- if (! restoring && ! item_addr_actions(curr_stop, OK)) {
|
|
|
+ if (! restoring && ! item_addr_actions(curr_stop, OK, 1)) {
|
|
|
send_cont(1);
|
|
|
}
|
|
|
else if (! restoring) {
|
|
@@ -225,13 +227,19 @@ ureceive(p, c)
|
|
|
int i;
|
|
|
char buf[0x1000];
|
|
|
|
|
|
- if (! child_pid) return 0;
|
|
|
+ if (! child_pid) {
|
|
|
+ error("no process");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
|
|
|
if (! p) p = buf;
|
|
|
while (c >= 0x1000) {
|
|
|
i = read(from_child, p, 0x1000);
|
|
|
if (i <= 0) {
|
|
|
- if (i == 0) child_pid = 0;
|
|
|
+ if (i == 0) {
|
|
|
+ child_pid = 0;
|
|
|
+ }
|
|
|
+ else error("read failed");
|
|
|
return 0;
|
|
|
}
|
|
|
if (p != buf) p += i;
|
|
@@ -240,13 +248,16 @@ ureceive(p, c)
|
|
|
while (c > 0) {
|
|
|
i = read(from_child, p, (int)c);
|
|
|
if (i <= 0) {
|
|
|
- if (i == 0) child_pid = 0;
|
|
|
+ if (i == 0) {
|
|
|
+ child_pid = 0;
|
|
|
+ }
|
|
|
+ else error("read failed");
|
|
|
return 0;
|
|
|
}
|
|
|
p += i;
|
|
|
c -= i;
|
|
|
}
|
|
|
- return c == 0;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
static int
|
|
@@ -256,16 +267,25 @@ usend(p, c)
|
|
|
{
|
|
|
int i;
|
|
|
|
|
|
- if (! child_pid) return 0;
|
|
|
+ if (! child_pid) {
|
|
|
+ error("no process");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
while (c >= 0x1000) {
|
|
|
i = write(to_child, p, 0x1000);
|
|
|
- if (i < 0) return 0;
|
|
|
+ if (i < 0) {
|
|
|
+ if (child_pid) error("write failed");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
p += i;
|
|
|
c -= i;
|
|
|
}
|
|
|
while (c > 0) {
|
|
|
i = write(to_child, p, (int)c);
|
|
|
- if (i < 0) return 0;
|
|
|
+ if (i < 0) {
|
|
|
+ if (child_pid) error("write failed");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
p += i;
|
|
|
c -= i;
|
|
|
}
|
|
@@ -307,11 +327,15 @@ stopped(s, a)
|
|
|
if (s && a) {
|
|
|
fprintf(db_out, "%s ", s);
|
|
|
pos = print_position(a, 1);
|
|
|
+ if (stop_reason) {
|
|
|
+ fprintf(db_out, " (status entry %d)", stop_reason);
|
|
|
+ }
|
|
|
fputs("\n", db_out);
|
|
|
list_position(pos);
|
|
|
handle_displays();
|
|
|
}
|
|
|
curr_stop = a;
|
|
|
+ CurrentScope = get_scope_from_addr(a);
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
@@ -322,82 +346,84 @@ could_send(m, stop_message)
|
|
|
int type;
|
|
|
t_addr a;
|
|
|
static int level = 0;
|
|
|
+ int child_dead = 0;
|
|
|
|
|
|
level++;
|
|
|
for (;;) {
|
|
|
- if (child_pid) {
|
|
|
- int child_dead = 0;
|
|
|
- if (m->m_type & DB_RUN) disable_intr = 0;
|
|
|
- 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 != INTR) {
|
|
|
- if (! ugetm(&answer)) {
|
|
|
- child_dead = 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- if (interrupted && ! child_dead) {
|
|
|
- level--;
|
|
|
- if (! level) {
|
|
|
- child_interrupted = 0;
|
|
|
- CurrentScope = get_scope_from_addr((t_addr) answer.m_size);
|
|
|
- interrupted = 0;
|
|
|
- stopped("interrupted", (t_addr) answer.m_size);
|
|
|
- }
|
|
|
- return 1;
|
|
|
+ if (! child_pid) {
|
|
|
+ error("no process");
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if (m->m_type & DB_RUN) {
|
|
|
+ disable_intr = 0;
|
|
|
+ stop_reason = 0;
|
|
|
+ }
|
|
|
+ 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 != INTR) {
|
|
|
+ if (! ugetm(&answer)) {
|
|
|
+ child_dead = 1;
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
- if (child_dead) {
|
|
|
- wait(&child_status);
|
|
|
- if (child_status & 0177) {
|
|
|
- fprintf(db_out,
|
|
|
- "child died with signal %d\n",
|
|
|
- child_status & 0177);
|
|
|
- }
|
|
|
- else {
|
|
|
- fprintf(db_out,
|
|
|
- "child terminated, exit status %d\n",
|
|
|
- child_status >> 8);
|
|
|
- }
|
|
|
- init_run();
|
|
|
+ if (interrupted && ! child_dead) {
|
|
|
level--;
|
|
|
+ if (! level) {
|
|
|
+ child_interrupted = 0;
|
|
|
+ interrupted = 0;
|
|
|
+ stopped("interrupted", (t_addr) answer.m_size);
|
|
|
+ }
|
|
|
return 1;
|
|
|
}
|
|
|
- a = answer.m_size;
|
|
|
- type = answer.m_type;
|
|
|
- if (m->m_type & DB_RUN) {
|
|
|
- /* run command */
|
|
|
- CurrentScope = get_scope_from_addr((t_addr) a);
|
|
|
- if (! item_addr_actions(a, type) &&
|
|
|
- ( type == DB_SS || type == OK)) {
|
|
|
- /* 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 & ~ DB_SS) != CONT) {
|
|
|
- m->m_type = CONT | (m->m_type & DB_SS);
|
|
|
- }
|
|
|
- continue;
|
|
|
- }
|
|
|
- if (type != END_SS && single_stepping) {
|
|
|
- m->m_type = CLRSS;
|
|
|
- uputm(m) && ugetm(&answer);
|
|
|
- }
|
|
|
- single_stepping = 0;
|
|
|
+ }
|
|
|
+ if (child_dead) {
|
|
|
+ wait(&child_status);
|
|
|
+ if (child_status & 0177) {
|
|
|
+ fprintf(db_out,
|
|
|
+ "child died with signal %d\n",
|
|
|
+ child_status & 0177);
|
|
|
}
|
|
|
- if (stop_message) {
|
|
|
- stopped("stopped", a);
|
|
|
+ else {
|
|
|
+ fprintf(db_out,
|
|
|
+ "child terminated, exit status %d\n",
|
|
|
+ child_status >> 8);
|
|
|
}
|
|
|
+ init_run();
|
|
|
level--;
|
|
|
- return type;
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ a = answer.m_size;
|
|
|
+ type = answer.m_type;
|
|
|
+ if (m->m_type & DB_RUN) {
|
|
|
+ /* run command */
|
|
|
+ CurrentScope = get_scope_from_addr((t_addr) a);
|
|
|
+ if (! item_addr_actions(a, type, stop_message) &&
|
|
|
+ ( type == DB_SS || type == OK)) {
|
|
|
+ /* 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 & ~ DB_SS) != CONT) {
|
|
|
+ m->m_type = CONT | (m->m_type & DB_SS);
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (type != END_SS && single_stepping) {
|
|
|
+ m->m_type = CLRSS;
|
|
|
+ if (! uputm(m) || ! ugetm(&answer)) return 0;
|
|
|
+ }
|
|
|
+ single_stepping = 0;
|
|
|
+ }
|
|
|
+ if (stop_message) {
|
|
|
+ stopped("stopped", a);
|
|
|
}
|
|
|
level--;
|
|
|
- return 0;
|
|
|
+ return 1;
|
|
|
}
|
|
|
/*NOTREACHED*/
|
|
|
}
|
|
@@ -415,17 +441,22 @@ getbytes(size, from, to, kind)
|
|
|
put_int(m.m_buf, pointer_size, (long)from);
|
|
|
|
|
|
if (! could_send(&m, 0)) {
|
|
|
- error("no process");
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- if (answer.m_type == FAIL || answer.m_type == INTR) {
|
|
|
+ switch(answer.m_type) {
|
|
|
+ case FAIL:
|
|
|
+ error("could not get value");
|
|
|
return 0;
|
|
|
+ case INTR:
|
|
|
+ error("interrupted");
|
|
|
+ return 0;
|
|
|
+ case DATA:
|
|
|
+ return ureceive(to, answer.m_size);
|
|
|
+ default:
|
|
|
+ assert(0);
|
|
|
}
|
|
|
-
|
|
|
- assert(answer.m_type == DATA);
|
|
|
-
|
|
|
- return ureceive(to, answer.m_size);
|
|
|
+ /*NOTREACHED*/
|
|
|
}
|
|
|
|
|
|
int
|
|
@@ -449,7 +480,6 @@ get_string(size, from, to)
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
-int
|
|
|
set_bytes(size, from, to)
|
|
|
long size;
|
|
|
char *from;
|
|
@@ -461,9 +491,21 @@ set_bytes(size, from, to)
|
|
|
m.m_size = size;
|
|
|
put_int(m.m_buf, pointer_size, (long) to);
|
|
|
|
|
|
- return uputm(&m) && usend(from, size)
|
|
|
- && ugetm(&m)
|
|
|
- && m.m_type != FAIL;
|
|
|
+ if (! uputm(&m) || ! usend(from, size) || ! ugetm(&m)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ switch(answer.m_type) {
|
|
|
+ case FAIL:
|
|
|
+ error("could not handle this SET request");
|
|
|
+ break;
|
|
|
+ case INTR:
|
|
|
+ error("interrupted");
|
|
|
+ break;
|
|
|
+ case OK:
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ assert(0);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
int
|
|
@@ -475,16 +517,25 @@ get_dump(globmessage, globbuf, stackmessage, stackbuf)
|
|
|
|
|
|
m.m_type = DUMP;
|
|
|
if (! could_send(&m, 0)) {
|
|
|
- error("no process");
|
|
|
return 0;
|
|
|
}
|
|
|
- if (answer.m_type == FAIL || answer.m_type == INTR) return 0;
|
|
|
- assert(answer.m_type == DGLOB);
|
|
|
+ switch(answer.m_type) {
|
|
|
+ case FAIL:
|
|
|
+ error("request for DUMP failed");
|
|
|
+ return 0;
|
|
|
+ case INTR:
|
|
|
+ error("interrupted");
|
|
|
+ return 0;
|
|
|
+ case DGLOB:
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ assert(0);
|
|
|
+ }
|
|
|
+
|
|
|
*globmessage = answer;
|
|
|
*globbuf = malloc((unsigned) answer.m_size);
|
|
|
if (! ureceive(*globbuf, answer.m_size) || ! ugetm(stackmessage)) {
|
|
|
if (*globbuf) free(*globbuf);
|
|
|
- error("no process");
|
|
|
return 0;
|
|
|
}
|
|
|
assert(stackmessage->m_type == DSTACK);
|
|
@@ -492,7 +543,6 @@ get_dump(globmessage, globbuf, stackmessage, stackbuf)
|
|
|
if (! ureceive(*stackbuf, stackmessage->m_size)) {
|
|
|
if (*globbuf) free(*globbuf);
|
|
|
if (*stackbuf) free(*stackbuf);
|
|
|
- error("no process");
|
|
|
return 0;
|
|
|
}
|
|
|
put_int(globmessage->m_buf+SP_OFF*pointer_size, pointer_size,
|
|
@@ -537,10 +587,20 @@ get_EM_regs(level)
|
|
|
m.m_size = level;
|
|
|
|
|
|
if (! could_send(&m, 0)) {
|
|
|
- error("no process");
|
|
|
return 0;
|
|
|
}
|
|
|
- if (answer.m_type == FAIL || answer.m_type == INTR) return 0;
|
|
|
+ switch(answer.m_type) {
|
|
|
+ case FAIL:
|
|
|
+ error("request for registers failed");
|
|
|
+ return 0;
|
|
|
+ case INTR:
|
|
|
+ error("interrupted");
|
|
|
+ return 0;
|
|
|
+ case GETEMREGS:
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ assert(0);
|
|
|
+ }
|
|
|
*to++ = (t_addr) get_int(answer.m_buf, pointer_size, T_UNSIGNED);
|
|
|
*to++ = (t_addr) get_int(answer.m_buf+pointer_size, pointer_size, T_UNSIGNED);
|
|
|
*to++ = (t_addr) get_int(answer.m_buf+2*pointer_size, pointer_size, T_UNSIGNED);
|
|
@@ -558,7 +618,20 @@ set_pc(PC)
|
|
|
m.m_type = SETEMREGS;
|
|
|
m.m_size = 0;
|
|
|
put_int(m.m_buf+PC_OFF*pointer_size, pointer_size, (long)PC);
|
|
|
- return could_send(&m, 0) && answer.m_type != FAIL && answer.m_type != INTR;
|
|
|
+ if (! could_send(&m, 0)) return 0;
|
|
|
+ switch(answer.m_type) {
|
|
|
+ case FAIL:
|
|
|
+ error("could not set PC to %lx", (long) PC);
|
|
|
+ return 0;
|
|
|
+ case INTR:
|
|
|
+ error("interrupted");
|
|
|
+ return 0;
|
|
|
+ case OK:
|
|
|
+ return 1;
|
|
|
+ default:
|
|
|
+ assert(0);
|
|
|
+ }
|
|
|
+ /*NOTREACHED*/
|
|
|
}
|
|
|
|
|
|
int
|
|
@@ -569,7 +642,7 @@ send_cont(stop_message)
|
|
|
|
|
|
m.m_type = (CONT | (db_ss ? DB_SS : 0));
|
|
|
m.m_size = 0;
|
|
|
- return could_send(&m, stop_message) && answer.m_type != FAIL;
|
|
|
+ return could_send(&m, stop_message) && child_pid;
|
|
|
}
|
|
|
|
|
|
int
|
|
@@ -582,9 +655,7 @@ do_single_step(type, count)
|
|
|
m.m_type = type | (db_ss ? DB_SS : 0);
|
|
|
m.m_size = count;
|
|
|
single_stepping = 1;
|
|
|
- if (could_send(&m, 1) && answer.m_type != FAIL && answer.m_type != INTR) {
|
|
|
- return 1;
|
|
|
- }
|
|
|
+ if (could_send(&m, 1) && child_pid) return 1;
|
|
|
single_stepping = 0;
|
|
|
return 0;
|
|
|
}
|
|
@@ -596,12 +667,10 @@ set_or_clear_breakpoint(a, type)
|
|
|
{
|
|
|
struct message_hdr m;
|
|
|
|
|
|
- if (a == ILL_ADDR || a == NO_ADDR) return 0;
|
|
|
-
|
|
|
m.m_type = type;
|
|
|
m.m_size = a;
|
|
|
if (debug) printf("%s breakpoint at 0x%lx\n", type == SETBP ? "setting" : "clearing", (long) a);
|
|
|
- if (! could_send(&m, 0)) {
|
|
|
+ if (child_pid && ! could_send(&m, 0)) {
|
|
|
}
|
|
|
|
|
|
return 1;
|
|
@@ -618,7 +687,8 @@ set_or_clear_trace(start, end, type)
|
|
|
put_int(m.m_buf, pointer_size, (long)start);
|
|
|
put_int(m.m_buf+pointer_size, pointer_size, (long)end);
|
|
|
if (debug) printf("%s trace at [0x%lx,0x%lx]\n", type == SETTRACE ? "setting" : "clearing", (long) start, (long) end);
|
|
|
- if (! could_send(&m, 0)) {
|
|
|
+ if (child_pid && ! could_send(&m, 0)) {
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
return 1;
|