int context_attach(pid_t pid, ContextAttachCallBack * done, void * data, int mode) { Context * ctx = NULL; assert(done != NULL); trace(LOG_CONTEXT, "context: attaching pid %d", pid); if ((mode & CONTEXT_ATTACH_SELF) == 0 && ptrace(PT_ATTACH, pid, 0, 0) < 0) { int err = errno; trace(LOG_ALWAYS, "error: ptrace(PT_ATTACH) failed: pid %d, error %d %s", pid, err, errno_to_str(err)); errno = err; return -1; } add_waitpid_process(pid); ctx = create_context(pid2id(pid, 0)); ctx->mem = ctx; ctx->mem_access |= MEM_ACCESS_INSTRUCTION; ctx->mem_access |= MEM_ACCESS_DATA; ctx->mem_access |= MEM_ACCESS_USER; ctx->big_endian = big_endian_host(); EXT(ctx)->pid = pid; EXT(ctx)->attach_callback = done; EXT(ctx)->attach_data = data; list_add_first(&ctx->ctxl, &pending_list); /* TODO: context_attach works only for main task in a process */ return 0; }
static RegisterDefinition * alloc_reg(void) { RegisterDefinition * r = regs_index + regs_cnt++; assert(regs_cnt <= regs_max); r->dwarf_id = -1; r->eh_frame_id = -1; r->big_endian = big_endian_host(); return r; }
static void event_attach_done(void * x) { AttachDoneArgs * args = (AttachDoneArgs *)x; if (context_find_from_pid(args->pid, 0) != NULL) { args->done(ERR_ALREADY_ATTACHED, NULL, args->data); } else { Context * ctx = NULL; if (parent_ctx == NULL) { pid_t pid = taskIdSelf(); parent_ctx = create_context(pid2id(pid, 0)); EXT(parent_ctx)->pid = pid; parent_ctx->mem = parent_ctx; parent_ctx->mem_access |= MEM_ACCESS_INSTRUCTION; parent_ctx->mem_access |= MEM_ACCESS_DATA; parent_ctx->big_endian = big_endian_host(); link_context(parent_ctx); send_context_created_event(parent_ctx); } assert(parent_ctx->ref_count > 0); ctx = create_context(pid2id(args->pid, EXT(parent_ctx)->pid)); EXT(ctx)->pid = args->pid; EXT(ctx)->regs = (REG_SET *)loc_alloc(sizeof(REG_SET)); ctx->mem = parent_ctx; ctx->big_endian = parent_ctx->big_endian; (ctx->parent = parent_ctx)->ref_count++; list_add_last(&ctx->cldl, &parent_ctx->children); link_context(ctx); trace(LOG_CONTEXT, "context: attached: ctx %#lx, id %#x", ctx, EXT(ctx)->pid); send_context_created_event(ctx); args->done(0, ctx, args->data); if (taskIsStopped(args->pid)) { struct event_info * info; ctx->pending_intercept = 1; info = event_info_alloc(EVENT_HOOK_STOP); if (info != NULL) { info->stopped_ctx.ctxId = args->pid; event_info_post(info); } } } loc_free(x); }