diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-10-27 19:42:01 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-10-27 19:42:01 +0200 |
| commit | a7c0c01bf4812402cf025a651ab30b37782431e3 (patch) | |
| tree | 19a4838571af31a48d188ba8ab6cf9cd6a3c0fc8 /src | |
| parent | d80226ec618917cfe41857a5fd24fcc7faf0c18b (diff) | |
| download | box64-a7c0c01bf4812402cf025a651ab30b37782431e3.tar.gz box64-a7c0c01bf4812402cf025a651ab30b37782431e3.zip | |
[DYNAREC] Cancel a dynablock if a segfault occurs while building it
Diffstat (limited to 'src')
| -rw-r--r-- | src/custommem.c | 4 | ||||
| -rwxr-xr-x | src/dynarec/dynablock.c | 13 | ||||
| -rwxr-xr-x | src/include/dynablock.h | 3 | ||||
| -rwxr-xr-x | src/libtools/signals.c | 2 |
4 files changed, 20 insertions, 2 deletions
diff --git a/src/custommem.c b/src/custommem.c index 92d6a4f4..171855e4 100644 --- a/src/custommem.c +++ b/src/custommem.c @@ -377,7 +377,7 @@ uintptr_t FindFreeDynarecMap(dynablock_t* db, size_t size) mmaplist[i].locked = 0; return ret; } else { - printf_log(LOG_INFO, "BOX64: Warning, sub not found, corrupted mmaplist[%d] info?\n", i); + printf_log(LOG_INFO, "BOX64: Warning, sub not found, corrupted mmaplist[%zu] info?\n", i); if(box64_log >= LOG_DEBUG) printBlock(mmaplist[i].block, mmaplist[i].first); } @@ -460,7 +460,7 @@ void ActuallyFreeDynarecMap(dynablock_t* db, uintptr_t addr, size_t size) memset(&mmaplist[i].helper[(uintptr_t)sub-(uintptr_t)mmaplist[i].block], 0, size); } if(mmaplist[i].locked) { - printf_log(LOG_INFO, "BOX64: Warning, Free a chunk in a locked mmaplist[%d]\n", i); + printf_log(LOG_INFO, "BOX64: Warning, Free a chunk in a locked mmaplist[%zu]\n", i); ++mmaplist[i].locked; } return; diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c index 5df4979d..321bd25d 100755 --- a/src/dynarec/dynablock.c +++ b/src/dynarec/dynablock.c @@ -2,6 +2,7 @@ #include <stdlib.h> #include <pthread.h> #include <errno.h> +#include <setjmp.h> #include "debug.h" #include "box64context.h" @@ -290,6 +291,14 @@ dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int* c return block; } +//TODO: move this to dynrec_arm.c and track allocated structure to avoid memory leak +static __thread struct __jmp_buf_tag dynarec_jmpbuf; + +void cancelFillBlock() +{ + longjmp(&dynarec_jmpbuf, 1); +} + /* return NULL if block is not found / cannot be created. Don't create if create==0 @@ -330,6 +339,10 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t // fill the block block->x64_addr = (void*)addr; pthread_mutex_lock(&my_context->mutex_dyndump); + if(sigsetjmp(&dynarec_jmpbuf, 1)) { + printf_log(LOG_INFO, "FillBlock at %p triggered a segfault, cancelling\n", (void*)addr); + return NULL; + } void* ret = FillBlock64(block, filladdr); pthread_mutex_unlock(&my_context->mutex_dyndump); if(!ret) { diff --git a/src/include/dynablock.h b/src/include/dynablock.h index 618a3651..d6424c4f 100755 --- a/src/include/dynablock.h +++ b/src/include/dynablock.h @@ -29,4 +29,7 @@ dynablock_t* DBAlternateBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr) // Create and Add an new dynablock in the list, handling direct/map dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int* created); +// for use in signal handler +void cancelFillBlock(); + #endif //__DYNABLOCK_H_ \ No newline at end of file diff --git a/src/libtools/signals.c b/src/libtools/signals.c index 1ac0dd4f..191267c4 100755 --- a/src/libtools/signals.c +++ b/src/libtools/signals.c @@ -736,6 +736,8 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx) int Locks = unlockMutex(); uint32_t prot = getProtection((uintptr_t)addr); #ifdef DYNAREC + if((Locks & (1<<8)) && (sig==SIGSEGV)) //1<<8 is mutex_dyndump + cancelFillBlock(); // Segfault inside a Fillblock, just cancel it's creation, don't relock mutex dynablock_t* db = NULL; int db_searched = 0; if ((sig==SIGSEGV) && (addr) && (info->si_code == SEGV_ACCERR) && (prot&PROT_DYNAREC)) { |