blob: 0b47e58ac976d789def9d2b9629756f0ee672a49 [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 <string.h>
#include <unistd.h>
#include <errno.h>
#include "dbg.h"
#include "dbg_proxy.h"
#include "session.h"
#include "proxy.h"
#include "proxy_event.h"
#include "bitset.h"
#include "handler.h"
/*
* The TIMEOUT determines how often the debugger polls progress routines.
* Too often and it uses too much CPU, too few and things will slow down...
*/
#define CLIENT_TIMEOUT 50000
#define SERVER_TIMEOUT 50000
static void session_event_handler(void *, void *);
static proxy_clnt_helper_funcs clnt_helper_funcs = {
session_event_handler,
NULL
};
static void
session_event_handler(void *event, void *data)
{
dbg_event * ev;
proxy_msg * msg = (proxy_msg *)event;
session * s = (session *)data;
if (DbgDeserializeEvent(msg->msg_id, msg->num_args, msg->args, &ev) < 0)
return;
if (s->sess_event_handler != NULL)
s->sess_event_handler(ev, s->sess_event_data);
}
/*
* Session initialization
*/
int
DbgInit(session **sess, char *name, char *attr, ...)
{
va_list ap;
int res;
session * s;
struct timeval tv = {0, CLIENT_TIMEOUT};
s = (session *)malloc(sizeof(session));
clnt_helper_funcs.eventdata = (void *)s;
va_start(ap, attr);
res = proxy_clnt_init(name, &tv, &clnt_helper_funcs, &s->sess_proxy, attr, ap);
va_end(ap);
if (res < 0) {
free(s);
return -1;
}
s->sess_event_handler = NULL;
*sess = s;
return 0;
}
int
DbgConnect(session *s)
{
return proxy_clnt_connect(s->sess_proxy);
}
int
DbgCreate(session *s)
{
return proxy_clnt_create(s->sess_proxy);
}
int
DbgStartSession(session *s, char *dir, char *prog, char *args)
{
proxy_msg * msg = new_proxy_msg(DBG_STARTSESSION_CMD, 0);
proxy_msg_add_string(msg, dir);
proxy_msg_add_string(msg, prog);
proxy_msg_add_string(msg, args);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
/*
* Breakpoint operations
*/
int
DbgSetLineBreakpoint(session *s, bitset *set, int bpid, char *file, int line)
{
proxy_msg * msg = new_proxy_msg(DBG_SETLINEBREAKPOINT_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_int(msg, bpid);
proxy_msg_add_string(msg, file);
proxy_msg_add_int(msg, line);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgSetFuncBreakpoint(session *s, bitset *set, int bpid, char *file, char *func)
{
proxy_msg * msg = new_proxy_msg(DBG_SETFUNCBREAKPOINT_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_int(msg, bpid);
proxy_msg_add_string(msg, file);
proxy_msg_add_string(msg, func);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgDeleteBreakpoint(session *s, bitset *set, int bpid)
{
proxy_msg * msg = new_proxy_msg(DBG_DELETEBREAKPOINT_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_int(msg, bpid);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgEnableBreakpoint(session *s, bitset *set, int bpid)
{
proxy_msg * msg = new_proxy_msg(DBG_ENABLEBREAKPOINT_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_int(msg, bpid);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgDisableBreakpoint(session *s, bitset *set, int bpid)
{
proxy_msg * msg = new_proxy_msg(DBG_DISABLEBREAKPOINT_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_int(msg, bpid);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgConditionBreakpoint(session *s, bitset *set, int bpid, char *expr)
{
proxy_msg * msg = new_proxy_msg(DBG_CONDITIONBREAKPOINT_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_int(msg, bpid);
proxy_msg_add_string(msg, expr);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgBreakpointAfter(session *s, bitset *set, int bpid, int icount)
{
proxy_msg * msg = new_proxy_msg(DBG_BREAKPOINTAFTER_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_int(msg, bpid);
proxy_msg_add_int(msg, icount);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgSetWatchpoint(session *s, bitset *set, int bpid, char *expr, int access, int read, char *condition, int icount)
{
proxy_msg * msg = new_proxy_msg(DBG_SETWATCHPOINT_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_int(msg, bpid);
proxy_msg_add_string(msg, expr);
proxy_msg_add_int(msg, access);
proxy_msg_add_int(msg, read);
proxy_msg_add_string(msg, condition);
proxy_msg_add_int(msg, icount);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
/*
* Process control operations
*/
int
DbgGo(session *s, bitset *set)
{
proxy_msg * msg = new_proxy_msg(DBG_GO_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgStep(session *s, bitset *set, int count, int type)
{
proxy_msg * msg = new_proxy_msg(DBG_STEP_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_int(msg, count);
proxy_msg_add_int(msg, type);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgTerminate(session *s, bitset *set)
{
proxy_msg * msg = new_proxy_msg(DBG_TERMINATE_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgSuspend(session *s, bitset *set)
{
proxy_msg * msg = new_proxy_msg(DBG_SUSPEND_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
/*
* Stack frame operations
*/
int
DbgListStackframes(session *s, bitset *set, int low, int depth)
{
proxy_msg * msg = new_proxy_msg(DBG_LISTSTACKFRAMES_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_int(msg, low);
proxy_msg_add_int(msg, depth);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgSetCurrentStackframe(session *s, bitset *set, int level)
{
proxy_msg * msg = new_proxy_msg(DBG_SETCURRENTSTACKFRAME_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_int(msg, level);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
/*
* Expression/variable operations
*/
int
DbgEvaluateExpression(session *s, bitset *set, char *exp)
{
proxy_msg * msg = new_proxy_msg(DBG_EVALUATEEXPRESSION_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_string(msg, exp);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgGetType(session *s, bitset *set, char *exp)
{
proxy_msg * msg = new_proxy_msg(DBG_GETTYPE_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_string(msg, exp);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgListLocalVariables(session *s, bitset *set)
{
proxy_msg * msg = new_proxy_msg(DBG_LISTLOCALVARIABLES_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgListArguments(session *s, bitset *set, int low, int high)
{
proxy_msg * msg = new_proxy_msg(DBG_LISTARGUMENTS_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_int(msg, low);
proxy_msg_add_int(msg, high);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgListGlobalVariables(session *s, bitset *set)
{
proxy_msg * msg = new_proxy_msg(DBG_LISTGLOBALVARIABLES_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgListInfoThreads(session *s, bitset *set)
{
proxy_msg * msg = new_proxy_msg(DBG_LISTINFOTHREADS_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgSetThreadSelect(session *s, bitset *set, int threadNum)
{
proxy_msg * msg = new_proxy_msg(DBG_SETTHREADSELECT_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_int(msg, threadNum);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgStackInfoDepth(session *s, bitset *set)
{
proxy_msg * msg = new_proxy_msg(DBG_STACKINFODEPTH_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgDataReadMemory(session *s, bitset *set, long offset, char *address, char *format, int wordSize, int rows, int cols, char *asChar)
{
proxy_msg * msg = new_proxy_msg(DBG_DATAREADMEMORY_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_int(msg, offset);
proxy_msg_add_string(msg, address);
proxy_msg_add_string(msg, format);
proxy_msg_add_int(msg, wordSize);
proxy_msg_add_int(msg, rows);
proxy_msg_add_int(msg, cols);
proxy_msg_add_string(msg, asChar);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgDataWriteMemory(session *s, bitset *set, long offset, char *address, char *format, int wordSize, char *value)
{
proxy_msg * msg = new_proxy_msg(DBG_DATAWRITEMEMORY_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_int(msg, offset);
proxy_msg_add_string(msg, address);
proxy_msg_add_string(msg, format);
proxy_msg_add_int(msg, wordSize);
proxy_msg_add_string(msg, value);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgListSignals(session *s, bitset *set, char *name)
{
proxy_msg * msg = new_proxy_msg(DBG_LISTSIGNALS_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_string(msg, name);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgSignalInfo(session *s, bitset *set, char *arg)
{
proxy_msg * msg = new_proxy_msg(DBG_SIGNALINFO_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_string(msg, arg);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgCLIHandle(session *s, bitset *set, char *arg)
{
proxy_msg * msg = new_proxy_msg(DBG_CLIHANDLE_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_string(msg, arg);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgQuit(session *s)
{
proxy_msg * msg = new_proxy_msg(DBG_QUIT_CMD, 0);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgDataEvaluateExpression(session *s, bitset *set, char *arg)
{
proxy_msg * msg = new_proxy_msg(DBG_DATAEVALUATEEXPRESSION_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_string(msg, arg);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgGetPartialAIF(session *s, bitset *set, char *name, char *key, int listChildren, int express)
{
proxy_msg * msg = new_proxy_msg(DBG_GETPARTIALAIF_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_string(msg, name);
proxy_msg_add_string(msg, key);
proxy_msg_add_int(msg, listChildren);
proxy_msg_add_int(msg, express);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
int
DbgVariableDelete(session *s, bitset *set, char *arg)
{
proxy_msg * msg = new_proxy_msg(DBG_VARIABLEDELETE_CMD, 0);
proxy_msg_add_bitset(msg, set);
proxy_msg_add_string(msg, arg);
proxy_clnt_queue_msg(s->sess_proxy, msg);
free_proxy_msg(msg);
return 0;
}
/*
* Event handling
*/
int
DbgProgress(session *s)
{
return proxy_clnt_progress(s->sess_proxy);
}
void
DbgRegisterEventHandler(session *s, void (*event_callback)(dbg_event *, void *), void *data)
{
s->sess_event_handler = event_callback;
s->sess_event_data = data;
RegisterEventHandler(PROXY_EVENT_HANDLER, session_event_handler, (void *)s);
//s->sess_proxy->clnt_funcs->regeventhandler(s->sess_proxy_data, session_event_handler, (void *)s);
}
/**
* Unregister file descriptor handler
*/
void
DbgUnregisterEventHandler(session *s, void (*event_callback)(dbg_event *, void *))
{
s->sess_event_handler = NULL;
UnregisterEventHandler(PROXY_EVENT_HANDLER, session_event_handler);
}
/**
* Register a handler for file descriptor events.
*/
void
DbgRegisterReadFileHandler(session *s, int fd, int (*file_handler)(int, void *), void *data)
{
RegisterFileHandler(fd, READ_FILE_HANDLER, file_handler, data);
}
void
DbgRegisterWriteFileHandler(session *s, int fd, int (*file_handler)(int, void *), void *data)
{
RegisterFileHandler(fd, WRITE_FILE_HANDLER, file_handler, data);
}
void
DbgRegisterExceptFileHandler(session *s, int fd, int (*file_handler)(int, void *), void *data)
{
RegisterFileHandler(fd, EXCEPT_FILE_HANDLER, file_handler, data);
}
/**
* Unregister file descriptor handler
*/
void
DbgUnregisterFileHandler(session *s, int fd)
{
UnregisterFileHandler(fd);
}