示例#1
0
文件: dbg_gdb.c 项目: smillaedler/rr
void dbg_reply_get_thread_list(struct dbg_context* dbg,
                               const dbg_threadid_t* threads, size_t len)
{
    assert(DREQ_GET_THREAD_LIST == dbg->req.type);

    if (0 == len) {
        write_packet(dbg, "l");
    } else {
        size_t maxlen =	1/*m char*/ +
                        (2 * sizeof(pid_t) + 1/*,*/) * len +
                        1/*\0*/;
        char* str = sys_malloc(maxlen);
        int i, offset = 0;

        str[offset++] = 'm';
        for (i = 0; i < len; ++i) {
            offset += snprintf(&str[offset], maxlen - offset,
                               "%02x,", threads[i]);
        }
        /* Overwrite the trailing ',' */
        str[offset - 1] = '\0';

        write_packet(dbg, str);
        sys_free((void**)&str);
    }

    consume_request(dbg);
}
示例#2
0
文件: dbg_gdb.c 项目: smillaedler/rr
void dbg_reply_get_is_thread_alive(struct dbg_context* dbg, int alive)
{
    assert(DREQ_GET_IS_THREAD_ALIVE == dbg->req.type);

    write_packet(dbg, alive ? "OK" : "E01");

    consume_request(dbg);
}
示例#3
0
文件: dbg_gdb.c 项目: smillaedler/rr
void dbg_reply_watchpoint_request(struct dbg_context* dbg, int code)
{
    assert(DREQ_WATCH_FIRST <= dbg->req.type
           && dbg->req.type <= DREQ_WATCH_LAST);

    write_packet(dbg, code ? "" : "OK");

    consume_request(dbg);
}
示例#4
0
文件: dbg_gdb.c 项目: smillaedler/rr
void dbg_reply_get_stop_reason(struct dbg_context* dbg,
                               dbg_threadid_t which, int sig)
{
    assert(DREQ_GET_STOP_REASON == dbg->req.type);

    send_stop_reply_packet(dbg, which, sig);

    consume_request(dbg);
}
示例#5
0
文件: dbg_gdb.c 项目: smillaedler/rr
void dbg_reply_get_offsets(struct dbg_context* dbg/*, TODO */)
{
    assert(DREQ_GET_OFFSETS == dbg->req.type);

    /* XXX FIXME TODO */
    write_packet(dbg, "");

    consume_request(dbg);
}
示例#6
0
文件: dbg_gdb.c 项目: smillaedler/rr
void dbg_notify_stop(struct dbg_context* dbg, dbg_threadid_t thread, int sig)
{
    assert(dbg_is_resume_request(&dbg->req)
           || dbg->req.type == DREQ_INTERRUPT);

    send_stop_reply_packet(dbg, thread, sig);

    consume_request(dbg);
}
示例#7
0
文件: dbg_gdb.c 项目: smillaedler/rr
void dbg_reply_get_current_thread(struct dbg_context* dbg,
                                  dbg_threadid_t thread)
{
    assert(DREQ_GET_CURRENT_THREAD == dbg->req.type);

    /* TODO multiprocess */
    write_hex_packet(dbg, thread);

    consume_request(dbg);
}
示例#8
0
文件: dbg_gdb.c 项目: smillaedler/rr
void dbg_reply_get_reg(struct dbg_context* dbg, dbg_regvalue_t value)
{
    char buf[32];

    assert(DREQ_GET_REG == dbg->req.type);

    print_reg(value, buf);
    write_packet(dbg, buf);

    consume_request(dbg);
}
示例#9
0
文件: dbg_gdb.c 项目: smillaedler/rr
void dbg_notify_exit_signal(struct dbg_context* dbg, int sig)
{
    char buf[64];

    assert(dbg_is_resume_request(&dbg->req)
           || dbg->req.type == DREQ_INTERRUPT);

    snprintf(buf, sizeof(buf) - 1, "X%02x", sig);
    write_packet(dbg, buf);

    consume_request(dbg);
}
示例#10
0
文件: dbg_gdb.c 项目: smillaedler/rr
void dbg_reply_get_regs(struct dbg_context* dbg,
                        const struct dbg_regfile* file)
{
    /* XXX this will be wrong on x64 WINNT */
    char buf[1 + DREG_NUM_LINUX_I386 * 2 * sizeof(long)];
    int i;

    assert(DREQ_GET_REGS == dbg->req.type);

    for (i = 0; i < DREG_NUM_LINUX_I386; ++i) {
        print_reg(file->regs[i], &buf[i * 2 * sizeof(long)]);
    }
    write_packet(dbg, buf);

    consume_request(dbg);
}
示例#11
0
文件: dbg_gdb.c 项目: smillaedler/rr
void dbg_reply_get_mem(struct dbg_context* dbg, const byte* mem, size_t len)
{
    char* buf;

    assert(DREQ_GET_MEM == dbg->req.type);
    assert(len <= dbg->req.mem.len);

    if (len > 0) {
        size_t i;

        buf = sys_malloc(2 * len + 1);
        for (i = 0; i < len; ++i) {
            unsigned long b = mem[i];
            snprintf(&buf[2 * i], 3, "%02lx", b);
        }
        write_packet(dbg, buf);
        sys_free((void**)&buf);
    } else {
        write_packet(dbg, "");
    }

    consume_request(dbg);
}
示例#12
0
文件: dbg_gdb.c 项目: smillaedler/rr
static int process_packet(struct dbg_context* dbg)
{
    char request;
    char* payload = NULL;
    int ret;

    assert(INTERRUPT_CHAR == dbg->inbuf[0] ||
           ('$' == dbg->inbuf[0]
            && (((byte*)memchr(dbg->inbuf, '#', dbg->inlen) - dbg->inbuf)
                == dbg->packetend)));

    if (INTERRUPT_CHAR == dbg->inbuf[0]) {
        request = INTERRUPT_CHAR;
    } else {
        request = dbg->inbuf[1];
        payload = (char*)&dbg->inbuf[2];
        dbg->inbuf[dbg->packetend] = '\0';
    }

    debug("raw request %c(%s)", request, payload);

    switch(request) {
    case INTERRUPT_CHAR:
        debug("gdb requests interrupt");
        dbg->req.type = DREQ_INTERRUPT;
        ret = 1;
        break;
    case 'D':
        log_info("gdb is detaching from us, exiting");
        write_packet(dbg, "OK");
        exit(0);
    case 'g':
        dbg->req.type = DREQ_GET_REGS;
        dbg->req.target = dbg->query_thread;
        debug("gdb requests registers");
        ret = 1;
        break;
    case 'G':
        /* XXX we can't let gdb spray registers in general,
         * because it may cause replay to diverge.  But some
         * writes may be OK.  Let's see how far we can get
         * with ignoring these requests. */
        write_packet(dbg, "");
        ret = 0;
        break;
    case 'H':
        ret = set_selected_thread(dbg, payload);
        break;
    case 'k':
        log_info("gdb requests kill, exiting");
        write_packet(dbg, "OK");
        exit(0);
    case 'm':
        dbg->req.type = DREQ_GET_MEM;
        dbg->req.target = dbg->query_thread;
        dbg->req.mem.addr = (void*)strtoul(payload, &payload, 16);
        ++payload;
        dbg->req.mem.len = strtoul(payload, &payload, 16);
        assert('\0' == *payload);

        debug("gdb requests memory (addr=0x%p, len=%u)",
              dbg->req.mem.addr, dbg->req.mem.len);

        ret = 1;
        break;
    case 'M':
        /* We can't allow the debugger to write arbitrary data
         * to memory, or the replay may diverge. */
        write_packet(dbg, "");
        ret = 0;
        break;
    case 'p':
        dbg->req.type = DREQ_GET_REG;
        dbg->req.target = dbg->query_thread;
        dbg->req.reg = strtoul(payload, &payload, 16);
        assert('\0' == *payload);
        debug("gdb requests register value (%d)", dbg->req.reg);
        ret = 1;
        break;
    case 'P':
        /* XXX we can't let gdb spray registers in general,
         * because it may cause replay to diverge.  But some
         * writes may be OK.  Let's see how far we can get
         * with ignoring these requests. */
        write_packet(dbg, "");
        ret = 0;
        break;
    case 'q':
        ret = query(dbg, payload);
        break;
    case 'Q':
        ret = set(dbg, payload);
        break;
    case 'T':
        dbg->req.type = DREQ_GET_IS_THREAD_ALIVE;
        dbg->req.target = parse_threadid(payload, &payload);
        assert('\0' == *payload);
        debug("gdb wants to know if %d is alive", dbg->req.target);
        ret = 1;
        break;
    case 'v':
        ret = process_vpacket(dbg, payload);
        break;
    case 'X':
        /* We can't allow the debugger to write arbitrary data
         * to memory, or the replay may diverge. */
        write_packet(dbg, "");
        ret = 0;
        break;
    case 'z':
    case 'Z': {
        int type = strtol(payload, &payload, 16);
        assert(',' == *payload++);
        if (!(0 <= type && type <= 4)) {
            log_warn("Unknown watch type %d", type);
            write_packet(dbg, "");
            ret = 0;
            break;
        }
        dbg->req.type =	type + (request == 'Z' ?
                                DREQ_SET_SW_BREAK :
                                DREQ_REMOVE_SW_BREAK);
        dbg->req.mem.addr = (void*)strtoul(payload, &payload, 16);
        assert(',' == *payload++);
        dbg->req.mem.len = strtoul(payload, &payload, 16);
        assert('\0' == *payload);

        debug("gdb requests %s breakpoint (addr=%p, len=%u)",
              'Z' == request ? "set" : "remove",
              dbg->req.mem.addr, dbg->req.mem.len);

        ret = 1;
        break;
    }
    case '?':
        debug("gdb requests stop reason");
        dbg->req.type = DREQ_GET_STOP_REASON;
        dbg->req.target = dbg->query_thread;
        ret = 1;
        break;
    default:
        log_warn("Unhandled gdb request '%c'", dbg->inbuf[1]);
        /* Play dumb and hope gdb doesn't /really/ need this
         * request ... */
        write_packet(dbg, "");
        ret = 0;
    }
    /* Erase the newly processed packet from the input buffer. */
    memmove(dbg->inbuf, dbg->inbuf + dbg->packetend,
            dbg->inlen - dbg->packetend);
    dbg->inlen = (dbg->inlen - dbg->packetend);

    /* If we processed the request internally, consume it. */
    if (ret == 0) {
        consume_request(dbg);
    }
    return ret;
}
示例#13
0
static void fifo_server(FILE *fifo_stream)
{
	char buf[MAX_FIFO_COMMAND];
	int line_len;
	char *file_sep, *command, *file;
	struct fifo_command *f;

	file_sep=command=file=0;

	while(1) {

		/* commands must look this way ':<command>:[filename]' */
		if (!read_line(buf, MAX_FIFO_COMMAND, fifo_stream, &line_len)) {
			/* line breaking must have failed -- consume the rest
			   and proceed to a new request
			*/
			LOG(L_ERR, "ERROR: fifo_server: command expected\n");
			goto consume;
		}
		if (line_len==0) {
			LOG(L_DBG, "INFO: fifo_server: command empty\n");
			continue;
		}
		if (line_len<3) {
			LOG(L_ERR, "ERROR: fifo_server: command must have at least 3 chars\n");
			goto consume;
		}
		if (*buf!=CMD_SEPARATOR) {
			LOG(L_ERR, "ERROR: fifo_server: command must begin with %c: %.*s\n", 
				CMD_SEPARATOR, line_len, buf );
			goto consume;
		}
		command=buf+1;
		file_sep=strchr(command, CMD_SEPARATOR );
		if (file_sep==NULL) {
			LOG(L_ERR, "ERROR: fifo_server: file separator missing\n");
			goto consume;
		}
		if (file_sep==command) {
			LOG(L_ERR, "ERROR: fifo_server: empty command\n");
			goto consume;
		}
		if (*(file_sep+1)==0) file=NULL; 
		else {
			file=file_sep+1;
			file=trim_filename(file);
			if (file==0) {
				LOG(L_ERR, "ERROR: fifo_server: trimming filename\n");
				goto consume;
			}
		}
		/* make command zero-terminated */
		*file_sep=0;

		f=lookup_fifo_cmd( command );
		if (f==0) {
			LOG(L_ERR, "ERROR: fifo_server: command %s is not available\n",
				command);
			fifo_reply(file, "500 command '%s' not available\n", command);
			goto consume;
		}
		if (f->f(fifo_stream, file)<0) {
			LOG(L_ERR, "ERROR: fifo_server: command (%s) "
				"processing failed\n", command );
			goto consume;
		}

consume:
		if (file) { pkg_free(file); file=0;}
		consume_request(fifo_stream);
	}
}