2016-04-16 78 views
0

コードはMIPS-> ARM動的再コンパイラです。 recompile_function()を何度も実行した後は、以下のコードのcondition節でクラッシュしますが、以前の関数の実行中に問題なくこのコード行を実行できます。未処理の例外0xC0000008:動的再コンパイラで無効なハンドルが指定されました

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 
    ...... 
} 

変数outは、再コンパイルされたコードを書き込むためのポインタです。 base_addrは常に割り当てられたメモリ空間の元の開始点を指します。変数outは、命令が書き込まれるたびに4バイトずつ進みますが、base_addrは変更されません。 ":0xC0000008:無効なハンドルが指定されましたfrontend.exeで0x7738EC9F(ntdll.dllの)で未処理の例外。"

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

エラーがあります

これはfaulting句命令の回りの逆アセンブル・コードです。

#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)で未処理の例外:スタッククッキーインストルメンテーションコードがスタックベースのバッファオーバーランを検出しました"です。 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です。

+2

無効なハンドル例外が発生する可能性は低いです(ハンドルをまったく処理しません)。クラッシュの場所が間違っているか、デバッガからのエラーかコールスタックを調べて、実行がntdllでどのように終わったかを確認します。 – Jester

+0

@Jesterデバッガからのメッセージが表示されます。この線も指している逆アセンブル・ウィンドウを確認しました。さらに、続行を選択すると、新しいエラーがポップアップし、関数__report_gsfailureのコード行 "__fastfail"でプログラムがクラッシュします。新しいエラーは、 "frontend.exeの0x53831547(mupen64plus.dll)で未処理の例外:スタッククッキーインストルメンテーションコードがスタックベースのバッファオーバーランを検出しました"です。 0x53831546は、コード行 "__fastfail"のアドレスです。 –

+0

障害のある命令についての逆アセンブリで質問を更新する必要があります。また、 'base_addr'と' out'がどのように定義されているかを示してください。 – Jester

答えて

0

エラーは、クラッシュした条件節の上にある__clear_cacheによって発生します。その関数呼び出しを無効にすると、クラッシュが修正されました。

関連する問題