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); }
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; }
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]; }