未处理的exception0xC0000008:在动态重新编译器中指定了无效的句柄

代码是MIPS-> ARM动态重新编译器。 在运行recompile_function()多次之后,它会在下面代码的条件子句中崩溃,尽管在早期的函数运行期间它可以运行这行代码而没有任何问题。

void recompile_function(){ //recompilation code ...... if (out > (u_char *)((u_char *)base_addr + (1 << TARGET_SIZE_2) - MAX_OUTPUT_BLOCK_SIZE - JUMP_TABLE_SIZE)) out = (u_char *)base_addr; // other code ...... } 

变量输出是用于编写重新编译代码的指针。 base_addr始终指向已分配内存空间的原始开始。 每次写入指令时,变量输出进行4个字节,而base_addr保持不变。

 extern char extra_memory[33554432]; #define BASE_ADDR ((int)(&extra_memory)) void *base_addr; u_char *out; void new_dynarec_init() { protect_readwrite(); base_addr = ((int)(&extra_memory)); out = (u_char *)base_addr; } 

错误是“frontend.exe中0x7738EC9F(ntdll.dll)上的未处理exception:0xC0000008:指定了无效句柄。”

这是关于断层子句指令的反汇编代码。

 #if NEW_DYNAREC == NEW_DYNAREC_ARM __clear_cache((void *)beginning, out); 53830242 ldr r1,[r9] 53830246 add r3,r4,r5,lsl #2 5383024A mov r0,r7 5383024C str r3,[r2] 5383024E blx __clear_cache_bugfix (537D19DCh) //cacheflush((void *)beginning,out,0); #endif // If we're within 256K of the end of the buffer, // start over from the beginning. (Is 256K enough?) if (out > (u_char *)((u_char *)base_addr + (1 << TARGET_SIZE_2) - MAX_OUTPUT_BLOCK_SIZE - JUMP_TABLE_SIZE)) 53830252 mov r2,#0xAA98 53830256 movt r2,#0x5462 5383025A ldr r3,new_recompile_block+0A1E8h (53830550h) 5383025C ldr r4,[r2] 5383025E ldr r2,[r9] 53830262 add r3,r3,r4 53830264 cmp r2,r3 53830266 bls new_recompile_block+9F06h (5383026Eh) out = (u_char *)base_addr; 53830268 mov r2,r4 5383026A str r4,[r9] 

这是调试器提示我的那一行。 我检查了反汇编窗口,它也指向这一行。 更重要的是,如果我选择继续,将弹出一个新错误,程序将在函数__report_gsfailure中的代码行“__fastfail”崩溃。 新错误是frontend.exe中的0x53831547(mupen64plus.dll)处的未处理exception:堆栈cookie检测代码检测到基于堆栈的缓冲区溢出“。 0x53831546是代码行“__fastfail”的地址。

 #pragma warning(push) #pragma warning(disable: 4100) // unreferenced formal parameter __declspec(noreturn) void __cdecl __report_gsfailure(GSFAILURE_PARAMETER) { 5383153C push {r0,r1} 5383153E push {r11,lr} 53831542 mov r11,sp __fastfail(FAST_FAIL_STACK_COOKIE_CHECK_FAILURE); 53831544 movs r0,#2 53831546 __fastfail } // Declare stub for rangecheckfailure, since these occur often enough that the // code bloat of setting up the parameters hurts performance __declspec(noreturn) void __cdecl __report_rangecheckfailure() { 53831548 push {r11,lr} 5383154C mov r11,sp __report_securityfailure(FAST_FAIL_RANGE_CHECK_FAILURE); 5383154E movs r0,#8 53831550 bl __report_securityfailure (53831558h) 53831554 __debugbreak 

寄存器PC = 53831546,因此执行点是__fastfail。

该错误是由位于崩溃条件子句上方的__clear_cache引起的。 禁用该函数调用修复了崩溃。