2

Any idea why this happens? The method works flawlessly for the currentprocess and fails for remote process running on the same local machine with a garbage error code 2147483661 (0x80000000D) for me, since there is no hint at all anywhere about this particular error code, or am i missing something?. Also, I feel; since SymInitialize itself failed, and so is SymFromAddr. Am I correct?

The process in question is running as admin and does have the SeDebug and SeSecurity Privileges.

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;
}
Jimson James
  • 2,937
  • 6
  • 43
  • 78
  • 1
    My crystal ball says you are running this on a 64-bit operating system and the remote process is a 64-bit process but you compiled your code to x86. – Hans Passant Sep 02 '12 at 19:10
  • Great, Does your crystal ball mention anything about things that happens behind the scene then? Because, even though the problem rectified by targeting a 32 bit process, but I do not find a way to make work `SymFromAddr` and I'm really suspicious about the x64 OS vs x86 process targeting another x86 process. – Jimson James Sep 02 '12 at 19:36
  • Well, If we compile the code to Win32 and target a x86 process, there no problem. But when I compiled it to x64 even the NtQueryInformation returned error! – Jimson James Sep 02 '12 at 21:23
  • 1
    This is just not the proper way to document a question. My guess was right, you should have used that to improve your question so somebody can post a correct answer. – Hans Passant Sep 02 '12 at 21:41

3 Answers3

3

Another reason, although probably not, in this case, might be that the process is not fully started yet. In my debugger code, I was calling SymInitialize immediately after WaitForDebugEvent returned a CREATE_PROCESS_DEBUG_EVENT event code. This gave 0x80000000D. Calling it a bit later (right before I needed a stack-walk) succeeded.

halfer
  • 19,824
  • 17
  • 99
  • 186
Rob
  • 3,315
  • 1
  • 24
  • 35
1

Microsoft result codes are usually expressed in hex. In this case, you'd Google for "SymInitialize error 8000000D":

I came up empty-handed for anything on error code "8000000D" (except for this, but the MSDN link sounds interesting:

The handle passed to SymInitialize must be the same value passed to all other symbol handler functions called by the process. It is the handle that the functions use to identify the caller and locate the correct symbol information. <= It sounds like you're doing this...

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: You are not calling SymInitialize() from multiple threads, are you?

paulsm4
  • 114,292
  • 17
  • 138
  • 190
1

You would get error 2147483661 if you try to invoke SymInitialize where target process ID belongs to a 64-bit process, but your own process is a 32-bit process.

halfer
  • 19,824
  • 17
  • 99
  • 186
Ricky Lung
  • 680
  • 7
  • 12