[DYNAREC] Cancel a dynablock if a segfault occurs while building it

This commit is contained in:
ptitSeb 2021-10-27 19:42:01 +02:00
parent d80226ec61
commit a7c0c01bf4
4 changed files with 20 additions and 2 deletions

View File

@ -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;

View File

@ -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) {

View File

@ -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_

View File

@ -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)) {