| /****************************************************************************** | |
| * 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 <stdlib.h> | |
| #include <string.h> | |
| #include "dbg_event.h" | |
| #include "args.h" | |
| #include "proxy_msg.h" | |
| #define EMPTY "*" | |
| static void | |
| dbg_add_location(proxy_msg *m, location *loc) | |
| { | |
| proxy_msg_add_string(m, loc->file); | |
| proxy_msg_add_string(m, loc->func); | |
| proxy_msg_add_string(m, loc->addr); | |
| proxy_msg_add_int(m, loc->line); | |
| } | |
| static void | |
| dbg_add_breakpoint(proxy_msg *m, breakpoint *bp) | |
| { | |
| proxy_msg_add_int(m, bp->id); | |
| proxy_msg_add_int(m, bp->ignore); | |
| proxy_msg_add_int(m, bp->special); | |
| proxy_msg_add_int(m, bp->deleted); | |
| proxy_msg_add_string(m, bp->type); | |
| dbg_add_location(m, &bp->loc); | |
| proxy_msg_add_int(m, bp->hits); | |
| } | |
| static void | |
| dbg_add_signalinfo(proxy_msg *m, signal_info *sig) | |
| { | |
| if (sig == NULL) { | |
| proxy_msg_add_string(m, EMPTY); | |
| return; | |
| } | |
| proxy_msg_add_string(m, sig->name); | |
| proxy_msg_add_int(m, sig->stop); | |
| proxy_msg_add_int(m, sig->print); | |
| proxy_msg_add_int(m, sig->pass); | |
| proxy_msg_add_string(m, sig->desc); | |
| } | |
| static void | |
| dbg_add_stackframe(proxy_msg *m, stackframe *sf) | |
| { | |
| if (sf == NULL) { | |
| proxy_msg_add_string(m, EMPTY); | |
| return; | |
| } | |
| proxy_msg_add_int(m, sf->level); | |
| dbg_add_location(m, &sf->loc); | |
| } | |
| static void | |
| dbg_add_strings(proxy_msg *m, List *lst) | |
| { | |
| char * s; | |
| proxy_msg_add_int(m, SizeOfList(lst)); | |
| for (SetList(lst); (s = (char *)GetListElement(lst)) != NULL; ) { | |
| proxy_msg_add_string(m, s); | |
| } | |
| } | |
| static void | |
| dbg_add_stackframes(proxy_msg *m, List *lst) | |
| { | |
| stackframe * s; | |
| proxy_msg_add_int(m, SizeOfList(lst)); | |
| for (SetList(lst); (s = (stackframe *)GetListElement(lst)) != NULL; ) { | |
| dbg_add_stackframe(m, s); | |
| } | |
| } | |
| static void | |
| dbg_add_signals(proxy_msg *m, List *lst) | |
| { | |
| signal_info * s; | |
| proxy_msg_add_int(m, SizeOfList(lst)); | |
| for (SetList(lst); (s = (signal_info *)GetListElement(lst)) != NULL; ) { | |
| dbg_add_signalinfo(m, s); | |
| } | |
| } | |
| static void | |
| dbg_add_memory(proxy_msg *m, memory *mem) | |
| { | |
| if (mem == NULL) { | |
| proxy_msg_add_string(m, EMPTY); | |
| return; | |
| } | |
| proxy_msg_add_string(m, mem->addr); | |
| proxy_msg_add_string(m, mem->ascii); | |
| dbg_add_strings(m, mem->data); | |
| } | |
| static void | |
| dbg_add_memories(proxy_msg *m, List *lst) | |
| { | |
| memory * mem; | |
| proxy_msg_add_int(m, SizeOfList(lst)); | |
| for (SetList(lst); (mem = (memory *)GetListElement(lst)) != NULL; ) { | |
| dbg_add_memory(m, mem); | |
| } | |
| } | |
| static void | |
| dbg_add_memoryinfo(proxy_msg *m, memoryinfo *meninfo) | |
| { | |
| if (meninfo == NULL) { | |
| proxy_msg_add_string(m, EMPTY); | |
| return; | |
| } | |
| proxy_msg_add_string(m, meninfo->addr); | |
| proxy_msg_add_int(m, meninfo->nextRow); | |
| proxy_msg_add_int(m, meninfo->prevRow); | |
| proxy_msg_add_int(m, meninfo->nextPage); | |
| proxy_msg_add_int(m, meninfo->prevPage); | |
| proxy_msg_add_int(m, meninfo->numBytes); | |
| proxy_msg_add_int(m, meninfo->totalBytes); | |
| dbg_add_memories(m, meninfo->memories); | |
| } | |
| static void | |
| dbg_add_aif(proxy_msg *m, AIF *a) | |
| { | |
| proxy_msg_add_string(m, AIF_FORMAT(a)); | |
| proxy_msg_add_data(m, AIF_DATA(a), AIF_LEN(a)); | |
| } | |
| /* | |
| * Serialize a debug event for sending between debug servers. | |
| * | |
| * Note that the serialized event does not include the bitset, since it is | |
| * only relevant to communication with the client. The bitset is | |
| * added just prior to sending back to the client. | |
| */ | |
| int | |
| DbgSerializeEvent(dbg_event *e, unsigned char **result, int *len) | |
| { | |
| int res = 0; | |
| proxy_msg * p = NULL; | |
| if (e == NULL) | |
| return -1; | |
| p = new_proxy_msg(e->event_id, e->trans_id); | |
| switch (e->event_id) | |
| { | |
| case DBGEV_OK: | |
| break; | |
| case DBGEV_ERROR: | |
| proxy_msg_add_int(p, e->dbg_event_u.error_event.error_code); | |
| proxy_msg_add_string(p, e->dbg_event_u.error_event.error_msg); | |
| break; | |
| case DBGEV_OUTPUT: | |
| proxy_msg_add_string(p, e->dbg_event_u.output); | |
| break; | |
| case DBGEV_SUSPEND: | |
| proxy_msg_add_int(p, e->dbg_event_u.suspend_event.reason); | |
| switch (e->dbg_event_u.suspend_event.reason) { | |
| case DBGEV_SUSPEND_BPHIT: | |
| proxy_msg_add_int(p, e->dbg_event_u.suspend_event.ev_u.bpid); | |
| proxy_msg_add_int(p, e->dbg_event_u.suspend_event.thread_id); | |
| proxy_msg_add_int(p, e->dbg_event_u.suspend_event.depth); | |
| dbg_add_strings(p, e->dbg_event_u.suspend_event.changed_vars); | |
| break; | |
| case DBGEV_SUSPEND_SIGNAL: | |
| dbg_add_signalinfo(p, e->dbg_event_u.suspend_event.ev_u.sig); | |
| dbg_add_stackframe(p, e->dbg_event_u.suspend_event.frame); | |
| proxy_msg_add_int(p, e->dbg_event_u.suspend_event.thread_id); | |
| proxy_msg_add_int(p, e->dbg_event_u.suspend_event.depth); | |
| dbg_add_strings(p, e->dbg_event_u.suspend_event.changed_vars); | |
| break; | |
| case DBGEV_SUSPEND_STEP: | |
| case DBGEV_SUSPEND_INT: | |
| dbg_add_stackframe(p, e->dbg_event_u.suspend_event.frame); | |
| proxy_msg_add_int(p, e->dbg_event_u.suspend_event.thread_id); | |
| proxy_msg_add_int(p, e->dbg_event_u.suspend_event.depth); | |
| dbg_add_strings(p, e->dbg_event_u.suspend_event.changed_vars); | |
| break; | |
| } | |
| break; | |
| case DBGEV_BPSET: | |
| proxy_msg_add_int(p, e->dbg_event_u.bpset_event.bpid); | |
| dbg_add_breakpoint(p, e->dbg_event_u.bpset_event.bp); | |
| break; | |
| case DBGEV_SIGNALS: | |
| dbg_add_signals(p, e->dbg_event_u.list); | |
| break; | |
| case DBGEV_EXIT: | |
| proxy_msg_add_int(p, e->dbg_event_u.exit_event.reason); | |
| switch (e->dbg_event_u.exit_event.reason) { | |
| case DBGEV_EXIT_NORMAL: | |
| proxy_msg_add_int(p, e->dbg_event_u.exit_event.ev_u.exit_status); | |
| break; | |
| case DBGEV_EXIT_SIGNAL: | |
| dbg_add_signalinfo(p, e->dbg_event_u.exit_event.ev_u.sig); | |
| break; | |
| } | |
| break; | |
| case DBGEV_FRAMES: | |
| dbg_add_stackframes(p, e->dbg_event_u.list); | |
| break; | |
| case DBGEV_THREAD_SELECT: | |
| proxy_msg_add_int(p, e->dbg_event_u.thread_select_event.thread_id); | |
| dbg_add_stackframe(p, e->dbg_event_u.thread_select_event.frame); | |
| break; | |
| case DBGEV_THREADS: | |
| proxy_msg_add_int(p, e->dbg_event_u.threads_event.thread_id); | |
| dbg_add_strings(p, e->dbg_event_u.threads_event.list); | |
| break; | |
| case DBGEV_STACK_DEPTH: | |
| proxy_msg_add_int(p, e->dbg_event_u.stack_depth); | |
| break; | |
| case DBGEV_DATAR_MEM: | |
| dbg_add_memoryinfo(p, e->dbg_event_u.meminfo); | |
| break; | |
| case DBGEV_VARS: | |
| dbg_add_strings(p, e->dbg_event_u.list); | |
| break; | |
| case DBGEV_ARGS: | |
| dbg_add_strings(p, e->dbg_event_u.list); | |
| break; | |
| case DBGEV_TYPE: | |
| proxy_msg_add_string(p, e->dbg_event_u.type_desc); | |
| break; | |
| case DBGEV_DATA: | |
| dbg_add_aif(p, e->dbg_event_u.data_event.data); | |
| proxy_msg_add_string(p, e->dbg_event_u.data_event.type_desc); | |
| proxy_msg_add_string(p, e->dbg_event_u.data_event.name); | |
| break; | |
| default: | |
| res = -1; | |
| break; | |
| } | |
| res = proxy_serialize_msg(p, result, len); | |
| free_proxy_msg(p); | |
| return res; | |
| } | |
| static int | |
| dbg_str_to_int(char ***args, int *nargs, int *val) | |
| { | |
| if (*nargs < 1) | |
| return -1; | |
| proxy_get_int(*(*args)++, val); | |
| (*nargs)--; | |
| return 0; | |
| } | |
| static int | |
| dbg_copy_str(char ***args, int *nargs, char **str) | |
| { | |
| if (*nargs < 1) | |
| return -1; | |
| *str = strdup(*(*args)++); | |
| (*nargs)--; | |
| return 0; | |
| } | |
| static int | |
| dbg_str_to_data(char ***args, int *nargs, char **data, int *len) | |
| { | |
| if (*nargs < 1) | |
| return -1; | |
| proxy_get_data(*(*args)++, data, len); | |
| (*nargs)--; | |
| return 0; | |
| } | |
| static int | |
| dbg_str_to_location(char ***args, int *nargs, location *loc) | |
| { | |
| if (dbg_copy_str(args, nargs, &loc->file) < 0 || | |
| dbg_copy_str(args, nargs, &loc->func) < 0 || | |
| dbg_copy_str(args, nargs, &loc->addr) < 0 || | |
| dbg_str_to_int(args, nargs, &loc->line) < 0) { | |
| FreeLocation(loc); | |
| return -1; | |
| } | |
| return 0; | |
| } | |
| static int | |
| dbg_str_to_breakpoint(char ***args, int *nargs, breakpoint **bp) | |
| { | |
| int id; | |
| breakpoint * b; | |
| if (dbg_str_to_int(args, nargs, &id) < 0) { | |
| return -1; | |
| } | |
| b = NewBreakpoint(id); | |
| if (dbg_str_to_int(args, nargs, &b->ignore) < 0 || | |
| dbg_str_to_int(args, nargs, &b->special) < 0 || | |
| dbg_str_to_int(args, nargs, &b->deleted) < 0 || | |
| dbg_copy_str(args, nargs, &b->type) < 0 || | |
| dbg_str_to_location(args, nargs, &b->loc) < 0 || | |
| dbg_str_to_int(args, nargs, &b->hits) < 0) { | |
| FreeBreakpoint(b); | |
| return -1; | |
| } | |
| *bp = b; | |
| return 0; | |
| } | |
| static int | |
| dbg_str_to_stackframe(char ***args, int *nargs, stackframe **frame) | |
| { | |
| int level; | |
| stackframe * sf; | |
| if (strcmp(*(*args), EMPTY) == 0) { | |
| (*args)++; | |
| (*nargs)--; | |
| *frame = NULL; | |
| return 0; | |
| } | |
| if (dbg_str_to_int(args, nargs, &level) < 0) { | |
| return -1; | |
| } | |
| sf = NewStackframe(level); | |
| if (dbg_str_to_location(args, nargs, &sf->loc) < 0) { | |
| FreeStackframe(sf); | |
| return -1; | |
| } | |
| *frame = sf; | |
| return 0; | |
| } | |
| static int | |
| dbg_str_to_signalinfo(char ***args, int *nargs, signal_info **sig) | |
| { | |
| signal_info *s; | |
| if (strcmp(*(*args), EMPTY) == 0) { | |
| (*args)++; | |
| (*nargs)--; | |
| *sig = NULL; | |
| return 0; | |
| } | |
| s = NewSignalInfo(); | |
| if (dbg_copy_str(args, nargs, &s->name) < 0 || | |
| dbg_str_to_int(args, nargs, &s->stop) < 0 || | |
| dbg_str_to_int(args, nargs, &s->print) < 0 || | |
| dbg_str_to_int(args, nargs, &s->pass) < 0 || | |
| dbg_copy_str(args, nargs, &s->desc) < 0) { | |
| FreeSignalInfo(s); | |
| return -1; | |
| } | |
| *sig = s; | |
| return 0; | |
| } | |
| static int | |
| dbg_str_to_stackframes(char ***args, int *nargs, List **lst) | |
| { | |
| int i; | |
| int count; | |
| stackframe * sf; | |
| if (dbg_str_to_int(args, nargs, &count) < 0) { | |
| return -1; | |
| } | |
| *lst = NewList(); | |
| for (i = 0; i < count; i++) { | |
| if (dbg_str_to_stackframe(args, nargs, &sf) < 0) { | |
| DestroyList(*lst, FreeStackframe); | |
| return -1; | |
| } | |
| AddToList(*lst, (void *)sf); | |
| } | |
| return 0; | |
| } | |
| static int | |
| dbg_str_to_signals(char ***args, int *nargs, List **lst) | |
| { | |
| int i; | |
| int count; | |
| signal_info * sig; | |
| if (dbg_str_to_int(args, nargs, &count) < 0) { | |
| } | |
| *lst = NewList(); | |
| for (i = 0; i < count; i++) { | |
| if (dbg_str_to_signalinfo(args, nargs, &sig) < 0) { | |
| DestroyList(*lst, FreeMemory); | |
| return -1; | |
| } | |
| AddToList(*lst, (void *)sig); | |
| } | |
| return 0; | |
| } | |
| static int | |
| dbg_str_to_list(char ***args, int *nargs, List **lst) | |
| { | |
| int i; | |
| int count; | |
| char * str; | |
| if (dbg_str_to_int(args, nargs, &count) < 0) { | |
| return -1; | |
| } | |
| *lst = NewList(); | |
| for (i = 0; i < count; i++) { | |
| if (dbg_copy_str(args, nargs, &str) < 0) { | |
| DestroyList(*lst, free); | |
| return -1; | |
| } | |
| AddToList(*lst, (void *)str); | |
| } | |
| return 0; | |
| } | |
| static int | |
| dbg_str_to_aif(char ***args, int *nargs, AIF **res) | |
| { | |
| int data_len; | |
| AIF * a; | |
| char * fmt; | |
| char * data; | |
| if (dbg_copy_str(args, nargs, &fmt) < 0 || | |
| dbg_str_to_data(args, nargs, &data, &data_len) < 0) { | |
| return -1; | |
| } | |
| a = NewAIF(0, 0); | |
| AIF_FORMAT(a) = fmt; | |
| AIF_DATA(a) = data; | |
| AIF_LEN(a) = data_len; | |
| *res = a; | |
| return 0; | |
| } | |
| static int | |
| dbg_str_to_memory_data(char ***args, int *nargs, List **lst) | |
| { | |
| int i; | |
| int count; | |
| char * str; | |
| if (dbg_str_to_int(args, nargs, &count) < 0) { | |
| return -1; | |
| } | |
| *lst = NewList(); | |
| for (i = 0; i < count; i++) { | |
| if (dbg_copy_str(args, nargs, &str) < 0) { | |
| DestroyList(*lst, free); | |
| return -1; | |
| } | |
| AddToList(*lst, (void *)str); | |
| } | |
| return 0; | |
| } | |
| static int | |
| dbg_str_to_memory(char ***args, int *nargs, List **lst) | |
| { | |
| int i; | |
| int count; | |
| memory * m; | |
| if (dbg_str_to_int(args, nargs, &count) < 0) { | |
| } | |
| *lst = NewList(); | |
| for (i = 0; i < count; i++) { | |
| m = NewMemory(); | |
| if (dbg_copy_str(args, nargs, &m->addr) < 0 || | |
| dbg_copy_str(args, nargs, &m->ascii) < 0 || | |
| dbg_str_to_memory_data(args, nargs, &m->data) < 0) { | |
| DestroyList(*lst, FreeMemory); | |
| return -1; | |
| } | |
| AddToList(*lst, (void *)m); | |
| } | |
| return 0; | |
| } | |
| static int | |
| dbg_str_to_memoryinfo(char ***args, int *nargs, memoryinfo **info) | |
| { | |
| memoryinfo * meminfo; | |
| if (*nargs < 1) | |
| return -1; | |
| if (strcmp(*(*args), EMPTY) == 0) { | |
| (*args)++; | |
| (*nargs)--; | |
| *info = NULL; | |
| } | |
| meminfo = NewMemoryInfo(); | |
| if (dbg_copy_str(args, nargs, &meminfo->addr) < 0 || | |
| dbg_str_to_int(args, nargs, (int *)&meminfo->nextRow) < 0 || | |
| dbg_str_to_int(args, nargs, (int *)&meminfo->prevRow) < 0 || | |
| dbg_str_to_int(args, nargs, (int *)&meminfo->nextPage) < 0 || | |
| dbg_str_to_int(args, nargs, (int *)&meminfo->prevPage) < 0 || | |
| dbg_str_to_int(args, nargs, (int *)&meminfo->numBytes) < 0 || | |
| dbg_str_to_int(args, nargs, (int *)&meminfo->totalBytes) < 0 || | |
| dbg_str_to_memory(args, nargs, &meminfo->memories) < 0) { | |
| FreeMemoryInfo(meminfo); | |
| return -1; | |
| } | |
| *info = meminfo; | |
| return 0; | |
| } | |
| /* | |
| * Convert an array of strings (as a result of deserializing a proxy message) | |
| * into a debug event. | |
| */ | |
| int | |
| DbgDeserializeEvent(int id, int nargs, char **args, dbg_event **ev) | |
| { | |
| dbg_event * e = NULL; | |
| e = NewDbgEvent(id); | |
| switch (id) | |
| { | |
| case DBGEV_OK: | |
| break; | |
| case DBGEV_ERROR: | |
| dbg_str_to_int(&args, &nargs, &e->dbg_event_u.error_event.error_code); | |
| dbg_copy_str(&args, &nargs, &e->dbg_event_u.error_event.error_msg); | |
| break; | |
| case DBGEV_OUTPUT: | |
| dbg_copy_str(&args, &nargs, &e->dbg_event_u.output); | |
| break; | |
| case DBGEV_SUSPEND: | |
| dbg_str_to_int(&args, &nargs, &e->dbg_event_u.suspend_event.reason); | |
| switch (e->dbg_event_u.suspend_event.reason) { | |
| case DBGEV_SUSPEND_BPHIT: | |
| dbg_str_to_int(&args, &nargs, &e->dbg_event_u.suspend_event.ev_u.bpid); | |
| dbg_str_to_int(&args, &nargs, &e->dbg_event_u.suspend_event.thread_id); | |
| dbg_str_to_int(&args, &nargs, &e->dbg_event_u.suspend_event.depth); | |
| dbg_str_to_list(&args, &nargs, &e->dbg_event_u.suspend_event.changed_vars); | |
| break; | |
| case DBGEV_SUSPEND_SIGNAL: | |
| dbg_str_to_signalinfo(&args, &nargs, &e->dbg_event_u.suspend_event.ev_u.sig); | |
| dbg_str_to_stackframe(&args, &nargs, &e->dbg_event_u.suspend_event.frame); | |
| dbg_str_to_int(&args, &nargs, &e->dbg_event_u.suspend_event.thread_id); | |
| dbg_str_to_int(&args, &nargs, &e->dbg_event_u.suspend_event.depth); | |
| dbg_str_to_list(&args, &nargs, &e->dbg_event_u.suspend_event.changed_vars); | |
| break; | |
| case DBGEV_SUSPEND_STEP: | |
| case DBGEV_SUSPEND_INT: | |
| dbg_str_to_stackframe(&args, &nargs, &e->dbg_event_u.suspend_event.frame); | |
| dbg_str_to_int(&args, &nargs, &e->dbg_event_u.suspend_event.thread_id); | |
| dbg_str_to_int(&args, &nargs, &e->dbg_event_u.suspend_event.depth); | |
| dbg_str_to_list(&args, &nargs, &e->dbg_event_u.suspend_event.changed_vars); | |
| break; | |
| default: | |
| goto error_out; | |
| } | |
| break; | |
| case DBGEV_BPSET: | |
| dbg_str_to_int(&args, &nargs, &e->dbg_event_u.bpset_event.bpid); | |
| dbg_str_to_breakpoint(&args, &nargs, &e->dbg_event_u.bpset_event.bp); | |
| break; | |
| case DBGEV_SIGNALS: | |
| dbg_str_to_signals(&args, &nargs, &e->dbg_event_u.list); | |
| break; | |
| case DBGEV_EXIT: | |
| dbg_str_to_int(&args, &nargs, &e->dbg_event_u.exit_event.reason); | |
| switch (e->dbg_event_u.exit_event.reason) { | |
| case DBGEV_EXIT_NORMAL: | |
| dbg_str_to_int(&args, &nargs, &e->dbg_event_u.exit_event.ev_u.exit_status); | |
| break; | |
| case DBGEV_EXIT_SIGNAL: | |
| dbg_str_to_signalinfo(&args, &nargs, &e->dbg_event_u.exit_event.ev_u.sig); | |
| break; | |
| default: | |
| goto error_out; | |
| } | |
| break; | |
| case DBGEV_FRAMES: | |
| dbg_str_to_stackframes(&args, &nargs, &e->dbg_event_u.list); | |
| break; | |
| case DBGEV_THREAD_SELECT: | |
| dbg_str_to_int(&args, &nargs, &e->dbg_event_u.thread_select_event.thread_id); | |
| dbg_str_to_stackframe(&args, &nargs, &e->dbg_event_u.thread_select_event.frame); | |
| break; | |
| case DBGEV_THREADS: | |
| dbg_str_to_int(&args, &nargs, &e->dbg_event_u.threads_event.thread_id); | |
| dbg_str_to_list(&args, &nargs, &e->dbg_event_u.threads_event.list); | |
| break; | |
| case DBGEV_STACK_DEPTH: | |
| dbg_str_to_int(&args, &nargs, &e->dbg_event_u.stack_depth); | |
| break; | |
| case DBGEV_DATAR_MEM: | |
| dbg_str_to_memoryinfo(&args, &nargs, &e->dbg_event_u.meminfo); | |
| break; | |
| case DBGEV_VARS: | |
| dbg_str_to_list(&args, &nargs, &e->dbg_event_u.list); | |
| break; | |
| case DBGEV_ARGS: | |
| dbg_str_to_list(&args,&nargs, &e->dbg_event_u.list); | |
| break; | |
| case DBGEV_TYPE: | |
| dbg_copy_str(&args, &nargs, &e->dbg_event_u.type_desc); | |
| break; | |
| case DBGEV_DATA: | |
| dbg_str_to_aif(&args, &nargs, &e->dbg_event_u.data_event.data); | |
| dbg_copy_str(&args, &nargs, &e->dbg_event_u.data_event.type_desc); | |
| dbg_copy_str(&args, &nargs, &e->dbg_event_u.data_event.name); | |
| break; | |
| default: | |
| goto error_out; | |
| } | |
| *ev = e; | |
| return 0; | |
| error_out: | |
| if (e != NULL) | |
| FreeDbgEvent(e); | |
| return -1; | |
| } | |
| dbg_event * | |
| NewDbgEvent(int event) { | |
| dbg_event * e = (dbg_event *)malloc(sizeof(dbg_event)); | |
| memset((void *)e, 0, sizeof(dbg_event)); | |
| e->event_id = event; | |
| return e; | |
| } | |
| void | |
| FreeDbgEvent(dbg_event *e) { | |
| switch (e->event_id) { | |
| case DBGEV_OK: | |
| break; | |
| case DBGEV_OUTPUT: | |
| free(e->dbg_event_u.output); | |
| break; | |
| case DBGEV_SUSPEND: | |
| switch (e->dbg_event_u.suspend_event.reason) { | |
| case DBGEV_SUSPEND_SIGNAL: | |
| if (e->dbg_event_u.suspend_event.ev_u.sig != NULL) { | |
| FreeSignalInfo(e->dbg_event_u.suspend_event.ev_u.sig); | |
| } | |
| break; | |
| case DBGEV_SUSPEND_INT: | |
| case DBGEV_SUSPEND_STEP: | |
| break; | |
| case DBGEV_SUSPEND_BPHIT: | |
| break; | |
| } | |
| if (e->dbg_event_u.suspend_event.frame != NULL) { | |
| FreeStackframe(e->dbg_event_u.suspend_event.frame); | |
| } | |
| if (e->dbg_event_u.suspend_event.changed_vars != NULL) { | |
| DestroyList(e->dbg_event_u.suspend_event.changed_vars, free); | |
| } | |
| break; | |
| case DBGEV_EXIT: | |
| switch (e->dbg_event_u.suspend_event.reason) { | |
| case DBGEV_EXIT_SIGNAL: | |
| if (e->dbg_event_u.suspend_event.ev_u.sig != NULL) { | |
| FreeSignalInfo(e->dbg_event_u.suspend_event.ev_u.sig); | |
| } | |
| break; | |
| case DBGEV_EXIT_NORMAL: | |
| break; | |
| } | |
| break; | |
| case DBGEV_FRAMES: | |
| if (e->dbg_event_u.list != NULL) { | |
| DestroyList(e->dbg_event_u.list, FreeStackframe); | |
| } | |
| break; | |
| case DBGEV_DATA: | |
| if (e->dbg_event_u.data_event.data != NULL) { | |
| AIFFree(e->dbg_event_u.data_event.data); | |
| } | |
| if (e->dbg_event_u.data_event.type_desc != NULL) { | |
| free(e->dbg_event_u.data_event.type_desc); | |
| } | |
| if (e->dbg_event_u.data_event.name != NULL) { | |
| free(e->dbg_event_u.data_event.name); | |
| } | |
| break; | |
| case DBGEV_TYPE: | |
| if (e->dbg_event_u.type_desc != NULL) { | |
| free(e->dbg_event_u.type_desc); | |
| } | |
| break; | |
| case DBGEV_THREAD_SELECT: | |
| if (e->dbg_event_u.thread_select_event.frame != NULL) { | |
| FreeStackframe(e->dbg_event_u.thread_select_event.frame); | |
| } | |
| break; | |
| case DBGEV_THREADS: | |
| if (e->dbg_event_u.threads_event.list != NULL) { | |
| DestroyList(e->dbg_event_u.threads_event.list, free); | |
| } | |
| break; | |
| case DBGEV_DATAR_MEM: | |
| if (e->dbg_event_u.meminfo != NULL) { | |
| FreeMemoryInfo(e->dbg_event_u.meminfo); | |
| } | |
| break; | |
| case DBGEV_ARGS: | |
| case DBGEV_VARS: | |
| if (e->dbg_event_u.list != NULL) { | |
| DestroyList(e->dbg_event_u.list, free); | |
| } | |
| break; | |
| case DBGEV_SIGNALS: | |
| if (e->dbg_event_u.list != NULL) { | |
| DestroyList(e->dbg_event_u.list, FreeSignalInfo); | |
| } | |
| break; | |
| case DBGEV_BPSET: | |
| if (e->dbg_event_u.bpset_event.bp != NULL) { | |
| FreeBreakpoint(e->dbg_event_u.bpset_event.bp); | |
| } | |
| break; | |
| case DBGEV_ERROR: | |
| if (e->dbg_event_u.error_event.error_msg != NULL) { | |
| free(e->dbg_event_u.error_event.error_msg); | |
| } | |
| } | |
| if (e->procs != NULL) { | |
| bitset_free(e->procs); | |
| } | |
| free(e); | |
| } | |
| dbg_event * | |
| DbgErrorEvent(int err, char *msg) | |
| { | |
| dbg_event * e = NewDbgEvent(DBGEV_ERROR); | |
| e->dbg_event_u.error_event.error_code = err; | |
| if (msg != NULL) { | |
| e->dbg_event_u.error_event.error_msg = strdup(msg); | |
| } | |
| return e; | |
| } |