//-------------------------------------------------------------------------- gdecode_t rpc_debmod_t::dbg_get_debug_event(debug_event_t *event, int timeout_ms) { if ( has_pending_event ) { verbev(("get_debug_event => has pending event, returning it\n")); *event = pending_event; has_pending_event = false; poll_debug_events = false; return GDE_ONE_EVENT; } gdecode_t result = GDE_NO_EVENT; if ( poll_debug_events ) { // do we have something waiting? // we must use TIMEOUT here to avoid competition between // IDA analyzer and the debugger program. // The analysis will be slow during the application run. // As soon as the program is suspended, the analysis will be fast // because get_debug_event() will not be called. if ( irs_ready(irs, TIMEOUT) != 0 ) { verbev(("get_debug_event => remote has an event for us\n")); // get the packet - it should be RPC_EVENT (nothing else can be) qstring empty; int flags = timeout_ms > 0 ? SET_PRF_TIMEOUT(timeout_ms) | PRF_POLL : PRF_DONT_POLL; rpc_packet_t *rp = process_request(empty, flags); verbev(("get_debug_event => processed remote event, has=%d\n", has_pending_event)); if ( rp != NULL || !has_pending_event ) { warning("rpc: event protocol error (rp=%p has_event=%d)", rp, has_pending_event); return GDE_ERROR; } } } else { verbev(("get_debug_event => first time, send GET_DEBUG_EVENT\n")); qstring cmd = prepare_rpc_packet(RPC_GET_DEBUG_EVENT); append_long(cmd, timeout_ms); rpc_packet_t *rp = process_request(cmd); if ( rp == NULL ) return GDE_ERROR; const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; result = gdecode_t(extract_long(&answer, end)); if ( result >= GDE_ONE_EVENT ) extract_debug_event(&answer, end, event); else poll_debug_events = true; verbev(("get_debug_event => remote said %d, poll=%d now\n", result, poll_debug_events)); qfree(rp); } return result; }
//------------------------------------------------------------------------- ssize_t irs_recv(idarpc_stream_t *irs, void *buf, size_t n, int timeout) { if ( timeout != -1 && !irs_ready(irs, timeout) ) { SET_SYSTEM_SPECIFIC_ERRNO(SYSTEM_SPECIFIC_TIMEOUT_ERROR); return -1; // no data } return qrecv(sock_from_irs(irs), buf, (int)n); }
//-------------------------------------------------------------------------- gdecode_t idaapi rpc_debmod_t::dbg_get_debug_event(debug_event_t *event, int timeout_ms) { if ( has_pending_event ) { verbev(("get_debug_event => has pending event, returning it\n")); *event = pending_event; has_pending_event = false; poll_debug_events = false; return GDE_ONE_EVENT; } gdecode_t result = GDE_NO_EVENT; if ( poll_debug_events ) { // do we have something waiting? if ( irs_ready(irs, timeout_ms) != 0 ) { verbev(("get_debug_event => remote has an event for us\n")); // get the packet - it should be RPC_EVENT (nothing else can be) bytevec_t empty; rpc_packet_t *rp = process_request(empty); verbev(("get_debug_event => processed remote event, has=%d\n", has_pending_event)); if ( rp != NULL || !has_pending_event ) { warning("rpc: event protocol error (rp=%p has_event=%d)", rp, has_pending_event); return GDE_ERROR; } } } else { verbev(("get_debug_event => first time, send GET_DEBUG_EVENT\n")); bytevec_t req = prepare_rpc_packet(RPC_GET_DEBUG_EVENT); append_dd(req, timeout_ms); rpc_packet_t *rp = process_request(req); if ( rp == NULL ) return GDE_ERROR; const uchar *answer = (uchar *)(rp+1); const uchar *end = answer + rp->length; result = gdecode_t(extract_long(&answer, end)); if ( result >= GDE_ONE_EVENT ) extract_debug_event(&answer, end, event); else poll_debug_events = true; verbev(("get_debug_event => remote said %d, poll=%d now\n", result, poll_debug_events)); qfree(rp); } return result; }