pid_t handle_events_until_dump_trap(pid_t wait_for) { while (true) { event_t e = wait_event(wait_for); if (e.signo == SIGTRAP) { if (is_dump_sigtrap(e.tid)) { clear_trap(e.tid); return e.tid; } else if (is_hook_sigtrap(e.tid)) { assert(tracer_state == TRACER_LOCKED || tracer_state == TRACER_FIRSTTOUCH); clear_trap(e.tid); tracer_lock_range(e.tid); continue; } else { // If we arrive here, it is a syscall handle_syscall(e.tid); ptrace_syscall(e.tid); continue; } } else if (e.signo == SIGSEGV) { void *addr = round_to_page(e.sigaddr); switch (tracer_state) { case TRACER_UNLOCKED: /* We should never get a sigsegv in unlocked state ! */ errx(EXIT_FAILURE, "SIGSEGV at %p before locking memory during capture\n", e.sigaddr); case TRACER_FIRSTTOUCH: firsttouch_handler(e.tid, addr); break; case TRACER_LOCKED: mru_handler(e.tid, addr); break; case TRACER_DUMPING: dump_handler(e.tid, addr); break; default: assert(false); /* we should never be here */ } ptrace_syscall(e.tid); } else if (e.signo == SIGSTOP) { /* A new thread is starting, ignore this event, next wait_event call will unblock the thread once its parents registers it in tids array */ } else if (e.signo == SIGWINCH) { /* Ignore signal SIGWINCH, tty resize */ ptrace_syscall(e.tid); continue; } else { errx(EXIT_FAILURE, "Unexpected signal in wait_sigtrap: %d\n", e.signo); } } debug_print("%s", "\n"); }
static void handle_channel_msg(void * x) { Trap trap; ChannelNP * c = (ChannelNP *)x; int has_msg; assert(is_dispatch_thread()); assert(c->magic == CHANNEL_MAGIC); assert(c->ibuf.handling_msg == HandleMsgTriggered); assert(c->ibuf.message_count); has_msg = ibuf_start_message(&c->ibuf); if (has_msg <= 0) { if (has_msg < 0 && c->chan.state != ChannelStateDisconnected) { trace(LOG_PROTOCOL, "Socket is shutdown by remote peer, channel %#lx %s", c, c->chan.peer_name); channel_close(&c->chan); } } else if (set_trap(&trap)) { if (c->chan.receive) { c->chan.receive(&c->chan); } else { handle_protocol_message(&c->chan); assert(c->out_bin_block == NULL); } clear_trap(&trap); } else { trace(LOG_ALWAYS, "Exception in message handler: %s", errno_to_str(trap.error)); send_eof_and_close(&c->chan, trap.error); } }
DWARFCache * get_dwarf_cache(ELF_File * File) { DWARFCache * Cache = (DWARFCache *)File->dwarf_dt_cache; if (Cache == NULL) { Trap trap; if (!sCloseListenerOK) { elf_add_close_listener(free_dwarf_cache); sCloseListenerOK = 1; } sCache = Cache = (DWARFCache *)(File->dwarf_dt_cache = loc_alloc_zero(sizeof(DWARFCache))); sCache->magic = SYM_CACHE_MAGIC; sCache->mFile = File; sCache->mObjectHash = loc_alloc_zero(sizeof(ObjectInfo *) * OBJ_HASH_SIZE); if (set_trap(&trap)) { dio_LoadAbbrevTable(File); load_symbol_tables(); load_debug_sections(); clear_trap(&trap); } else { sCache->mErrorCode = trap.error; strncpy(sCache->mErrorMsg, trap.msg, sizeof(sCache->mErrorMsg) - 1); } sCache = NULL; } if (Cache->mErrorCode) str_exception(Cache->mErrorCode, Cache->mErrorMsg); return Cache; }
int ini_server(const char * url, Protocol * p, TCFBroadcastGroup * b) { ChannelServer * serv = NULL; PeerServer * ps = NULL; Trap trap; if (!set_trap(&trap)) { bcg = NULL; proto = NULL; if (ps != NULL) peer_server_free(ps); errno = trap.error; return -1; } bcg = b; proto = p; ps = channel_peer_from_url(url); if (ps == NULL) str_exception(ERR_OTHER, "Invalid server URL"); peer_server_addprop(ps, loc_strdup("Name"), loc_strdup(PROXY_NAME)); peer_server_addprop(ps, loc_strdup("Proxy"), loc_strdup("")); SERVER_ADDPROP_HOOK; serv = channel_server(ps); if (serv == NULL) exception(errno); serv->new_conn = channel_new_connection; clear_trap(&trap); add_channel_redirection_listener(channel_redirection_listener); return 0; }
static void subscribe_cb(Channel * c, void * x, int error) { Trap trap; PortConnection * conn = (PortConnection *)x; PortAttribute * attr = conn->server->redir_info->attrs; OutputStream * out = &conn->server->channel->out; if (set_trap(&trap)) { if (!error) { error = read_errno(&c->inp); json_test_char(&c->inp, MARKER_EOM); } clear_trap(&trap); } else { error = trap.error; } /* Ignore error for subscribe since we may already have subscribed for this channel */ conn->pending = protocol_send_command(conn->server->channel, "PortForward", "create", portcreate_cb, conn); write_stream(out, '{'); json_write_string(out, "ID"); write_stream(out, ':'); json_write_string(out, conn->id); write_stream(out, ','); while (attr != NULL) { json_write_string(out, attr->name); write_stream(out, ':'); write_string(out, attr->value); attr = attr->next; } write_stream(out, '}'); write_stream(out, MARKER_EOA); write_stream(out, MARKER_EOM); }
static void command_get_context_cache_client(void * x) { GetContextArgs * args = (GetContextArgs *)x; Channel * c = cache_channel(); Context * ctx = NULL; int frame = STACK_NO_FRAME; RegisterDefinition * reg_def = NULL; Trap trap; if (set_trap(&trap)) { if (id2register(args->id, &ctx, &frame, ®_def) < 0) exception(errno); clear_trap(&trap); } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); if (reg_def != NULL) { write_context(&c->out, args->id, ctx, frame, reg_def); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); }
static void delete_config_done(Channel *c, void *client_data, int error) { PortConnection * conn = (PortConnection *) client_data; Trap trap; if (set_trap(&trap)) { if (!error) { error = read_errno(&c->inp); json_test_char(&c->inp, MARKER_EOM); } clear_trap(&trap); } else { error = trap.error; } if (!conn->auto_connect_stream) { protocol_send_command(conn->server->channel, "Streams", "disconnect", disconnect_stream_done, conn); json_write_string(&conn->server->channel->out, conn->out_stream_id); write_stream(&conn->server->channel->out, MARKER_EOA); write_stream(&conn->server->channel->out, MARKER_EOM); } else { loc_free(conn->out_stream_id); conn->out_stream_id = NULL; loc_free(conn->in_stream_id); conn->in_stream_id = NULL; port_unlock(conn); port_connection_close(conn); } }
void virtual_stream_create(const char * type, const char * context_id, size_t buf_len, unsigned access, VirtualStreamCallBack * callback, void * callback_args, VirtualStream ** res) { LINK * l; VirtualStream * stream = loc_alloc_zero(sizeof(VirtualStream)); buf_len++; list_init(&stream->clients); strncpy(stream->type, type, sizeof(stream->type) - 1); stream->magic = STREAM_MAGIC; stream->id = id_cnt++; stream->access = access; stream->callback = callback; stream->callback_args = callback_args; stream->ref_cnt = 1; stream->buf = loc_alloc(buf_len); stream->buf_len = buf_len; for (l = subscriptions.next; l != &subscriptions; l = l->next) { Subscription * h = all2subscription(l); if (strcmp(type, h->type) == 0) { Trap trap; create_client(stream, h->channel); if (set_trap(&trap)) { send_event_stream_created(&h->channel->out, stream, context_id); clear_trap(&trap); } else { trace(LOG_ALWAYS, "Exception sending stream created event: %d %s", trap.error, errno_to_str(trap.error)); } } } list_add_first(&stream->link_all, &streams); *res = stream; }
static void load_debug_sections(void) { Trap trap; unsigned idx; ELF_File * File = sCache->mFile; memset(&trap, 0, sizeof(trap)); sSymbolTableLen = sCache->mSymbolTableLen; sObjectList = NULL; sObjectListTail = NULL; sCompUnitsMax = 0; for (idx = 1; idx < File->section_cnt; idx++) { ELF_Section * sec = File->sections + idx; if (sec->size == 0) continue; if (sec->name == NULL) continue; if (strcmp(sec->name, ".debug") == 0 || strcmp(sec->name, ".debug_info") == 0) { sDebugSection = sec; sParentObject = NULL; sPrevSibling = NULL; dio_EnterDebugSection(NULL, sec, 0); if (set_trap(&trap)) { while (dio_GetPos() < sec->size) { dio_ReadUnit(&sUnitDesc, entry_callback); sCompUnit->mDesc = sUnitDesc; } clear_trap(&trap); } dio_ExitSection(); sParentObject = NULL; sPrevSibling = NULL; sCompUnit = NULL; sDebugSection = NULL; if (trap.error) break; } else if (strcmp(sec->name, ".debug_ranges") == 0) { sCache->mDebugRanges = sec; } else if (strcmp(sec->name, ".debug_aranges") == 0) { sCache->mDebugARanges = sec; } else if (strcmp(sec->name, ".debug_line") == 0) { sCache->mDebugLine = sec; } else if (strcmp(sec->name, ".debug_loc") == 0) { sCache->mDebugLoc = sec; } } if (sObjectList == NULL) { loc_free(sCache->mObjectHash); sCache->mObjectHash = NULL; } sCache->mObjectList = sObjectList; sSymbolTableLen = 0; sObjectList = NULL; sObjectListTail = NULL; sCompUnitsMax = 0; if (trap.error) str_exception(trap.error, trap.msg); }
static void getcapabilities_cb(Channel * c, void * x, int error) { Trap trap; PortConnection * conn = (PortConnection *)x; PortAttribute * attr = conn->server->redir_info->attrs; OutputStream * out = &conn->server->channel->out; if (set_trap(&trap)) { if (!error) { error = read_errno(&c->inp); json_read_struct(&c->inp, read_getcapabilities_struct, (void *)conn); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); } clear_trap(&trap); } else { error = trap.error; } if (error) { connect_port_callback(conn, error); } else { if (conn->auto_connect_stream) { conn->pending = protocol_send_command(conn->server->channel, "PortForward", "create", portcreate_cb, conn); write_stream(out, '{'); json_write_string(out, "ID"); write_stream(out, ':'); json_write_string(out, conn->id); while (attr != NULL) { write_stream(out, ','); if (strcmp(attr->name, "RemotePort") == 0) { json_write_string(out, "Port"); } else { json_write_string(out, attr->name); } write_stream(out, ':'); write_string(out, attr->value); attr = attr->next; } if (conn->auto_connect_stream) { write_stream(out, ','); json_write_string(out, "AutoConnect"); write_stream(out, ':'); json_write_boolean(out, 1); } write_stream(out, '}'); write_stream(out, MARKER_EOA); write_stream(out, MARKER_EOM); } else { conn->pending = protocol_send_command(conn->server->channel, "Streams", "subscribe", subscribe_cb, conn); json_write_string(out, "PortForward"); write_stream(out, MARKER_EOA); write_stream(out, MARKER_EOM); } } }
static void run_cache_client(int retry) { Trap trap; unsigned i; unsigned id = current_client.id; void * args_copy = NULL; assert(id != 0); current_cache = NULL; cache_miss_cnt = 0; def_channel = NULL; if (current_client.args_copy) args_copy = current_client.args; for (i = 0; i < listeners_cnt; i++) listeners[i](retry ? CTLE_RETRY : CTLE_START); if (set_trap(&trap)) { current_client.client(current_client.args); clear_trap(&trap); assert(current_client.id == 0); assert(cache_miss_cnt == 0); } else if (id != current_client.id) { trace(LOG_ALWAYS, "Unhandled exception in data cache client: %s", errno_to_str(trap.error)); assert(current_client.id == 0); assert(cache_miss_cnt == 0); } else { if (get_error_code(trap.error) != ERR_CACHE_MISS || cache_miss_cnt == 0 || current_cache == NULL) { trace(LOG_ALWAYS, "Unhandled exception in data cache client: %s", errno_to_str(trap.error)); for (i = 0; i < listeners_cnt; i++) listeners[i](CTLE_COMMIT); } else { AbstractCache * cache = current_cache; if (cache->wait_list_cnt >= cache->wait_list_max) { cache->wait_list_max += 8; cache->wait_list_buf = (WaitingCacheClient *)loc_realloc(cache->wait_list_buf, cache->wait_list_max * sizeof(WaitingCacheClient)); } if (current_client.args != NULL && !current_client.args_copy) { void * mem = loc_alloc(current_client.args_size); memcpy(mem, current_client.args, current_client.args_size); current_client.args = mem; current_client.args_copy = 1; } if (cache->wait_list_cnt == 0) list_add_last(&cache->link, &cache_list); if (current_client.channel != NULL) channel_lock_with_msg(current_client.channel, channel_lock_msg); cache->wait_list_buf[cache->wait_list_cnt++] = current_client; for (i = 0; i < listeners_cnt; i++) listeners[i](CTLE_ABORT); args_copy = NULL; } memset(¤t_client, 0, sizeof(current_client)); current_cache = NULL; cache_miss_cnt = 0; def_channel = NULL; } if (args_copy != NULL) loc_free(args_copy); }
static LocationExpressionState * evaluate_location(Context * ctx, int frame, LocationInfo * loc_info) { Trap trap; StackFrame * frame_info = NULL; LocationExpressionState * state = NULL; static uint64_t args[] = { 0, 0 }; if (frame != STACK_NO_FRAME && get_frame_info(ctx, frame, &frame_info) < 0) return NULL; if (!set_trap(&trap)) return NULL; state = evaluate_location_expression(ctx, frame_info, loc_info->value_cmds.cmds, loc_info->value_cmds.cnt, args, loc_info->args_cnt); clear_trap(&trap); return state; }
static void command_get_children_cache_client(void * x) { GetChildrenArgs * args = (GetChildrenArgs *)x; Channel * c = cache_channel(); Context * ctx = NULL; int frame = STACK_NO_FRAME; StackFrame * frame_info = NULL; RegisterDefinition * defs = NULL; RegisterDefinition * parent = NULL; Trap trap; if (set_trap(&trap)) { if (id2register(args->id, &ctx, &frame, &parent) == 0) { if (frame != STACK_TOP_FRAME && get_frame_info(ctx, frame, &frame_info) < 0) exception(errno); } else if (id2frame(args->id, &ctx, &frame) == 0) { if (get_frame_info(ctx, frame, &frame_info) < 0) exception(errno); } else { ctx = id2ctx(args->id); frame = STACK_TOP_FRAME; } if (ctx != NULL) defs = get_reg_definitions(ctx); clear_trap(&trap); } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); write_stream(&c->out, '['); if (defs != NULL) { int cnt = 0; RegisterDefinition * reg_def; for (reg_def = defs; reg_def->name != NULL; reg_def++) { if (reg_def->parent != parent) continue; if (frame < 0 || frame_info->is_top_frame || reg_def->size == 0 || read_reg_value(frame_info, reg_def, NULL) == 0) { if (cnt > 0) write_stream(&c->out, ','); json_write_string(&c->out, register2id(ctx, frame, reg_def)); cnt++; } } } write_stream(&c->out, ']'); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); }
static void command_get_cache_client(void * x) { GetArgs * args = (GetArgs *)x; Channel * c = cache_channel(); Trap trap; bbf_pos = 0; if (set_trap(&trap)) { int frame = 0; Context * ctx = NULL; RegisterDefinition * reg_def = NULL; if (id2register(args->id, &ctx, &frame, ®_def) < 0) exception(errno); if (ctx->exited) exception(ERR_ALREADY_EXITED); if ((ctx->reg_access & REG_ACCESS_RD_STOP) != 0) { check_all_stopped(ctx); } if ((ctx->reg_access & REG_ACCESS_RD_RUNNING) == 0) { if (!ctx->stopped && context_has_state(ctx)) str_exception(ERR_IS_RUNNING, "Cannot read register if not stopped"); } if (reg_def->size > bbf_len) { bbf_len += 0x100 + reg_def->size; bbf = (uint8_t *)loc_realloc(bbf, bbf_len); } bbf_pos = reg_def->size; memset(bbf, 0, reg_def->size); if (frame < 0 || is_top_frame(ctx, frame)) { if (context_read_reg(ctx, reg_def, 0, reg_def->size, bbf) < 0) exception(errno); } else { StackFrame * info = NULL; if (get_frame_info(ctx, frame, &info) < 0) exception(errno); if (read_reg_bytes(info, reg_def, 0, reg_def->size, bbf) < 0) exception(errno); } clear_trap(&trap); } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); json_write_binary(&c->out, bbf, bbf_pos); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); }
static void terminal_exited(void * args) { Terminal * term = (Terminal *)args; Trap trap; if (set_trap(&trap)) { send_event_terminal_exited(&term->bcg->out, term); clear_trap(&trap); } else { trace(LOG_ALWAYS, "Exception sending terminal exited event: %d %s", trap.error, errno_to_str(trap.error)); } list_remove(&term->link); channel_unlock_with_msg(term->channel, TERMINALS); loc_free(term); }
static void getconfig_cb(Channel * c, void * x, int error) { Trap trap; PortConnection * conn = (PortConnection *)x; if (set_trap(&trap)) { if (!error) { error = read_errno(&c->inp); json_read_struct(&c->inp, read_getconfig_struct, (void *)conn); json_test_char(&c->inp, MARKER_EOA); json_test_char(&c->inp, MARKER_EOM); } clear_trap(&trap); } else { error = trap.error; } connect_port_callback(conn, error); }
static void run_cache_client(void) { Trap trap; cache_miss_cnt = 0; client_exited = 0; if (set_trap(&trap)) { current_client.client(current_client.args); clear_trap(&trap); assert(cache_miss_cnt == 0); assert(client_exited); } else if (get_error_code(trap.error) != ERR_CACHE_MISS || client_exited || cache_miss_cnt == 0) { trace(LOG_ALWAYS, "Unhandled exception in data cache client: %d %s", trap.error, errno_to_str(trap.error)); } if (cache_miss_cnt == 0 && current_client.args_copy) loc_free(current_client.args); memset(¤t_client, 0, sizeof(current_client)); cache_miss_cnt = 0; client_exited = 0; }
static void delete_write_request(WriteRequest * r, int error) { Channel * c = r->client->channel; Trap trap; if (set_trap(&trap)) { write_stringz(&c->out, "R"); write_stringz(&c->out, r->token); write_errno(&c->out, error); write_stream(&c->out, MARKER_EOM); clear_trap(&trap); } else { trace(LOG_ALWAYS, "Exception handling pending stream write command: %d %s", trap.error, errno_to_str(trap.error)); } list_remove(&r->link_client); loc_free(r->data); loc_free(r); }
static void append_format_parameter(char * type, char * style, char * param) { /* Note: 'param' is UTF-8 encoded JSON text */ char str[64]; if (param != NULL && (*param == '"' || strcmp(type, "number") == 0)) { Trap trap; ByteArrayInputStream buf; InputStream * inp = create_byte_array_input_stream(&buf, param, strlen(param)); if (set_trap(&trap)) { if (*param == '"') { char * x = json_read_alloc_string(inp); if (x != NULL) { char * s = x; while (*s) { realloc_msg_buf(); msg_buf[msg_buf_len++] = *s++; } loc_free(x); } param = NULL; } else { double x = json_read_double(inp); if (strcmp(style, "percent") == 0) { snprintf(str, sizeof(str), "%ld%%", (long)(x * 100)); } else if (strcmp(style, "integer") == 0) { snprintf(str, sizeof(str), "%ld", (long)x); } else { snprintf(str, sizeof(str), "%g", x); } param = str; } clear_trap(&trap); } } if (param != NULL) { while (*param) { realloc_msg_buf(); msg_buf[msg_buf_len++] = *param++; } } }
static void write_stream_done(Channel *c, void *client_data, int error) { Trap trap; PortConnection * conn = (PortConnection *) client_data;; if (set_trap(&trap)) { if (!error) { error = read_errno(&c->inp); json_test_char(&c->inp, MARKER_EOM); } clear_trap(&trap); } else { error = trap.error; } assert (conn->pending_write_request <= MAX_STREAM_WRITE && conn->pending_write_request > 0); if (conn->pending_write_request == MAX_STREAM_WRITE) { send_packet_callback(conn, error); } conn->pending_write_request--; }
static void command_setm_cache_client(void * x) { SetmArgs * args = (SetmArgs *)x; Channel * c = cache_channel(); int notify = 0; Trap trap; if (set_trap(&trap)) { unsigned locs_pos = 0; unsigned data_pos = 0; check_location_list(args->locs, args->locs_cnt, 1); while (locs_pos < args->locs_cnt) { Location * l = args->locs + locs_pos++; assert(l->frame_info == NULL); if (l->size > 0) { if (context_write_reg(l->ctx, l->reg_def, l->offs, l->size, args->data + data_pos) < 0) exception(errno); data_pos += l->size; l->notify = 1; notify = 1; } } clear_trap(&trap); } cache_exit(); if (notify) { unsigned locs_pos = 0; while (locs_pos < args->locs_cnt) { Location * l = args->locs + locs_pos++; if (l->notify) send_event_register_changed(l->id); } } write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); write_stream(&c->out, MARKER_EOM); loc_free(args->locs); loc_free(args->data); }
static void delete_config_done(Channel *c, void *client_data, int error) { PortConnection * conn = (PortConnection *) client_data; Trap trap; if (set_trap(&trap)) { if (!error) { error = read_errno(&c->inp); json_test_char(&c->inp, MARKER_EOM); } clear_trap(&trap); } else { error = trap.error; } loc_free(conn->out_stream_id); conn->out_stream_id = NULL; loc_free(conn->in_stream_id); conn->in_stream_id = NULL; port_unlock(conn); port_connection_close(conn); }
static void command_set_cache_client(void * x) { SetArgs * args = (SetArgs *)x; Channel * c = cache_channel(); int notify = 0; Trap trap; if (set_trap(&trap)) { int frame = 0; Context * ctx = NULL; RegisterDefinition * reg_def = NULL; if (id2register(args->id, &ctx, &frame, ®_def) < 0) exception(errno); if (frame >= 0 && !is_top_frame(ctx, frame)) exception(ERR_INV_CONTEXT); if (ctx->exited) exception(ERR_ALREADY_EXITED); if ((ctx->reg_access & REG_ACCESS_WR_STOP) != 0) { check_all_stopped(ctx); } if ((ctx->reg_access & REG_ACCESS_WR_RUNNING) == 0) { if (!ctx->stopped && context_has_state(ctx)) str_exception(ERR_IS_RUNNING, "Cannot write register if not stopped"); } if ((size_t)args->data_len > reg_def->size) exception(ERR_INV_DATA_SIZE); if (args->data_len > 0) { if (context_write_reg(ctx, reg_def, 0, args->data_len, args->data) < 0) exception(errno); notify = 1; } clear_trap(&trap); } cache_exit(); if (notify) send_event_register_changed(args->id); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); write_stream(&c->out, MARKER_EOM); loc_free(args->data); }
static void command_getm_cache_client(void * x) { GetmArgs * args = (GetmArgs *)x; Channel * c = cache_channel(); Trap trap; bbf_pos = 0; if (bbf == NULL) bbf = (uint8_t *)loc_alloc(bbf_len = 0x100); if (set_trap(&trap)) { unsigned locs_pos = 0; check_location_list(args->locs, args->locs_cnt, 0); while (locs_pos < args->locs_cnt) { Location * l = args->locs + locs_pos++; if (bbf_pos + l->size > bbf_len) { bbf_len += 0x100 + l->size; bbf = (uint8_t *)loc_realloc(bbf, bbf_len); } memset(bbf + bbf_pos, 0, l->size); if (l->frame_info == NULL) { if (context_read_reg(l->ctx, l->reg_def, l->offs, l->size, bbf + bbf_pos) < 0) exception(errno); } else { if (read_reg_bytes(l->frame_info, l->reg_def, l->offs, l->size, bbf + bbf_pos) < 0) exception(errno); } bbf_pos += l->size; } clear_trap(&trap); } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, trap.error); json_write_binary(&c->out, bbf, bbf_pos); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); loc_free(args->locs); }
static ContextAddress get_module_id(Context * ctx, ELF_File * module) { ELF_File * exe_file = NULL; ContextAddress addr = elf_get_debug_structure_address(ctx, &exe_file); size_t word_size = exe_file && exe_file->elf64 ? 8 : 4; Trap trap; if (addr == 0 || exe_file == NULL) str_exception(ERR_OTHER, "Cannot find loader debug data"); if (set_trap(&trap)) { ContextAddress r_map = 0; ContextAddress r_brk = 0; ContextAddress mod_id = 0; if (elf_read_memory_word(ctx, exe_file, addr + word_size * 1, &r_map) < 0) exception(errno); if (elf_read_memory_word(ctx, exe_file, addr + word_size * 2, &r_brk) < 0) exception(errno); if (r_map != 0 && r_brk != 0) mod_id = find_module(ctx, exe_file, module, r_map, r_brk); clear_trap(&trap); if (mod_id) return mod_id; } else { str_exception(trap.error, "Cannot access target ELF loader data"); } str_exception(ERR_OTHER, "Cannot get TLS module ID"); return 0; }
static void delete_read_request(ReadRequest * r) { Channel * c = r->client->channel; Trap trap; if (set_trap(&trap)) { write_stringz(&c->out, "R"); write_stringz(&c->out, r->token); write_stringz(&c->out, "null"); write_errno(&c->out, ERR_COMMAND_CANCELLED); json_write_long(&c->out, 0); write_stream(&c->out, 0); json_write_boolean(&c->out, 1); write_stream(&c->out, 0); write_stream(&c->out, MARKER_EOM); clear_trap(&trap); } else { trace(LOG_ALWAYS, "Exception handling pending stream read command: %d %s", trap.error, errno_to_str(trap.error)); } list_remove(&r->link_client); loc_free(r); }
static void delete_client(StreamClient * client) { VirtualStream * stream = client->stream; Trap trap; LINK * n; assert(stream->ref_cnt > 0); if (set_trap(&trap)) { send_event_stream_disposed(&client->channel->out, stream); clear_trap(&trap); } else { trace(LOG_ALWAYS, "Exception sending stream deleted event: %d %s", trap.error, errno_to_str(trap.error)); } list_remove(&client->link_hash); list_remove(&client->link_stream); list_remove(&client->link_all); for (n = client->read_requests.next; n != &client->read_requests;) { ReadRequest * r = client2read_request(n); n = n->next; delete_read_request(r); } for (n = client->write_requests.next; n != &client->write_requests;) { WriteRequest * r = client2write_request(n); n = n->next; delete_write_request(r, ERR_COMMAND_CANCELLED); } loc_free(client); if (--stream->ref_cnt == 0) { assert(list_is_empty(&stream->clients)); assert(stream->deleted); post_event(delete_stream, stream); } else if (stream->access & VS_ENABLE_REMOTE_READ) { advance_stream_buffer(stream); } }
static void portcreate_cb(Channel * c, void * x, int error) { Trap trap; PortConnection * conn = (PortConnection *)x; if (set_trap(&trap)) { if (!error) { error = read_errno(&c->inp); json_test_char(&c->inp, MARKER_EOM); } clear_trap(&trap); } else { error = trap.error; } if (error) { connect_port_callback(conn, error); } else { conn->pending = protocol_send_command(conn->server->channel, "PortForward", "getConfig", getconfig_cb, conn); json_write_string(&conn->server->channel->out, conn->id); write_stream(&conn->server->channel->out, MARKER_EOA); write_stream(&conn->server->channel->out, MARKER_EOM); } }
static void run_cache_client(int retry) { Trap trap; unsigned i; cache_miss_cnt = 0; client_exited = 0; def_channel = NULL; for (i = 0; i < listeners_cnt; i++) listeners[i](retry ? CTLE_RETRY : CTLE_START); if (set_trap(&trap)) { current_client.client(current_client.args); clear_trap(&trap); assert(cache_miss_cnt == 0); assert(client_exited); } else if (get_error_code(trap.error) != ERR_CACHE_MISS || client_exited || cache_miss_cnt == 0) { trace(LOG_ALWAYS, "Unhandled exception in data cache client: %d %s", trap.error, errno_to_str(trap.error)); } for (i = 0; i < listeners_cnt; i++) listeners[i](client_exited ? CTLE_COMMIT : CTLE_ABORT); if (cache_miss_cnt == 0 && current_client.args_copy) loc_free(current_client.args); memset(¤t_client, 0, sizeof(current_client)); cache_miss_cnt = 0; client_exited = 0; def_channel = NULL; }
void load_line_numbers(DWARFCache * Cache, CompUnit * Unit) { Trap trap; if (Unit->mFiles != NULL && Unit->mDirs != NULL) return; if (elf_load(Cache->mDebugLine)) exception(errno); dio_EnterDataSection(&Unit->mDesc, Cache->mDebugLine->data, Unit->mLineInfoOffs, Cache->mDebugLine->size); if (set_trap(&trap)) { U8_T header_pos = 0; U1_T opcode_base = 0; U1_T opcode_size[256]; U8_T header_size = 0; U1_T min_instruction_length = 0; U1_T is_stmt_default = 0; I1_T line_base = 0; U1_T line_range = 0; U8_T unit_size = 0; int dwarf64 = 0; LineNumbersState state; /* Read header */ unit_size = dio_ReadU4(); if (unit_size == 0xffffffffu) { unit_size = dio_ReadU8(); unit_size += 12; dwarf64 = 1; } else { unit_size += 4; } dio_ReadU2(); /* line info version */ header_size = dwarf64 ? dio_ReadU8() : (U8_T)dio_ReadU4(); header_pos = dio_GetPos(); min_instruction_length = dio_ReadU1(); is_stmt_default = dio_ReadU1() != 0; line_base = (I1_T)dio_ReadU1(); line_range = dio_ReadU1(); opcode_base = dio_ReadU1(); memset(opcode_size, 0, sizeof(opcode_size)); dio_Read(opcode_size + 1, opcode_base - 1); /* Read directory names */ for (;;) { char * Name = dio_ReadString(); if (Name == NULL) break; add_dir(Unit, Name); } /* Read source sFileLocks info */ for (;;) { U4_T dir = 0; FileInfo File; memset(&File, 0, sizeof(File)); File.mName = dio_ReadString(); if (File.mName == NULL) break; dir = dio_ReadULEB128(); if (dir > 0 && dir <= Unit->mDirsCnt) File.mDir = Unit->mDirs[dir - 1]; File.mModTime = dio_ReadULEB128(); File.mSize = dio_ReadULEB128(); add_file(Unit, &File); } /* Run the program */ if (header_pos + header_size != dio_GetPos()) str_exception(ERR_INV_DWARF, "Invalid line info header"); memset(&state, 0, sizeof(state)); state.mFile = 1; state.mLine = 1; if (is_stmt_default) state.mFlags |= LINE_IsStmt; while (dio_GetPos() < Unit->mLineInfoOffs + unit_size) { U1_T opcode = dio_ReadU1(); if (opcode >= opcode_base) { state.mLine += (unsigned)((int)((opcode - opcode_base) % line_range) + line_base); state.mAddress += (opcode - opcode_base) / line_range * min_instruction_length; add_state(Unit, &state); state.mFlags &= ~(LINE_BasicBlock | LINE_PrologueEnd | LINE_EpilogueBegin); } else if (opcode == 0) { U4_T op_size = dio_ReadULEB128(); U8_T op_pos = dio_GetPos(); switch (dio_ReadU1()) { case DW_LNE_define_file: { U4_T dir = 0; FileInfo File; memset(&File, 0, sizeof(File)); File.mName = dio_ReadString(); dir = dio_ReadULEB128(); if (dir > 0 && dir <= Unit->mDirsCnt) File.mDir = Unit->mDirs[dir - 1]; File.mModTime = dio_ReadULEB128(); File.mSize = dio_ReadULEB128(); add_file(Unit, &File); break; } case DW_LNE_end_sequence: state.mFlags |= LINE_EndSequence; add_state(Unit, &state); memset(&state, 0, sizeof(state)); state.mFile = 1; state.mLine = 1; if (is_stmt_default) state.mFlags |= LINE_IsStmt; else state.mFlags &= ~LINE_IsStmt; break; case DW_LNE_set_address: state.mAddress = (ContextAddress)dio_ReadAddress(); break; default: dio_Skip(op_size - 1); break; } if (dio_GetPos() != op_pos + op_size) str_exception(ERR_INV_DWARF, "Invalid line info op size"); } else { switch (opcode) { case DW_LNS_copy: add_state(Unit, &state); state.mFlags &= ~(LINE_BasicBlock | LINE_PrologueEnd | LINE_EpilogueBegin); break; case DW_LNS_advance_pc: state.mAddress += (ContextAddress)(dio_ReadU8LEB128() * min_instruction_length); break; case DW_LNS_advance_line: state.mLine += dio_ReadSLEB128(); break; case DW_LNS_set_file: state.mFile = dio_ReadULEB128(); break; case DW_LNS_set_column: state.mColumn = dio_ReadULEB128(); break; case DW_LNS_negate_stmt: state.mFlags ^= LINE_IsStmt; break; case DW_LNS_set_basic_block: state.mFlags |= LINE_BasicBlock; break; case DW_LNS_const_add_pc: state.mAddress += (255 - opcode_base) / line_range * min_instruction_length; break; case DW_LNS_fixed_advance_pc: state.mAddress += dio_ReadU2(); break; case DW_LNS_set_prologue_end: state.mFlags |= LINE_PrologueEnd; break; case DW_LNS_set_epilogue_begin: state.mFlags |= LINE_EpilogueBegin; break; case DW_LNS_set_isa: state.mISA = (U1_T)dio_ReadULEB128(); break; default: str_exception(ERR_INV_DWARF, "Invalid line info op code"); break; } } } dio_ExitSection(); clear_trap(&trap); } else { dio_ExitSection(); free_unit_cache(Unit); str_exception(trap.error, trap.msg); } }