예제 #1
0
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);
    }
}
예제 #3
0
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;
}
예제 #4
0
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);
}
예제 #6
0
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, &reg_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;
}
예제 #9
0
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);
        }
    }
}
예제 #11
0
파일: cache.c 프로젝트: eclipse/tcf.agent
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(&current_client, 0, sizeof(current_client));
        current_cache = NULL;
        cache_miss_cnt = 0;
        def_channel = NULL;
    }
    if (args_copy != NULL) loc_free(args_copy);
}
예제 #12
0
파일: symbols.c 프로젝트: tom3333/tcf.agent
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;
}
예제 #13
0
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);
}
예제 #14
0
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, &reg_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);
}
예제 #15
0
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);
}
예제 #17
0
파일: cache.c 프로젝트: eswartz/emul
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(&current_client, 0, sizeof(current_client));
    cache_miss_cnt = 0;
    client_exited = 0;
}
예제 #18
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);
}
예제 #19
0
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--;
}
예제 #21
0
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);
}
예제 #22
0
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);
}
예제 #23
0
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, &reg_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);
}
예제 #24
0
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);
}
예제 #25
0
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;
}
예제 #26
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);
    }
}
예제 #29
0
파일: cache.c 프로젝트: tom3333/tcf.agent
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(&current_client, 0, sizeof(current_client));
    cache_miss_cnt = 0;
    client_exited = 0;
    def_channel = NULL;
}
예제 #30
0
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);
    }
}