2

なぜこれが起こるのか分かりますか?メソッドは currentprocess に対して問題なく動作し、同じローカル マシンで実行されているリモート プロセスに対しては失敗し、ガベージ エラー コード 2147483661 (0x80000000D) が表示されます。これは、この特定のエラー コードに関するヒントがどこにもないためです。 . また、私は感じます。それSymInitialize自体が失敗したので、そうですSymFromAddr。私は正しいですか?

問題のプロセスは管理者として実行されており、SeDebug および SeSecurity 特権を持っています。

bool DbgHelpWrapper::MatchTargetSymbol( IntPtr processHandle, int procId, int threadId )
{
    DWORD dwStartAddress;
    DWORD dwInitializeError;
    DWORD dwThreadID = static_cast<DWORD>(threadId);
    DWORD dwProcessId = static_cast<DWORD>(procId);
    HANDLE hRemoteProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwProcessId );

    if (GetThreadStartAddress( processHandle, dwProcessId, dwThreadID, &dwStartAddress ))
    {
        dwInitializeError = ERROR_SUCCESS;
    } else {
        dwInitializeError = Marshal::GetLastWin32Error();
        System::Console::WriteLine( String::Format("GetThreadStartAddress failed: {0}", dwInitializeError ));
    }

    try
    {
        DWORD dwSymSetOptStatus = SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES);
        DWORD dwSymInitStatus = ERROR_SUCCESS;
        if (dwSymInitStatus = SymInitialize(hRemoteProcess, NULL, TRUE)) {
            dwInitializeError = ERROR_SUCCESS;
        } else {
            dwInitializeError = Marshal::GetLastWin32Error();
            System::Console::WriteLine( String::Format("SymInitialize failed: {0} error: {1}", dwSymInitStatus, dwInitializeError ));
            return false;
        }
        const int kMaxNameLength = 256;

        ULONG64 buffer[(sizeof(SYMBOL_INFO) + kMaxNameLength * sizeof(wchar_t) + sizeof(ULONG64) - 1) / sizeof(ULONG64)];
        memset(buffer, 0, sizeof(buffer));

        // Initialize symbol information retrieval structures.
        DWORD64 sym_displacement = 0;
        PSYMBOL_INFO symbol = reinterpret_cast<PSYMBOL_INFO>(&buffer[0]);
        symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
        symbol->MaxNameLen = kMaxNameLength - 1;
        if( SymFromAddr(hRemoteProcess, (DWORD64)dwStartAddress, &sym_displacement, symbol ))
        {
            System::String^ name = gcnew System::String( symbol->Name );
            System::Console::WriteLine( String::Format("Found thread with ModuleName: {0}", name ));
            if( name->Contains( this->symbolName ))
            {
                return true;
            }
        }
        else
        {
            dwInitializeError = Marshal::GetLastWin32Error();
            System::Console::WriteLine( String::Format("SymFromAddr failed: {0}", dwInitializeError ));
        }
    }
    finally
    {
        CloseHandle(hRemoteProcess);
    }
    return false;
}
4

3 に答える 3

3

おそらくこの場合ではありませんが、別の理由として、プロセスがまだ完全に開始されていないことが考えられます。私のデバッガー コードでは、WaitForDebugEvent が CREATE_PROCESS_DEBUG_EVENT イベント コードを返した直後に SymInitialize を呼び出していました。これにより、0x80000000D が得られました。少し後で(スタックウォークが必要になる直前に)呼び出すと、成功しました。

于 2015-02-16T23:59:12.497 に答える
1

プロセス ID が 64 ビット プロセスに属する SymInitialize を呼び出そうとすると、エラー 2147483661 が発生しましたが、独自のプロセスは 32 ビット プロセスです。

于 2014-09-04T04:14:38.253 に答える
1

Microsoft の結果コードは通常、16 進数で表されます。この場合、「SymInitialize エラー 8000000D」を Google で検索します。

エラーコード「8000000D」で何も手ぶらで出てきました(これを除く、しかしMSDNリンクは興味深いようです:

SymInitialize に渡されるハンドルは、プロセスによって呼び出される他のすべてのシンボル ハンドラー関数に渡される値と同じである必要があります。これは、関数が呼び出し元を識別し、正しいシンボル情報を見つけるために使用するハンドルです。<= こんなことをしているようですね...

A process that calls SymInitialize should not call it again unless it calls SymCleanup first. 
  <= What about this?

All DbgHelp functions, such as this one, are single threaded. Therefore, calls from more than one thread to this function will likely result in unexpected behavior or memory corruption. To avoid this, call SymInitialize only when your process starts and SymCleanup only when your process ends. It is not necessary for each thread in the process to call these functions.
  <= Or this

Q:複数のスレッドから SymInitialize() を呼び出していませんよね?

于 2012-09-02T19:11:22.020 に答える