/** * fixup for cfg set breakpoint function */ static int fixup_dbg_breakpoint(void** param, int param_no) { struct action *a; char *p; if(param_no!=1) return -1; a = dbg_fixup_get_action(param, param_no); p = (char*)(*param); return dbg_add_breakpoint(a, (*p=='0')?0:1); }
/* * 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; }
/* * dbg_sh_break * * Installs, deletes or configures a breakpoint * * Usage: * break {<address>|-n <name>|-l} -o {add|delete|get|inc|reset} [-c client] * * <address> Address to watch * -n name Name of the breakpoint (default 0xADDRESS) * At least one of both the address or the name has to be defined. * You can define both at one time for the add parameter. * -l Just list all break points (-o will be ignored) * * -c sid Use a special sid (if not defined the current client will be used) * * -o <op> Operation for breakpoint: * add Add a new breakpoint * delete Deletes an existing breakpoint * inc Increments its usage counter * get Reads its usage counter * reset Resets its usage counter * */ int dbg_sh_break(void) { dbg_shell_t *l__shell = *dbg_tls_shellptr; sid_t l__sid = 0; uintptr_t l__adr; utf8_t *l__name = NULL; int l__infopar = 0; /* We need at least the address parameter */ if (l__shell->n_pars < 2) { dbg_iprintf(l__shell->terminal, "Missing parameter. Try \"help break\" for more informations.\n"); return -1; } /* Get the SID */ l__sid = dbg_get_sidpar("break", SIDTYPE_THREAD); if (l__sid == SID_INVALID) return -1; /* Get the client structure */ mtx_lock(&dbg_clients_mtx, -1); dbg_client_t* l__client = dbg_find_client(l__sid); if (l__client == NULL) { mtx_unlock(&dbg_clients_mtx); dbg_iprintf(l__shell->terminal, "Can't find client 0x%X for \"break\".\n", l__sid); return 0xFFFFFFFF; } /* Address or name? */ if ((l__infopar = dbg_test_par(0, "-n")) > -1) { if (((unsigned)l__infopar + 1) >= l__shell->n_pars) { dbg_iprintf(l__shell->terminal, "Missing name parameter. Try \"help break\" for more informations.\n"); mtx_unlock(&dbg_clients_mtx); return -1; } l__name = l__shell->pars[l__infopar + 1]; l__adr = dbg_get_breakpoint_adr(l__client, l__shell->pars[l__infopar + 1]); if ((l__adr == 0) && (dbg_test_par(0, "add") == -1)) { dbg_iprintf(l__shell->terminal, "Can't find breakpoint %s.\n", l__shell->pars[l__infopar + 1]); mtx_unlock(&dbg_clients_mtx); return -1; } /* Read address although, if add operation */ if (dbg_test_par(0, "add") > -1) { /* Read address */ if (dbglib_atoul(l__shell->pars[1], &l__adr, 16)) { dbg_iprintf(l__shell->terminal, "Invalid address - %s.\n", l__shell->pars[1]); mtx_unlock(&dbg_clients_mtx); return -1; } } } else if (dbg_test_par(0, "-l") > -1) { /* Just list all breakpoints */ dbg_breaks_t *l__brk = l__client->breakpoints; int l__i = 0; while (l__brk != NULL) { dbg_iprintf(l__shell->terminal, "%.32s\t0x%.8X\t\t%i\n", l__brk->name, l__brk->address, l__brk->count); l__brk = l__brk->ls.n; l__i ++; if (l__i > 20) dbg_pause(l__shell->terminal); } mtx_unlock(&dbg_clients_mtx); return 0; } else { /* Read address */ if (dbglib_atoul(l__shell->pars[1], &l__adr, 16)) { dbg_iprintf(l__shell->terminal, "Invalid address - %s.\n", l__shell->pars[1]); mtx_unlock(&dbg_clients_mtx); return -1; } } /* Address 0 is invalid */ if (l__adr == 0) { dbg_iprintf(l__shell->terminal, "Invalid breakpoint address 0x%X.\n", l__adr); mtx_unlock(&dbg_clients_mtx); return -1; } /* Find the operation parameter */ if ((l__infopar = dbg_test_par(0, "-o")) > -1) { /* Is there a following parameter to -o? */ if (((unsigned)l__infopar + 1) >= l__shell->n_pars) { dbg_iprintf(l__shell->terminal, "Missing operation parameter. Try \"help break\" for more informations.\n"); mtx_unlock(&dbg_clients_mtx); return -1; } /* Test the operations */ if (!str_compare(l__shell->pars[l__infopar +1], "add", 3)) { int l__do_free_name = 0; /* Operation add */ if (l__name == NULL) { l__name = mem_alloc(12); if (l__name == NULL) { dbg_iprintf(l__shell->terminal, "Can't allocate name buffer, because of %i.\n", *tls_errno); mtx_unlock(&dbg_clients_mtx); return -1; } snprintf(l__name, 11, "0x%X", l__adr); l__do_free_name = 1; } if (dbg_add_breakpoint(l__client, l__name, l__adr)) { if (l__do_free_name) mem_free(l__name); dbg_iprintf(l__shell->terminal, "Can't create break point 0x%X of client 0x%X. Look at the system terminal for further informations.\n", l__adr, l__sid); mtx_unlock(&dbg_clients_mtx); return -1; } if (l__do_free_name) mem_free(l__name); mtx_unlock(&dbg_clients_mtx); return 0; } else if (!str_compare(l__shell->pars[l__infopar +1], "del", 3)) { /* Operation del */ if (dbg_del_breakpoint(l__client, l__adr)) { dbg_iprintf(l__shell->terminal, "Can't delete break point 0x%X of client 0x%X. Look at the system terminal for further informations.\n", l__adr, l__sid); mtx_unlock(&dbg_clients_mtx); return -1; } mtx_unlock(&dbg_clients_mtx); return 0; } else if (!str_compare(l__shell->pars[l__infopar +1], "get", 3)) { dbg_breaks_t l__buf; /* Operation get */ if (dbg_get_breakpoint_data(l__client, l__adr, &l__buf)) { dbg_iprintf(l__shell->terminal, "Can't get break point 0x%X of client 0x%X. Look at the system terminal for further informations.\n", l__adr, l__sid); mtx_unlock(&dbg_clients_mtx); return -1; } dbg_iprintf(l__shell->terminal, "Breakpoint:\t0x%X\nName:\t%s\nCounter:\t%i\n\n", l__buf.address, l__buf.name, l__buf.count); mtx_unlock(&dbg_clients_mtx); return 0; } else if (!str_compare(l__shell->pars[l__infopar +1], "inc", 3)) { dbg_breaks_t l__buf; /* Operation get */ if (dbg_inc_breakpoint_ctr(l__client, l__adr, &l__buf)) { dbg_iprintf(l__shell->terminal, "Can't get break point 0x%X of client 0x%X. Look at the system terminal for further informations.\n", l__adr, l__sid); mtx_unlock(&dbg_clients_mtx); return -1; } dbg_iprintf(l__shell->terminal, "Incremented counter.\nBreakpoint:\t0x%X\nName:\t%s\nCounter:\t%i\n\n", l__buf.address, l__buf.name, l__buf.count); mtx_unlock(&dbg_clients_mtx); return 0; } else if (!str_compare(l__shell->pars[l__infopar +1], "reset", 3)) { dbg_breaks_t l__buf; /* Operation get */ if (dbg_reset_breakpoint_ctr(l__client, l__adr, &l__buf)) { dbg_iprintf(l__shell->terminal, "Can't get break point 0x%X of client 0x%X. Look at the system terminal for further informations.\n", l__adr, l__sid); mtx_unlock(&dbg_clients_mtx); return -1; } dbg_iprintf(l__shell->terminal, "Reset counter.\nBreakpoint:\t0x%X\nName:\t%s\nCounter:\t%i\n\n", l__buf.address, l__buf.name, l__buf.count); mtx_unlock(&dbg_clients_mtx); return 0; } else { dbg_iprintf(l__shell->terminal, "Invalid operation - %s.\n", l__shell->pars[l__infopar +1]); mtx_unlock(&dbg_clients_mtx); return -1; } } else { dbg_iprintf(l__shell->terminal, "Missing operation parameter. Try \"help break\" for more informations.\n"); mtx_unlock(&dbg_clients_mtx); return -1; } }