Timeout error (#1173)
* Implement timeout state and new error for such case * Adjust test_i386_loop sample * Adjust test_i386_loop test
This commit is contained in:
parent
95890d593f
commit
3a3bc0c22d
@ -227,6 +227,7 @@ struct uc_struct {
|
||||
bool stop_request; // request to immediately stop emulation - for uc_emu_stop()
|
||||
bool quit_request; // request to quit the current TB, but continue to emulate - for uc_mem_protect()
|
||||
bool emulation_done; // emulation is done by uc_emu_start()
|
||||
bool timed_out; // emulation timed out, uc_emu_start() will result in EC_ERR_TIMEOUT
|
||||
QemuThread timer; // timer for emulation timeout
|
||||
uint64_t timeout; // timeout for uc_emu_start()
|
||||
|
||||
|
@ -163,7 +163,8 @@ typedef enum uc_err {
|
||||
UC_ERR_FETCH_UNALIGNED, // Unaligned fetch
|
||||
UC_ERR_HOOK_EXIST, // hook for this event already existed
|
||||
UC_ERR_RESOURCE, // Insufficient resource: uc_emu_start()
|
||||
UC_ERR_EXCEPTION // Unhandled CPU exception
|
||||
UC_ERR_EXCEPTION, // Unhandled CPU exception
|
||||
UC_ERR_TIMEOUT // Emulation timed out
|
||||
} uc_err;
|
||||
|
||||
|
||||
|
@ -382,8 +382,8 @@ static void test_i386_loop(void)
|
||||
// emulate machine code in 2 seconds, so we can quit even
|
||||
// if the code loops
|
||||
err = uc_emu_start(uc, ADDRESS, ADDRESS + sizeof(X86_CODE32_LOOP) - 1, 2 * UC_SECOND_SCALE, 0);
|
||||
if (err) {
|
||||
printf("Failed on uc_emu_start() with error returned %u: %s\n",
|
||||
if (err != UC_ERR_TIMEOUT) {
|
||||
printf("Failed on uc_emu_start() with error returned %u: %s, expected UC_ERR_TIMEOUT\n",
|
||||
err, uc_strerror(err));
|
||||
}
|
||||
|
||||
|
@ -379,7 +379,7 @@ static void test_i386_loop(void **state)
|
||||
// emulate machine code in 2 seconds, so we can quit even
|
||||
// if the code loops
|
||||
err = uc_emu_start(uc, address, address+sizeof(code), 2*UC_SECOND_SCALE, 0);
|
||||
uc_assert_success(err);
|
||||
uc_assert_err(err, UC_ERR_TIMEOUT);
|
||||
|
||||
// verify register values
|
||||
uc_assert_success(uc_reg_read(uc, UC_X86_REG_ECX, &r_ecx));
|
||||
|
7
uc.c
7
uc.c
@ -101,6 +101,8 @@ const char *uc_strerror(uc_err code)
|
||||
return "Insufficient resource (UC_ERR_RESOURCE)";
|
||||
case UC_ERR_EXCEPTION:
|
||||
return "Unhandled CPU exception (UC_ERR_EXCEPTION)";
|
||||
case UC_ERR_TIMEOUT:
|
||||
return "Emulation timed out (UC_ERR_TIMEOUT)";
|
||||
}
|
||||
}
|
||||
|
||||
@ -504,6 +506,7 @@ static void *_timeout_fn(void *arg)
|
||||
|
||||
// timeout before emulation is done?
|
||||
if (!uc->emulation_done) {
|
||||
uc->timed_out = true;
|
||||
// force emulation to stop
|
||||
uc_emu_stop(uc);
|
||||
}
|
||||
@ -535,6 +538,7 @@ uc_err uc_emu_start(uc_engine* uc, uint64_t begin, uint64_t until, uint64_t time
|
||||
uc->invalid_error = UC_ERR_OK;
|
||||
uc->block_full = false;
|
||||
uc->emulation_done = false;
|
||||
uc->timed_out = false;
|
||||
|
||||
switch(uc->arch) {
|
||||
default:
|
||||
@ -632,6 +636,9 @@ uc_err uc_emu_start(uc_engine* uc, uint64_t begin, uint64_t until, uint64_t time
|
||||
qemu_thread_join(&uc->timer);
|
||||
}
|
||||
|
||||
if(uc->timed_out)
|
||||
return UC_ERR_TIMEOUT;
|
||||
|
||||
return uc->invalid_error;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user