blob: a2a9fccbe667899169d88d73e11fd103c2a176a7 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2005 The Regents of the University of California.
* This material was produced under U.S. Government contract W-7405-ENG-36
* for Los Alamos National Laboratory, which is operated by the University
* of California for the U.S. Department of Energy. The U.S. Government has
* rights to use, reproduce, and distribute this software. NEITHER THE
* GOVERNMENT NOR THE UNIVERSITY MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
* ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
* to produce derivative works, such modified software should be clearly
* marked, so as not to confuse it with the version available from LANL.
*
* Additionally, this program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* LA-CC 04-115
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "dbg.h"
#include "proxy.h"
#include "proxy_tcp.h"
#include "bitset.h"
#include "itimer.h"
int completed;
int fatal;
bitset * procs_outstanding = NULL;
bitset * sess_procs = NULL;
void
event_callback(dbg_event *e, void *data)
{
stackframe * f;
char * s;
printf("in event callback\n");
if (e == NULL) {
printf("got null event!\n");
return;
}
if (e->procs != NULL) {
if (sess_procs == NULL)
sess_procs = bitset_dup(e->procs);
s = bitset_to_set(e->procs);
printf("%s ", s);
free(s);
}
printf("-> ");
switch (e->event_id) {
case DBGEV_ERROR:
printf("error: %s\n", e->dbg_event_u.error_event.error_msg);
switch (e->dbg_event_u.error_event.error_code) {
case DBGERR_NOBACKEND:
fatal++;
break;
default:
break;
}
break;
case DBGEV_OK:
printf("command ok\n");
break;
case DBGEV_INIT:
printf("debugger initilized\n");
break;
case DBGEV_SUSPEND:
switch (e->dbg_event_u.suspend_event.reason) {
case DBGEV_SUSPEND_BPHIT:
printf("hit breakpoint %d\n", e->dbg_event_u.suspend_event.ev_u.bpid);
break;
case DBGEV_SUSPEND_INT:
printf("suspend completed\n");
break;
case DBGEV_SUSPEND_STEP:
printf("step completed\n");
break;
case DBGEV_SUSPEND_SIGNAL:
printf("received signal %s\n", e->dbg_event_u.suspend_event.ev_u.sig->name);
break;
}
break;
case DBGEV_BPSET:
printf("breakpoint set\n");
break;
case DBGEV_EXIT:
switch (e->dbg_event_u.suspend_event.reason) {
case DBGEV_EXIT_NORMAL:
printf("exited with status %d\n", e->dbg_event_u.exit_event.ev_u.exit_status);
break;
case DBGEV_EXIT_SIGNAL:
printf("exited with signal %s\n", e->dbg_event_u.exit_event.ev_u.sig->name);
break;
}
case DBGEV_DATA:
printf("data is "); AIFPrint(stdout, 0, e->dbg_event_u.data_event.data); printf("\n");
break;
case DBGEV_FRAMES:
printf("got frames:\n");
for (SetList(e->dbg_event_u.list); (f = (stackframe *)GetListElement(e->dbg_event_u.list)) != NULL; ) {
printf(" #%d %s() at %s:%d\n", f->level, f->loc.func, f->loc.file, f->loc.line);
}
break;
default:
printf("got event %d\n", e->event_id);
break;
}
if (e->procs != NULL && procs_outstanding != NULL) {
bitset_invert(e->procs);
bitset_andeq(procs_outstanding, e->procs);
if (!bitset_isempty(procs_outstanding))
return;
}
completed++;
}
int
wait_for_event(session *s, bitset *p)
{
completed = 0;
fatal = 0;
printf("entering wait_for_event...\n");
if (p != NULL)
procs_outstanding = bitset_dup(p);
while (!completed) {
if (DbgProgress(s) < 0) {
fprintf(stderr, "error: %s\n", DbgGetErrorStr());
exit(1);
}
}
if (p != NULL) {
bitset_free(procs_outstanding);
procs_outstanding = NULL;
}
/*
* Check a fatal error hasn't ocurred
*/
return fatal ? -1 : 0;
}
/*
* Tell server to quit
*/
void
cleanup_and_exit(session *s, bitset *p)
{
DbgQuit(s);
wait_for_event(s, p);
exit(0);
}
int
do_test(session *s, char *dir, char *exe)
{
bitset * p1;
int bpid = 54;
itimer * t;
t = itimer_new("debug");
itimer_start(t);
if (DbgStartSession(s, dir, exe, NULL) < 0) {
fprintf(stderr, "error: %s\n", DbgGetErrorStr());
return 1;
}
if (wait_for_event(s, NULL) < 0) {
cleanup_and_exit(s, NULL);
}
itimer_mark(t, "launch");
p1 = sess_procs;
if (DbgSetLineBreakpoint(s, p1, bpid++, "xxx.c", 17) < 0) {
fprintf(stderr, "error: %s\n", DbgGetErrorStr());
return 1;
}
wait_for_event(s, p1);
itimer_mark(t, "breakpoint");
if (DbgGo(s, p1) < 0) {
fprintf(stderr, "error: %s\n", DbgGetErrorStr());
return 1;
}
wait_for_event(s, p1);
itimer_mark(t, "suspend");
if (DbgListStackframes(s, p1, 0, 1) < 0) {
fprintf(stderr, "error: %s\n", DbgGetErrorStr());
return 1;
}
wait_for_event(s, p1);
itimer_mark(t, "where");
if (DbgStep(s, p1, 1, 0) < 0) {
fprintf(stderr, "error: %s\n", DbgGetErrorStr());
return 1;
}
wait_for_event(s, p1);
itimer_mark(t, "step");
if (DbgStep(s, p1, 1, 0) < 0) {
fprintf(stderr, "error: %s\n", DbgGetErrorStr());
return 1;
}
wait_for_event(s, p1);
itimer_mark(t, "step");
if (DbgEvaluateExpression(s, p1, "a") < 0) {
fprintf(stderr, "error: %s\n", DbgGetErrorStr());
return 1;
}
wait_for_event(s, p1);
itimer_mark(t, "evaluate");
if (DbgListStackframes(s, p1, 1, 1) < 0) {
fprintf(stderr, "error: %s\n", DbgGetErrorStr());
return 1;
}
wait_for_event(s, p1);
itimer_mark(t, "where");
if (DbgQuit(s) < 0) {
fprintf(stderr, "error: %s\n", DbgGetErrorStr());
return 1;
}
wait_for_event(s, p1);
itimer_stop(t);
itimer_print(t);
itimer_free(t);
exit(0);
}