static void delete_channel(ChannelTCP * c) { trace(LOG_PROTOCOL, "Deleting channel %#lx", c); assert(c->lock_cnt == 0); assert(c->out_flush_cnt == 0); assert(c->magic == CHANNEL_MAGIC); assert(c->read_pending == 0); assert(c->ibuf.handling_msg != HandleMsgTriggered); channel_clear_broadcast_group(&c->chan); if (c->socket >= 0) { closesocket(c->socket); c->socket = -1; } list_remove(&c->chan.chanlink); c->magic = 0; #if ENABLE_OutputQueue output_queue_clear(&c->out_queue); #endif /* ENABLE_OutputQueue */ #if ENABLE_SSL if (c->ssl) SSL_free(c->ssl); #endif /* ENABLE_SSL */ #if ENABLE_Splice close(c->pipefd[0]); close(c->pipefd[1]); #endif /* ENABLE_Splice */ loc_free(c->ibuf.buf); loc_free(c->chan.peer_name); loc_free(c->addr_buf); loc_free(c); }
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); } }
static void process_exited(ChildProcess * prs) { send_event_process_exited(&prs->bcg->out, prs); flush_stream(&prs->bcg->out); #if defined(_WRS_KERNEL) semTake(prs_list_lock, WAIT_FOREVER); #endif list_remove(&prs->link); close(prs->inp); close(prs->out); if (prs->out != prs->err) close(prs->err); if (prs->inp_struct) { ProcessInput * inp = prs->inp_struct; if (!inp->req_posted) { virtual_stream_delete(inp->vstream); loc_free(inp); } else { inp->prs = NULL; } } if (prs->out_struct) prs->out_struct->prs = NULL; if (prs->err_struct) prs->err_struct->prs = NULL; loc_free(prs); #if defined(_WRS_KERNEL) semGive(prs_list_lock); #endif }
static void command_reset_cache_client(void * x) { CommandResetArgs * args = (CommandResetArgs *)x; Channel * c = cache_channel(); Context * ctx = id2ctx(args->id); OutputStream * out = &c->out; int err = 0; if (ctx == NULL) err = ERR_INV_CONTEXT; else if (ctx->exited) err = ERR_ALREADY_EXITED; if (!err) { Context * grp = get_reset_context(ctx); ResetInfo * rst = find_reset(grp, args->type); if (rst == NULL) err = set_errno(ERR_OTHER, "Unsupported reset type"); else if (rst->reset(ctx, &args->params) < 0) err = errno; } cache_exit(); while (args->params.list != NULL) { ResetParameter * p = args->params.list; args->params.list = p->next; loc_free(p->name); loc_free(p->value); loc_free(p); } write_stringz(out, "R"); write_stringz(out, args->token); write_errno(out, err); write_stream(out, MARKER_EOM); }
static void port_server_shutdown(PortServer * server) { PortConnection * conn; /* It seems we need to use shutdown to unblock threads blocked on recv/send */ if (server->sock != -1) { shutdown(server->sock, SHUT_RDWR); if (closesocket(server->sock) == -1) perror("closesocket"); server->sock = -1; list_remove(&server->link); /* Closing socket is enough; the various port connections * will be deleted when server deletion will be detected. In this * case this API will be called again. */ return; } for (conn = server->list; conn != NULL; ) { PortConnection * next_conn; next_conn = conn->next; port_connection_close(conn); conn = next_conn; } if (server->list != NULL) return; /* Wait for all port connections to be closed */ if (server->accept_in_progress) return; /* Wait for accept request to be aborted */ channel_unlock_with_msg(server->channel, channel_lock_svr_msg); if (server->redir_info) free_port_redirection_info(server->redir_info); loc_free(server->addr_buf); loc_free(server); }
static void delete_channel(ChannelNP * c) { trace(LOG_PROTOCOL, "Deleting channel %#lx", c); assert(c->lock_cnt == 0); assert(c->out_flush_cnt == 0); assert(c->magic == CHANNEL_MAGIC); assert(c->read_pending == 0); assert(c->ibuf.handling_msg != HandleMsgTriggered); channel_clear_broadcast_group(&c->chan); if (c->np_socket >= 0) { nopoll_conn_close(c->np_socket); c->np_socket = NULL; } list_remove(&c->chan.chanlink); if (list_is_empty(&channel_root) && list_is_empty(&channel_server_root)) shutdown_set_stopped(&channel_shutdown); c->magic = 0; #if ENABLE_OutputQueue output_queue_clear(&c->out_queue); #endif /* ENABLE_OutputQueue */ #if ENABLE_Splice close(c->pipefd[0]); close(c->pipefd[1]); #endif /* ENABLE_Splice */ output_queue_free_obuf(c->obuf); loc_free(c->ibuf.buf); loc_free(c->chan.peer_name); loc_free(c); }
static void channel_np_connect_done(void * args) { ChannelConnectInfo * info = (ChannelConnectInfo *)((AsyncReqInfo *)args)->client_data; if (info->req.error) { if (info->req.error == EPERM) { info->req.error = set_fmt_errno(ERR_OTHER, "Failed to handshake the connection h:%s p:%s", info->host, info->port); } else if (info->req.error == ECONNREFUSED) { info->req.error = set_fmt_errno(ERR_OTHER, "Failed to establish connection h:%s p:%s", info->host, info->port); } if (info->np_sock) nopoll_conn_close(info->np_sock); info->callback(info->callback_args, info->req.error, NULL); } else { ChannelNP * c = create_channel(info->np_sock, info->is_ssl, 0); if (c == NULL) { if (info->np_sock) nopoll_conn_close(info->np_sock); info->callback(info->callback_args, errno, NULL); } else { set_peer_addr(c, info->addr_buf, info->addr_len); info->callback(info->callback_args, 0, &c->chan); } } nopoll_ctx_unref(info->np_ctx); loc_free(info->host); loc_free(info->port); loc_free(info->addr_buf); loc_free(info); }
void peer_server_addprop(PeerServer * s, const char * name, const char * value) { unsigned i; assert(!s->listed); if (strcmp(name, "ID") == 0) { loc_free(name); s->id = value; return; } for (i = 0; i < s->ind; i++) { if (strcmp(s->list[i].name, name) == 0) { loc_free(name); loc_free(s->list[i].value); s->list[i].value = value; return; } } if (s->ind == s->max) { s->max *= 2; s->list = (PeerServerList *)loc_realloc(s->list, s->max * sizeof *s->list); } s->list[s->ind].name = name; s->list[s->ind].value = value; s->ind++; }
static void event_context_disposed(Context * ctx, void * args) { unsigned i; ContextExtensionDS * ext = EXT(ctx); for (i = 0; i < ext->disassemblers_cnt; i++) { loc_free(ext->disassemblers[i].isa); } loc_free(ext->disassemblers); }
static void free_port_redirection_attrs(PortAttribute * attrs) { while (attrs != NULL) { PortAttribute * attr = attrs; attrs = attr->next; loc_free(attr->name); loc_free(attr->value); loc_free(attr); } }
static void free_port_redirection_info(PortRedirectionInfo * redir) { if (!redir) return; while (redir->attrs != NULL) { PortAttribute * attr = redir->attrs; redir->attrs = attr->next; loc_free(attr->name); loc_free(attr->value); loc_free(attr); } loc_free(redir); }
static void delete_stream(void * args) { VirtualStream * stream = (VirtualStream *)args; assert(stream->magic == STREAM_MAGIC); assert(list_is_empty(&stream->clients)); assert(stream->deleted); stream->magic = 0; list_remove(&stream->link_all); loc_free(stream->buf); loc_free(stream); }
static void dispose_memory_map(MemoryMap * map) { unsigned i; for (i = 0; i < map->region_cnt; i++) { MemoryRegion * r = map->regions + i; assert(r->file == NULL); loc_free(r->file_name); } loc_free(map->regions); loc_free(map); }
void peer_server_free(PeerServer * s) { assert(!s->listed); while (s->ind > 0) { s->ind--; loc_free(s->list[s->ind].name); loc_free(s->list[s->ind].value); } loc_free(s->list); if (s->id) loc_free(s->id); loc_free(s); }
static void event_context_disposed(Context * ctx, void * args) { ContextExtensionRS * ext = EXT(ctx); unsigned i; (void)args; for (i = 0; i < ext->resets_cnt; i++) { ResetInfo * ri = ext->resets + i; loc_free(ri->type); loc_free(ri->desc); } loc_free(ext->resets); }
static void free_dwarf_cache(ELF_File * File) { DWARFCache * Cache = (DWARFCache *)File->dwarf_dt_cache; if (Cache != NULL) { unsigned i; assert(Cache->magic == SYM_CACHE_MAGIC); Cache->magic = 0; for (i = 0; i < Cache->mCompUnitsCnt; i++) { CompUnit * Unit = Cache->mCompUnits[i]; free_unit_cache(Unit); loc_free(Unit); } loc_free(Cache->mCompUnits); for (i = 0; i < Cache->mSymSectionsCnt; i++) { SymbolSection * tbl = Cache->mSymSections[i]; loc_free(tbl->mHashNext); loc_free(tbl); } while (Cache->mObjectList != NULL) { ObjectInfo * Info = Cache->mObjectList; Cache->mObjectList = Info->mListNext; loc_free(Info); } loc_free(Cache->mObjectHash); loc_free(Cache->mSymbolHash); loc_free(Cache); File->dwarf_dt_cache = NULL; } }
static void event_context_exited(Context * ctx, void * client_data) { unsigned i; SymbolCacheEntry ** symbol_cache = EXT(ctx)->symbol_cache; if (symbol_cache == NULL) return; for (i = 0; i < SYMBOL_CACHE_SIZE; i++) { while (symbol_cache[i] != NULL) { SymbolCacheEntry * entry = symbol_cache[i]; symbol_cache[i] = entry->next; release_error_report(entry->error); loc_free(entry); } } loc_free(symbol_cache); EXT(ctx)->symbol_cache = NULL; }
static void write_process_input_done(void * x) { AsyncReqInfo * req = x; ProcessInput * inp = (ProcessInput *)req->client_data; inp->req_posted = 0; if (inp->prs == NULL) { /* Process has exited */ virtual_stream_delete(inp->vstream); loc_free(inp); } else { int wr = inp->req.u.fio.rval; if (wr < 0) { int err = inp->req.error; trace(LOG_ALWAYS, "Can't write process input stream: %d %s", err, errno_to_str(err)); inp->buf_pos = inp->buf_len = 0; } else { inp->buf_pos += wr; } process_input_streams_callback(inp->vstream, 0, inp); } }
int plugins_destroy(void) { size_t i; for (i = 0; i < plugins_count; ++i) { if (dlclose(plugins_handles[i])) { trace(LOG_PLUGIN, "plugins error: \"%s\"", dlerror()); } } loc_free(plugins_handles); for (i = 0; i < function_entry_count; ++i) loc_free(function_entries[i].name); loc_free(function_entries); return 0; }
static void free_unit_cache(CompUnit * Unit) { Unit->mFilesCnt = 0; Unit->mFilesMax = 0; loc_free(Unit->mFiles); Unit->mFiles = NULL; Unit->mDirsCnt = 0; Unit->mDirsMax = 0; loc_free(Unit->mDirs); Unit->mDirs = NULL; Unit->mStatesCnt = 0; Unit->mStatesMax = 0; loc_free(Unit->mStates); Unit->mStates = NULL; }
static void np_channel_read_done(void * x) { AsyncReqInfo * req = (AsyncReqInfo *)x; ChannelNP * c = (ChannelNP *)req->client_data; ssize_t len = 0; assert(is_dispatch_thread()); assert(c->magic == CHANNEL_MAGIC); assert(c->read_pending != 0); assert(c->lock_cnt > 0); loc_free(req->u.user.data); c->read_pending = 0; /* some data is available retrieve it */ { len = c->rd_req.u.user.rval; if (req->error) { if (c->chan.state != ChannelStateDisconnected) { trace(LOG_ALWAYS, "Can't read from socket: %s", errno_to_str(req->error)); } len = 0; /* Treat error as EOF */ } } if (c->chan.state != ChannelStateDisconnected) { ibuf_read_done(&c->ibuf, len); } else if (len > 0) { np_post_read(&c->ibuf, c->ibuf.buf, c->ibuf.buf_size); } else { np_unlock(&c->chan); } }
static void event_get_context(void * arg) { GetContextArgs * s = (GetContextArgs *)arg; Channel * c = s->c; Context * ctx = s->ctx; if (!is_stream_closed(c)) { int err = 0; write_stringz(&c->out, "R"); write_stringz(&c->out, s->token); if (ctx->exited) err = ERR_ALREADY_EXITED; write_errno(&c->out, err); if (err == 0) { write_context(&c->out, ctx, s->parent != 0); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); flush_stream(&c->out); } stream_unlock(c); context_unlock(ctx); loc_free(s); }
void tmp_gc(void) { #if ENABLE_FastMemAlloc if (tmp_pool_pos + tmp_alloc_size >= tmp_pool_avr) { tmp_pool_avr = tmp_pool_pos + tmp_alloc_size; } else if (tmp_pool_avr > POOL_SIZE / 0x10) { tmp_pool_avr -= POOL_SIZE / 0x10000; } if (tmp_pool_max < tmp_pool_avr && tmp_pool_max < POOL_SIZE) { if (tmp_pool_max < POOL_SIZE / 0x10) tmp_pool_max = POOL_SIZE / 0x10; while (tmp_pool_max < tmp_pool_avr) tmp_pool_max *= 2; if (tmp_pool_max > POOL_SIZE) tmp_pool_max = POOL_SIZE; tmp_pool = (char *)loc_realloc(tmp_pool, tmp_pool_max); } else if (tmp_pool_avr < tmp_pool_max / 4 && tmp_pool_max > POOL_SIZE / 0x10) { tmp_pool_max /= 2; tmp_pool = (char *)loc_realloc(tmp_pool, tmp_pool_max); } tmp_pool_pos = sizeof(LINK); #endif while (!list_is_empty(&tmp_alloc_list)) { LINK * l = tmp_alloc_list.next; list_remove(l); loc_free(l); } tmp_alloc_size = 0; }
static void command_attach(char * token, Channel * c) { int err = 0; char id[256]; pid_t pid, parent; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); pid = id2pid(id, &parent); if (parent != 0) { err = ERR_INV_CONTEXT; } else if (context_find_from_pid(pid) != NULL) { err = ERR_ALREADY_ATTACHED; } else { AttachDoneArgs * data = loc_alloc_zero(sizeof *data); data->c = c; strcpy(data->token, token); if (context_attach(pid, attach_done, data, 0) == 0) { stream_lock(c); return; } err = errno; loc_free(data); } write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); write_stream(&c->out, MARKER_EOM); }
static void command_get_children(char * token, Channel * c) { int err = 0; char id[256]; Symbol sym; Symbol * list = NULL; int cnt = 0; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); if (id2symbol(id, &sym) < 0) err = errno; if (err == 0 && get_symbol_children(&sym, &list, &cnt) < 0) err = errno; write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, err); if (err == 0) { int i; write_stream(&c->out, '['); for (i = 0; i < cnt; i++) { if (i > 0) write_stream(&c->out, ','); json_write_string(&c->out, symbol2id(list + i)); } write_stream(&c->out, ']'); write_stream(&c->out, 0); } else { write_stringz(&c->out, "null"); } write_stream(&c->out, MARKER_EOM); loc_free(list); }
static void command_find_in_scope_cache_client(void * x) { CommandFindInScopeArgs * args = (CommandFindInScopeArgs *)x; Channel * c = cache_channel(); Context * ctx = NULL; int frame = STACK_NO_FRAME; Symbol * scope = NULL; Symbol * sym = NULL; int err = 0; if (id2frame(args->frame_id, &ctx, &frame) < 0) ctx = id2ctx(args->frame_id); if (ctx == NULL) err = set_errno(ERR_INV_CONTEXT, args->frame_id); else if (ctx->exited) err = ERR_ALREADY_EXITED; if (err == 0 && args->scope_id[0] && id2symbol(args->scope_id, &scope) < 0) err = errno; if (err == 0 && args->name == NULL) err = set_errno(EINVAL, "Symbol name must not be null"); if (err == 0 && find_symbol_in_scope(ctx, frame, args->ip, scope, args->name, &sym) < 0) err = errno; list_cnt = 0; if (err == 0) { list_add(sym); while (find_next_symbol(&sym) == 0) list_add(sym); if (get_error_code(errno) != ERR_SYM_NOT_FOUND) err = errno; } cache_exit(); write_stringz(&c->out, "R"); write_stringz(&c->out, args->token); write_errno(&c->out, err); write_symbol_list(&c->out); write_stream(&c->out, MARKER_EOM); loc_free(args->name); }
static void local_mutex_destroy (void * args) { ChannelNPMutex * mutex = (ChannelNPMutex *)args; if (args == 0) return; if (mutex->count != 0) return; pthread_mutex_destroy(&mutex->pmutex); loc_free(args); }
void cache_dispose(AbstractCache * cache) { assert(is_dispatch_thread()); assert(cache->wait_list_cnt == 0); assert(list_is_empty(&cache->link)); loc_free(cache->wait_list_buf); memset(cache, 0, sizeof(*cache)); }
static void command_disassemble(char * token, Channel * c) { int error = 0; Context * ctx = NULL; DisassembleCmdArgs * args = (DisassembleCmdArgs *)loc_alloc_zero(sizeof(DisassembleCmdArgs)); json_read_string(&c->inp, args->id, sizeof(args->id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); args->addr = (ContextAddress)json_read_uint64(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); args->size = (ContextAddress)json_read_uint64(&c->inp); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); json_read_struct(&c->inp, read_disassembly_params, args); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); ctx = id2ctx(args->id); if (ctx == NULL) error = ERR_INV_CONTEXT; else if (ctx->exited) error = ERR_ALREADY_EXITED; else if (context_get_group(ctx, CONTEXT_GROUP_PROCESS)->mem_access == 0) error = ERR_INV_CONTEXT; if (error != 0) { write_stringz(&c->out, "R"); write_stringz(&c->out, token); write_errno(&c->out, error); write_stringz(&c->out, "null"); write_stream(&c->out, MARKER_EOM); loc_free(args); } else { channel_lock(args->c = c); strlcpy(args->token, token, sizeof(args->token)); post_safe_event(ctx, safe_event_disassemble, args); } }
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); }