Пример #1
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);
}
Пример #2
0
static int get_stack_frame(Context * ctx, int frame, ContextAddress ip, IMAGEHLP_STACK_FRAME * stack_frame) {
    memset(stack_frame, 0, sizeof(IMAGEHLP_STACK_FRAME));
    if (frame == STACK_NO_FRAME) {
        stack_frame->InstructionOffset = ip;
    }
    else if (ctx->parent != NULL) {
        uint64_t v = 0;
        StackFrame * frame_info;
        if (get_frame_info(ctx, frame, &frame_info) < 0) return -1;
        if (read_reg_value(frame_info, get_PC_definition(ctx), &v) < 0) return -1;
        stack_frame->InstructionOffset = v;
    }
    return 0;
}
Пример #3
0
uint64_t evaluate_stack_trace_commands(Context * ctx, StackFrame * frame, StackTracingCommandSequence * cmds) {
    static uint64_t * stk = NULL;
    static int stk_size = 0;

    int i;
    int stk_pos = 0;

    for (i = 0; i < cmds->cmds_cnt; i++) {
        StackTracingCommand * cmd = cmds->cmds + i;
        if (stk_pos >= stk_size) {
            stk_size += 4;
            stk = (uint64_t *)loc_realloc(stk, sizeof(uint64_t) * stk_size);
        }
        switch (cmd->cmd) {
        case SFT_CMD_NUMBER:
            stk[stk_pos++] = cmd->num;
            break;
        case SFT_CMD_REGISTER:
            if (read_reg_value(frame, cmd->reg, stk + stk_pos) < 0) exception(errno);
            stk_pos++;
            break;
        case SFT_CMD_FP:
            stk[stk_pos++] = frame->fp;
            break;
        case SFT_CMD_DEREF:
            if (stk_pos < 1) stack_trace_error();
            {
                size_t j;
                size_t size = cmd->size;
                uint64_t n = 0;
                uint8_t buf[8];

                if (context_read_mem(ctx, (ContextAddress)stk[stk_pos - 1], buf, size) < 0) exception(errno);
                for (j = 0; j < size; j++) {
                    n = (n << 8) | buf[cmd->big_endian ? j : size - j - 1];
                }
                stk[stk_pos - 1] = n;
            }
            break;
        case SFT_CMD_ADD:
            if (stk_pos < 2) stack_trace_error();
            stk[stk_pos - 2] = stk[stk_pos - 2] + stk[stk_pos - 1];
            stk_pos--;
            break;
        case SFT_CMD_SUB:
            if (stk_pos < 2) stack_trace_error();
            stk[stk_pos - 2] = stk[stk_pos - 2] - stk[stk_pos - 1];
            stk_pos--;
            break;
        case SFT_CMD_AND:
            if (stk_pos < 2) stack_trace_error();
            stk[stk_pos - 2] = stk[stk_pos - 2] & stk[stk_pos - 1];
            stk_pos--;
            break;
        case SFT_CMD_OR:
            if (stk_pos < 2) stack_trace_error();
            stk[stk_pos - 2] = stk[stk_pos - 2] | stk[stk_pos - 1];
            stk_pos--;
            break;
        default:
            stack_trace_error();
            break;
        }
    }
    if (stk_pos == 0) stack_trace_error();
    return stk[stk_pos - 1];
}