Пример #1
0
int context_resume(Context * ctx, int mode, ContextAddress range_start, ContextAddress range_end) {
    switch (mode) {
    case RM_RESUME:
        return context_continue(ctx);
    case RM_STEP_INTO:
        return context_single_step(ctx);
    case RM_TERMINATE:
        sigset_set(&ctx->pending_signals, SIGKILL, 1);
        return context_continue(ctx);
    }
    errno = ERR_UNSUPPORTED;
    return -1;
}
Пример #2
0
static void command_resume(char * token, Channel * c) {
    char id[256];
    long mode;
    long count;
    Context * ctx;
    int err = 0;

    json_read_string(&c->inp, id, sizeof(id));
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    mode = json_read_long(&c->inp);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    count = json_read_long(&c->inp);
    if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    if (peek_stream(&c->inp) != MARKER_EOM) {
        json_read_struct(&c->inp, resume_params_callback, &err);
        if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX);
    }
    if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX);
    if (err == 0) {
        ctx = id2ctx(id);
        assert(safe_event_list == NULL);

        if (ctx == NULL) {
            err = ERR_INV_CONTEXT;
        }
        else if (ctx->exited) {
            err = ERR_ALREADY_EXITED;
        }
        else if (!ctx->intercepted) {
            err = ERR_ALREADY_RUNNING;
        }
        else if (ctx->regs_error) {
            err = ctx->regs_error;
        }
        else if (count != 1) {
            err = EINVAL;
        }
        else if (mode == RM_RESUME || mode == RM_STEP_INTO) {
            send_event_context_resumed(&c->bcg->out, ctx);
            if (mode == RM_STEP_INTO) {
                if (context_single_step(ctx) < 0) {
                    err = errno;
                }
                else {
                    ctx->pending_intercept = 1;
                }
            }
            else if (context_continue(ctx) < 0) {
                err = errno;
            }
        }
        else {
            err = EINVAL;
        }
    }
    send_simple_result(c, token, err);
}
Пример #3
0
int context_resume(Context * ctx, int mode, ContextAddress range_start, ContextAddress range_end) {
    switch (mode) {
    case RM_RESUME:
        return context_continue(ctx);
    case RM_STEP_INTO:
        return context_single_step(ctx);
    case RM_TERMINATE:
        return context_terminate(ctx);
    }
    errno = ERR_UNSUPPORTED;
    return -1;
}
Пример #4
0
static void event_context_stopped(Context * ctx, void * client_data) {
    TCFBroadcastGroup * bcg = client_data;

    assert(ctx->stopped);
    assert(!ctx->intercepted);
    assert(!ctx->exited);
    if (ctx->pending_safe_event) check_safe_events(ctx);
    if (ctx->pending_signals != 0) {
        send_event_context_exception(&bcg->out, ctx);
    }
    if (ctx->pending_intercept) {
        send_event_context_suspended(&bcg->out, ctx);
        flush_stream(&bcg->out);
    }
    if (!ctx->intercepted && safe_event_list == NULL) {
        context_continue(ctx);
    }
}
Пример #5
0
static void continue_temporary_stopped(void * arg) {
    LINK * qp;

    if ((uintptr_t)arg != safe_event_generation) return;
    assert(safe_event_list == NULL);

    if (channels_get_message_count(suspend_group) > 0) {
        post_event(continue_temporary_stopped, (void *)safe_event_generation);
        return;
    }

    for (qp = context_root.next; qp != &context_root; qp = qp->next) {
        Context * ctx = ctxl2ctxp(qp);
        if (ctx->exited) continue;
        if (!ctx->stopped) continue;
        if (ctx->intercepted) continue;
        context_continue(ctx);
    }
}
Пример #6
0
int context_single_step(Context * ctx) {
    assert(is_dispatch_thread());
    assert(context_has_state(ctx));
    assert(ctx->stopped);
    assert(!ctx->exited);
    assert(!EXT(ctx)->pending_step);

    if (skip_breakpoint(ctx, 1)) return 0;

    if (syscall_never_returns(ctx)) return context_continue(ctx);
    trace(LOG_CONTEXT, "context: single step ctx %#lx, id %S", ctx, ctx->id);
    if (EXT(ctx)->regs_dirty) {
        unsigned int state_count;
        if (thread_set_state(EXT(ctx)->pid, x86_THREAD_STATE32, EXT(ctx)->regs, &state_count) != KERN_SUCCESS) {
            int err = errno;
            trace(LOG_ALWAYS, "error: thread_set_state failed: ctx %#lx, id %s, error %d %s",
                ctx, ctx->id, err, errno_to_str(err));
            errno = err;
            return -1;
        }
        EXT(ctx)->regs_dirty = 0;
    }
    if (ptrace(PT_STEP, EXT(ctx)->pid, 0, 0) < 0) {
        int err = errno;
        if (err == ESRCH) {
            EXT(ctx)->pending_step = 1;
            send_context_started_event(ctx);
            return 0;
        }
        trace(LOG_ALWAYS, "error: ptrace(PT_STEP, ...) failed: ctx %#lx, id %s, error %d %s",
            ctx, ctx->id, err, errno_to_str(err));
        errno = err;
        return -1;
    }
    EXT(ctx)->pending_step = 1;
    send_context_started_event(ctx);
    return 0;
}