| /****************************************************************************** | |
| * 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 | |
| ******************************************************************************/ | |
| #ifdef __gnu_linux__ | |
| #define _GNU_SOURCE | |
| #endif /* __gnu_linux__ */ | |
| #include "config.h" | |
| #include <sys/types.h> | |
| #include <sys/stat.h> | |
| #include <sys/wait.h> | |
| #include <stdlib.h> | |
| #include <unistd.h> | |
| #include <string.h> | |
| #include <errno.h> | |
| #include <fcntl.h> | |
| #include "dbg.h" | |
| #include "dbg_event.h" | |
| #include "backend.h" | |
| #include "list.h" | |
| static dbg_event * LastEvent; | |
| static void (*EventCallback)(dbg_event *); | |
| static int ServerExit; | |
| static int Started; | |
| static int TestInit(void (*)(dbg_event *)); | |
| static int TestProgress(void); | |
| static int TestInterrupt(void); | |
| static int TestStartSession(char *, char *, char *, char *, char **, char **, long); | |
| static int TestSetLineBreakpoint(int, int, int, char *, int, char*, int, int); | |
| static int TestSetFuncBreakpoint(int, int, int, char *, char *, char*, int, int); | |
| static int TestDeleteBreakpoint(int); | |
| static int TestEnableBreakpoint(int); | |
| static int TestDisableBreakpoint(int); | |
| static int TestConditionBreakpoint(int, char *expr); | |
| static int TestBreakpointAfter(int, int icount); | |
| static int TestWatchpoint(int, char *, int, int, char *, int); | |
| static int TestGo(void); | |
| static int TestStep(int, int); | |
| static int TestTerminate(void); | |
| static int TestListStackframes(int, int); | |
| static int TestSetCurrentStackframe(int); | |
| static int TestEvaluateExpression(char *); | |
| static int TestGetNativeType(char *); | |
| static int TestGetLocalVariables(void); | |
| static int TestListArguments(int, int); | |
| static int TestGetInfoThread(void); | |
| static int TestSetThreadSelect(int); | |
| static int TestStackInfoDepth(void); | |
| static int TestDataReadMemory(long, char*, char*, int, int, int, char*); | |
| static int TestDataWriteMemory(long, char*, char*, int, char*); | |
| static int TestGetGlobalVariables(void); | |
| static int TestListSignals(char*); | |
| static int TestSignalInfo(char*); | |
| static int TestHandle(char*); | |
| static int TestQuit(void); | |
| static int TestDataEvaluateExpression(char*); | |
| static int TestGetPartialAIF(char *, char *, int, int); | |
| static int TestVarDelete(char*); | |
| static int SetAndCheckBreak(int, int, int, char *, char *, int, int); | |
| dbg_backend_funcs TestBackend = | |
| { | |
| TestInit, | |
| TestProgress, | |
| TestInterrupt, | |
| TestStartSession, | |
| TestSetLineBreakpoint, | |
| TestSetFuncBreakpoint, | |
| TestDeleteBreakpoint, | |
| TestEnableBreakpoint, | |
| TestDisableBreakpoint, | |
| TestConditionBreakpoint, | |
| TestBreakpointAfter, | |
| TestWatchpoint, | |
| TestGo, | |
| TestStep, | |
| TestTerminate, | |
| TestListStackframes, | |
| TestSetCurrentStackframe, | |
| TestEvaluateExpression, | |
| TestGetNativeType, | |
| TestGetLocalVariables, | |
| TestListArguments, | |
| TestGetGlobalVariables, | |
| TestGetInfoThread, | |
| TestSetThreadSelect, | |
| TestStackInfoDepth, | |
| TestDataReadMemory, | |
| TestDataWriteMemory, | |
| TestListSignals, | |
| TestSignalInfo, | |
| TestHandle, | |
| TestDataEvaluateExpression, | |
| TestGetPartialAIF, | |
| TestVarDelete, | |
| TestQuit | |
| }; | |
| static void | |
| SaveEvent(dbg_event *e) | |
| { | |
| if (LastEvent != NULL) | |
| FreeDbgEvent(LastEvent); | |
| LastEvent = e; | |
| } | |
| /* | |
| * Initialize Test | |
| */ | |
| static int | |
| TestInit(void (*event_callback)(dbg_event *)) | |
| { | |
| EventCallback = event_callback; | |
| LastEvent = NULL; | |
| ServerExit = 0; | |
| signal(SIGTERM, SIG_IGN); | |
| signal(SIGHUP, SIG_IGN); | |
| signal(SIGINT, SIG_IGN); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| * Start Test session | |
| */ | |
| static int | |
| TestStartSession(char *test_path, char *prog, char *path, char *work_dir, char **args, char **env, long timeout) | |
| { | |
| Started = 0; | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| * Progress test commands. | |
| * | |
| * TODO: Deal with errors | |
| * | |
| * @return -1 server shutdown | |
| * 1 event callback | |
| * 0 completed operation | |
| */ | |
| static int | |
| TestProgress(void) | |
| { | |
| int res = 0; | |
| /* | |
| * Check for existing events | |
| */ | |
| if (LastEvent != NULL) { | |
| if (EventCallback != NULL) { | |
| EventCallback(LastEvent); | |
| res = 1; | |
| } | |
| if (ServerExit && LastEvent->event_id == DBGEV_OK) { | |
| res = -1; | |
| } | |
| FreeDbgEvent(LastEvent); | |
| LastEvent = NULL; | |
| return res; | |
| } | |
| return 0; | |
| } | |
| /* | |
| ** Set breakpoint at specified line. | |
| */ | |
| static int | |
| TestSetLineBreakpoint(int bpid, int isTemp, int isHard, char *file, int line, char *condition, int ignoreCount, int tid) | |
| { | |
| int res; | |
| char* where = NULL; | |
| res = SetAndCheckBreak(bpid, isTemp, isHard, where, condition, ignoreCount, tid); | |
| return res; | |
| } | |
| /* | |
| ** Set breakpoint at start of specified function. | |
| */ | |
| static int | |
| TestSetFuncBreakpoint(int bpid, int isTemp, int isHard, char *file, char *func, char *condition, int ignoreCount, int tid) | |
| { | |
| int res; | |
| char* where = NULL; | |
| res = SetAndCheckBreak(bpid, isTemp, isHard, where, condition, ignoreCount, tid); | |
| return res; | |
| } | |
| /* | |
| ** Check that breakpoint command has succeded and | |
| ** extract appropriate information. Returns breakpoint | |
| ** id in bid. Adds to breakpoint list if necessary. | |
| */ | |
| static int | |
| SetAndCheckBreak(int bpid, int isTemp, int isHard, char *where, char *condition, int ignoreCount, int tid) | |
| { | |
| /* | |
| dbg_event * e; | |
| e = NewDbgEvent(DBGEV_BPSET); | |
| e->dbg_event_u.bpset_event.bpid = bpid; | |
| e->dbg_event_u.bpset_event.bp = MIBreakpointNew(); | |
| SaveEvent(e); | |
| */ | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| ** Delete a breakpoint. | |
| */ | |
| static int | |
| TestDeleteBreakpoint(int bpid) | |
| { | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| ** Enable a breakpoint. | |
| */ | |
| static int | |
| TestEnableBreakpoint(int bpid) | |
| { | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| ** Disable a breakpoint. | |
| */ | |
| static int | |
| TestDisableBreakpoint(int bpid) | |
| { | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| ** Condition a breakpoint. | |
| */ | |
| static int | |
| TestConditionBreakpoint(int bpid, char *expr) | |
| { | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| ** breakpoint after. | |
| */ | |
| static int | |
| TestBreakpointAfter(int bpid, int icount) | |
| { | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| * Set watch point | |
| */ | |
| static int | |
| TestWatchpoint(int bpid, char *expr, int isAccess, int isRead, char *condition, int ignoreCount) | |
| { | |
| /* | |
| dbg_event * e; | |
| e = NewDbgEvent(DBGEV_BPSET); | |
| e->dbg_event_u.bpset_event.bpid = bpid; | |
| e->dbg_event_u.bpset_event.bp = MIBreakpointNew(); | |
| SaveEvent(e); | |
| */ | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| ** Start/continue executing program. | |
| */ | |
| static int | |
| TestGo(void) | |
| { | |
| //SendCommandWait(DebugSession, cmd); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| * Execute count statements. | |
| * | |
| * type step kind | |
| * 0 enter function calls | |
| * 1 do not enter function calls | |
| * 2 step out of function (count ignored) | |
| */ | |
| static int | |
| TestStep(int count, int type) | |
| { | |
| //SendCommandWait(DebugSession, cmd); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| ** Terminate program execution. | |
| */ | |
| static int | |
| TestTerminate(void) | |
| { | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| ** Interrupt an executing program. | |
| */ | |
| static int | |
| TestInterrupt(void) | |
| { | |
| //SendCommandWait(DebugSession, cmd); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| ** Move up or down count stack frames. | |
| */ | |
| static int | |
| TestSetCurrentStackframe(int level) | |
| { | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| ** List current or all stack frames. | |
| */ | |
| static int | |
| TestListStackframes(int low, int high) | |
| { | |
| /* | |
| dbg_event * e; | |
| e = NewDbgEvent(DBGEV_FRAMES); | |
| e->dbg_event_u.list = frames; | |
| SaveEvent(e); | |
| */ | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| ** List local variables. | |
| */ | |
| static int | |
| TestGetLocalVariables(void) | |
| { | |
| /* | |
| dbg_event * e; | |
| e = NewDbgEvent(DBGEV_VARS); | |
| e->dbg_event_u.list = NewList(); | |
| SaveEvent(e); | |
| */ | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| ** List arguments. | |
| */ | |
| static int | |
| TestListArguments(int low, int high) | |
| { | |
| /* | |
| dbg_event * e; | |
| e = NewDbgEvent(DBGEV_ARGS); | |
| e->dbg_event_u.list = NewList(); | |
| SaveEvent(e); | |
| */ | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| ** List global variables. | |
| */ | |
| static int | |
| TestGetGlobalVariables(void) | |
| { | |
| DbgSetError(DBGERR_NOTIMP, NULL); | |
| return DBGRES_ERR; | |
| } | |
| /* | |
| ** Quit debugger. | |
| */ | |
| static int | |
| TestQuit(void) | |
| { | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| ServerExit++; | |
| return DBGRES_OK; | |
| } | |
| static int | |
| TestGetInfoThread(void) | |
| { | |
| /* | |
| dbg_event * e; | |
| e = NewDbgEvent(DBGEV_THREADS); | |
| e->dbg_event_u.threads_event.thread_id = info->current_thread_id; | |
| e->dbg_event_u.threads_event.list = NewList(); | |
| SaveEvent(e); | |
| */ | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| static int | |
| TestSetThreadSelect(int threadNum) | |
| { | |
| /* | |
| dbg_event * e; | |
| e = NewDbgEvent(DBGEV_THREAD_SELECT); | |
| e->dbg_event_u.thread_select_event.thread_id = info->current_thread_id; | |
| e->dbg_event_u.thread_select_event.frame = s; | |
| SaveEvent(e); | |
| */ | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| static int | |
| TestStackInfoDepth() | |
| { | |
| /* | |
| dbg_event * e; | |
| e = NewDbgEvent(DBGEV_STACK_DEPTH); | |
| e->dbg_event_u.stack_depth = depth; | |
| SaveEvent(e); | |
| */ | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| static int | |
| TestDataReadMemory(long offset, char* address, char* format, int wordSize, int rows, int cols, char* asChar) | |
| { | |
| /* | |
| dbg_event * e; | |
| e = NewDbgEvent(DBGEV_DATAR_MEM); | |
| e->dbg_event_u.meminfo = meminfo; | |
| SaveEvent(e); | |
| */ | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| static int | |
| TestDataWriteMemory(long offset, char* address, char* format, int wordSize, char* value) | |
| { | |
| //TODO | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| static int | |
| TestListSignals(char* name) | |
| { | |
| /* | |
| dbg_event * e; | |
| e = NewDbgEvent(DBGEV_SIGNALS); | |
| e->dbg_event_u.list = signals; | |
| SaveEvent(e); | |
| */ | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| static int | |
| TestSignalInfo(char* arg) | |
| { | |
| //SendCommandWait(DebugSession, cmd); | |
| return DBGRES_OK; | |
| } | |
| static int | |
| TestHandle(char *arg) | |
| { | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| static int | |
| TestDataEvaluateExpression(char *arg) | |
| { | |
| /* | |
| dbg_event * e; | |
| e = NewDbgEvent(DBGEV_DATA_EVA_EX); | |
| e->dbg_event_u.data_expression = res; | |
| SaveEvent(e); | |
| */ | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| /* | |
| ** Evaluate the expression exp. | |
| */ | |
| static int | |
| TestEvaluateExpression(char *exp) | |
| { | |
| AIF *a; | |
| if (strcmp(exp, "long_string") == 0) { | |
| a = StringToAIF("testing start from 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 end 200"); | |
| dbg_event * e; | |
| e = NewDbgEvent(DBGEV_DATA); | |
| e->dbg_event_u.data_event.data = a; | |
| e->dbg_event_u.data_event.type_desc = "string"; | |
| SaveEvent(e); | |
| } | |
| else if (strcmp(exp, "long_long_string") == 0) { | |
| a = StringToAIF("testing start from \ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789\ | |
| end 5000"); | |
| dbg_event * e; | |
| e = NewDbgEvent(DBGEV_DATA); | |
| e->dbg_event_u.data_event.data = a; | |
| e->dbg_event_u.data_event.type_desc = "string"; | |
| SaveEvent(e); | |
| } | |
| else { | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| } | |
| return DBGRES_OK; | |
| } | |
| /* | |
| ** Find native type of variable. | |
| */ | |
| static int | |
| TestGetNativeType(char *var) | |
| { | |
| /* | |
| dbg_event * e; | |
| e = NewDbgEvent(DBGEV_TYPE); | |
| e->dbg_event_u.type_desc = type; | |
| SaveEvent(e); | |
| */ | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| /*************************** PARTIAL AIF ***************************/ | |
| static int | |
| TestGetPartialAIF(char* name, char* key, int listChildren, int express) | |
| { | |
| /* | |
| dbg_event * e; | |
| e = NewDbgEvent(DBGEV_PARTIAL_AIF); | |
| e->dbg_event_u.partial_aif_event.data = a; | |
| e->dbg_event_u.partial_aif_event.type_desc = strdup(mivar->type); | |
| e->dbg_event_u.partial_aif_event.name = strdup(mivar->name); | |
| SaveEvent(e); | |
| */ | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } | |
| static int | |
| TestVarDelete(char *name) | |
| { | |
| SaveEvent(NewDbgEvent(DBGEV_OK)); | |
| return DBGRES_OK; | |
| } |