2

知道为什么会这样吗?该方法对当前进程完美无缺,对于在同一台本地机器上运行的远程进程失败,我的垃圾错误代码为 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

Microsoft 结果代码通常以十六进制表示。在这种情况下,您会在 Google 上搜索“SymInitialize 错误 8000000D”:

对于错误代码“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

问:您不是从多个线程调用 SymInitialize(),是吗?

于 2012-09-02T19:11:22.020 回答
1

如果您尝试调用 SymInitialize 其中进程 id 属于 64 位进程,但您自己的进程是 32 位进程,则会收到错误 2147483661。

于 2014-09-04T04:14:38.253 回答