mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-22 15:45:29 +00:00
Timeout error (#1173)
* Implement timeout state and new error for such case * Adjust test_i386_loop sample * Adjust test_i386_loop test Backports commit 3a3bc0c22de5453335dfb597a95dbda07c9f47a2 from unicorn
This commit is contained in:
parent
2a47d652a6
commit
c206e37963
|
@ -262,6 +262,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()
|
||||
|
||||
|
|
|
@ -170,7 +170,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,9 +382,9 @@ 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",
|
||||
err, uc_strerror(err));
|
||||
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));
|
||||
}
|
||||
|
||||
// now print out some registers
|
||||
|
|
|
@ -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));
|
||||
|
|
8
uc.c
8
uc.c
|
@ -103,6 +103,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)";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -530,6 +532,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);
|
||||
}
|
||||
|
@ -561,6 +564,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:
|
||||
|
@ -663,6 +667,10 @@ 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 a new issue