Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
nsStackFrameWin.cpp File Reference
#include "nscore.h"
#include "windows.h"
#include "stdio.h"
#include "nsStackFrameWin.h"

Go to the source code of this file.

Defines

#define _StackWalk64   0
#define _SymFunctionTableAccess64   0
#define _SymGetModuleBase64   0
#define _SymFromAddr   0
#define _SymLoadModule64   0
#define _SymGetModuleInfo64   0
#define _EnumerateLoadedModules64   0
#define _SymGetLineFromAddr64   0

Functions

PR_END_EXTERN_C void PrintError (char *prefix, FILE *out)
PRBool EnsureImageHlpInitialized ()
static BOOL CALLBACK callbackEspecial (LPSTR aModuleName, DWORD aModuleBase, ULONG aModuleSize, PVOID aUserContext)
static BOOL CALLBACK callbackEspecial64 (PTSTR aModuleName, DWORD64 aModuleBase, ULONG aModuleSize, PVOID aUserContext)
BOOL SymGetModuleInfoEspecial (HANDLE aProcess, DWORD aAddr, PIMAGEHLP_MODULE aModuleInfo, PIMAGEHLP_LINE aLineInfo)
HANDLE GetCurrentPIDorHandle ()
PRBool EnsureSymInitialized ()
void DumpStackToFile (FILE *aStream)
 Walk the stack, translating PC's found into strings and recording the chain in aBuffer.
DWORD WINAPI DumpStackToFileThread (LPVOID lpdata)
void DumpStackToFileMain64 (struct DumpStackToFileData *data)
void DumpStackToFileMain (struct DumpStackToFileData *data)

Variables

PR_BEGIN_EXTERN_C SYMSETOPTIONSPROC _SymSetOptions
SYMINITIALIZEPROC _SymInitialize
SYMCLEANUPPROC _SymCleanup
STACKWALKPROC _StackWalk
SYMFUNCTIONTABLEACCESSPROC _SymFunctionTableAccess
SYMGETMODULEBASEPROC _SymGetModuleBase
SYMGETSYMFROMADDRPROC _SymGetSymFromAddr
SYMLOADMODULE _SymLoadModule
SYMUNDNAME _SymUnDName
SYMGETMODULEINFO _SymGetModuleInfo
ENUMLOADEDMODULES _EnumerateLoadedModules
SYMGETLINEFROMADDRPROC _SymGetLineFromAddr
HANDLE hStackWalkMutex

Define Documentation

Definition at line 110 of file nsStackFrameWin.cpp.

Definition at line 66 of file nsStackFrameWin.cpp.

Definition at line 87 of file nsStackFrameWin.cpp.

Definition at line 73 of file nsStackFrameWin.cpp.

Definition at line 117 of file nsStackFrameWin.cpp.

Definition at line 80 of file nsStackFrameWin.cpp.

Definition at line 103 of file nsStackFrameWin.cpp.

Definition at line 94 of file nsStackFrameWin.cpp.


Function Documentation

static BOOL CALLBACK callbackEspecial ( LPSTR  aModuleName,
DWORD  aModuleBase,
ULONG  aModuleSize,
PVOID  aUserContext 
) [static]

Definition at line 234 of file nsStackFrameWin.cpp.

{
    BOOL retval = TRUE;
    DWORD addr = *(DWORD*)aUserContext;

    /*
     * You'll want to control this if we are running on an
     *  architecture where the addresses go the other direction.
     * Not sure this is even a realistic consideration.
     */
    const BOOL addressIncreases = TRUE;

    /*
     * If it falls inside the known range, load the symbols.
     */
    if (addressIncreases
       ? (addr >= aModuleBase && addr <= (aModuleBase + aModuleSize))
       : (addr <= aModuleBase && addr >= (aModuleBase - aModuleSize))
        ) {
        retval = _SymLoadModule(GetCurrentProcess(), NULL, aModuleName, NULL, aModuleBase, aModuleSize);
    }

    return retval;
}

Here is the caller graph for this function:

static BOOL CALLBACK callbackEspecial64 ( PTSTR  aModuleName,
DWORD64  aModuleBase,
ULONG  aModuleSize,
PVOID  aUserContext 
) [static]

Definition at line 263 of file nsStackFrameWin.cpp.

{
#ifdef USING_WXP_VERSION
    BOOL retval = TRUE;
    DWORD64 addr = *(DWORD64*)aUserContext;

    /*
     * You'll want to control this if we are running on an
     *  architecture where the addresses go the other direction.
     * Not sure this is even a realistic consideration.
     */
    const BOOL addressIncreases = TRUE;

    /*
     * If it falls in side the known range, load the symbols.
     */
    if (addressIncreases
       ? (addr >= aModuleBase && addr <= (aModuleBase + aModuleSize))
       : (addr <= aModuleBase && addr >= (aModuleBase - aModuleSize))
        ) {
        retval = _SymLoadModule64(GetCurrentProcess(), NULL, aModuleName, NULL, aModuleBase, aModuleSize);
    }

    return retval;
#else
    return FALSE;
#endif
}
void DumpStackToFile ( FILE aStream)

Walk the stack, translating PC's found into strings and recording the chain in aBuffer.

For this to work properly, the DLLs must be rebased so that the address in the file agrees with the address in memory. Otherwise StackWalk will return FALSE when it hits a frame in a DLL whose in memory address doesn't match its in-file address.

Definition at line 439 of file nsStackFrameWin.cpp.

{
    HANDLE myProcess = ::GetCurrentProcess();
    HANDLE myThread, walkerThread;
    DWORD walkerReturn;
    struct DumpStackToFileData data;

    if (!EnsureSymInitialized())
        return;

    // Have to duplicate handle to get a real handle.
    ::DuplicateHandle(
      ::GetCurrentProcess(),
      ::GetCurrentThread(),
      ::GetCurrentProcess(),
      &myThread,
      THREAD_ALL_ACCESS, FALSE, 0
    );

    data.stream = aStream;
    data.thread = myThread;
    data.process = myProcess;
    walkerThread = ::CreateThread( NULL, 0, DumpStackToFileThread, (LPVOID) &data, 0, NULL ) ;
    if (walkerThread) {
        walkerReturn = ::WaitForSingleObject(walkerThread, 2000); // no timeout is never a good idea
        CloseHandle(myThread) ;
        if (walkerReturn != WAIT_OBJECT_0) {
            PrintError("ThreadWait", aStream);
        }
    }
    else {
        PrintError("ThreadCreate", aStream);
    }
    return;
}

Here is the call graph for this function:

void DumpStackToFileMain ( struct DumpStackToFileData *  data)

Definition at line 634 of file nsStackFrameWin.cpp.

{
    // Get the context information for the thread. That way we will
    // know where our sp, fp, pc, etc. are and can fill in the
    // STACKFRAME with the initial values.
    CONTEXT context;
    HANDLE myProcess = data->process;
    HANDLE myThread = data->thread;
    FILE* aStream = data->stream;
    DWORD addr;
    STACKFRAME frame;
    int skip = 2;  // skip our own stack walking frames
    BOOL ok;

    // Get a context for the specified thread.
    memset(&context, 0, sizeof(CONTEXT));
    context.ContextFlags = CONTEXT_FULL;
    if (!GetThreadContext(myThread, &context)) {
        PrintError("GetThreadContext", aStream);
        return;
    }

    // Setup initial stack frame to walk from
#if defined _M_IX86
    memset(&frame, 0, sizeof(frame));
    frame.AddrPC.Offset    = context.Eip;
    frame.AddrPC.Mode      = AddrModeFlat;
    frame.AddrStack.Offset = context.Esp;
    frame.AddrStack.Mode   = AddrModeFlat;
    frame.AddrFrame.Offset = context.Ebp;
    frame.AddrFrame.Mode   = AddrModeFlat;
#else
    fprintf(aStream, "Unknown platform. No stack walking.");
    return;
#endif

    // Now walk the stack and map the pc's to symbol names
    while (1) {

        ok = 0;

        // debug routines are not threadsafe, so grab the lock.
        DWORD dwWaitResult;
        dwWaitResult = WaitForSingleObject(hStackWalkMutex, INFINITE);
        if (dwWaitResult == WAIT_OBJECT_0) {

            ok = _StackWalk(
                IMAGE_FILE_MACHINE_I386,
                myProcess,
                myThread,
                &frame,
                &context,
                0,                        // read process memory routine
                _SymFunctionTableAccess,  // function table access routine
                _SymGetModuleBase,        // module base routine
                0                         // translate address routine
              );

            if (ok)
                addr = frame.AddrPC.Offset;
            else
                PrintError("WalkStack", aStream);

            if (!ok || (addr == 0)) {
                ReleaseMutex(hStackWalkMutex);  // release our lock
                break;
            }

            if (skip-- > 0) {
                ReleaseMutex(hStackWalkMutex);  // release the lock
                continue;
            }

            //
            // Attempt to load module info before we attempt to resolve the symbol.
            // This just makes sure we get good info if available.
            //

            IMAGEHLP_MODULE modInfo;
            modInfo.SizeOfStruct = sizeof(modInfo);
            BOOL modInfoRes;
            modInfoRes = SymGetModuleInfoEspecial(myProcess, addr, &modInfo, nsnull);

#ifdef USING_WXP_VERSION
            ULONG64 buffer[(sizeof(SYMBOL_INFO) +
              MAX_SYM_NAME*sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)];
            PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
            pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
            pSymbol->MaxNameLen = MAX_SYM_NAME;

            DWORD64 displacement;

            ok = _SymFromAddr && _SymFromAddr(myProcess, addr, &displacement, pSymbol);
#else
            char buf[sizeof(IMAGEHLP_SYMBOL) + 512];
            PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL) buf;
            pSymbol->SizeOfStruct = sizeof(buf);
            pSymbol->MaxNameLength = 512;

            DWORD displacement;

            ok = _SymGetSymFromAddr(myProcess,
                        frame.AddrPC.Offset,
                        &displacement,
                        pSymbol);
#endif

            // All done with debug calls so release our lock.
            ReleaseMutex(hStackWalkMutex);

            if (ok)
                fprintf(aStream, "%s!%s+0x%08X\n", modInfo.ImageName, pSymbol->Name, displacement);
            else
                fprintf(aStream, "0x%08X\n", (DWORD) addr);

            // Stop walking when we get to kernel32.dll.
            if (strcmp(modInfo.ImageName, "kernel32.dll") == 0)
                break;

        }
        else {
            PrintError("LockError", aStream);
        }
        
    }

    return;

}

Here is the call graph for this function:

Here is the caller graph for this function:

void DumpStackToFileMain64 ( struct DumpStackToFileData *  data)

Definition at line 502 of file nsStackFrameWin.cpp.

{
#ifdef USING_WXP_VERSION
    // Get the context information for the thread. That way we will
    // know where our sp, fp, pc, etc. are and can fill in the
    // STACKFRAME64 with the initial values.
    CONTEXT context;
    HANDLE myProcess = data->process;
    HANDLE myThread = data->thread;
    FILE* aStream = data->stream;
    DWORD64 addr;
    STACKFRAME64 frame64;
    int skip = 6; // skip our own stack walking frames
    BOOL ok;

    // Get a context for the specified thread.
    memset(&context, 0, sizeof(CONTEXT));
    context.ContextFlags = CONTEXT_FULL;
    if (!GetThreadContext(myThread, &context)) {
        PrintError("GetThreadContext", aStream);
        return;
    }

    // Setup initial stack frame to walk from
    memset(&frame64, 0, sizeof(frame64));
#ifdef _M_IX86
    frame64.AddrPC.Offset    = context.Eip;
    frame64.AddrStack.Offset = context.Esp;
    frame64.AddrFrame.Offset = context.Ebp;
#elif defined _M_AMD64
    frame64.AddrPC.Offset    = context.Rip;
    frame64.AddrStack.Offset = context.Rsp;
    frame64.AddrFrame.Offset = context.Rbp;
#elif defined _M_IA64
    frame64.AddrPC.Offset    = context.StIIP;
    frame64.AddrStack.Offset = context.SP;
    frame64.AddrFrame.Offset = context.RsBSP;
#else
    fprintf(aStream, "Unknown platform. No stack walking.");
    return;
#endif
    frame64.AddrPC.Mode      = AddrModeFlat;
    frame64.AddrStack.Mode   = AddrModeFlat;
    frame64.AddrFrame.Mode   = AddrModeFlat;
    frame64.AddrReturn.Mode  = AddrModeFlat;

    // Now walk the stack and map the pc's to symbol names
    while (1) {

        ok = 0;

        // stackwalk is not threadsafe, so grab the lock.
        DWORD dwWaitResult;
        dwWaitResult = WaitForSingleObject(hStackWalkMutex, INFINITE);
        if (dwWaitResult == WAIT_OBJECT_0) {

            ok = _StackWalk64(
#ifdef _M_AMD64
              IMAGE_FILE_MACHINE_AMD64,
#elif defined _M_IA64
              IMAGE_FILE_MACHINE_IA64,
#elif defined _M_IX86
              IMAGE_FILE_MACHINE_I386,
#else
              0,
#endif
              myProcess,
              myThread,
              &frame64,
              &context,
              NULL,
              _SymFunctionTableAccess64, // function table access routine
              _SymGetModuleBase64,       // module base routine
              0
            );

            if (ok)
                addr = frame64.AddrPC.Offset;
            else
                PrintError("WalkStack64", aStream);

            if (!ok || (addr == 0)) {
                ReleaseMutex(hStackWalkMutex);  // release our lock
                break;
            }

            if (skip-- > 0) {
                ReleaseMutex(hStackWalkMutex);  // release our lock
                continue;
            }

            //
            // Attempt to load module info before we attempt to reolve the symbol.
            // This just makes sure we get good info if available.
            //

            IMAGEHLP_MODULE64 modInfo;
            modInfo.SizeOfStruct = sizeof(modInfo);
            BOOL modInfoRes;
            modInfoRes = SymGetModuleInfoEspecial64(myProcess, addr, &modInfo, nsnull);

            ULONG64 buffer[(sizeof(SYMBOL_INFO) +
              MAX_SYM_NAME*sizeof(TCHAR) + sizeof(ULONG64) - 1) / sizeof(ULONG64)];
            PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
            pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
            pSymbol->MaxNameLen = MAX_SYM_NAME;

            DWORD64 displacement;
            ok = _SymFromAddr && _SymFromAddr(myProcess, addr, &displacement, pSymbol);

            // All done with debug calls so release our lock.
            ReleaseMutex(hStackWalkMutex);

            if (ok)
                fprintf(aStream, "%s!%s+0x%016X\n", modInfo.ImageName, pSymbol->Name, displacement);
            else
                fprintf(aStream, "0x%016X\n", addr);

            // Stop walking when we get to kernel32.dll.
            if (strcmp(modInfo.ImageName, "kernel32.dll") == 0)
                break;
        }
        else {
            PrintError("LockError64", aStream);
        } 
    }
    return;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

DWORD WINAPI DumpStackToFileThread ( LPVOID  lpdata)

Definition at line 476 of file nsStackFrameWin.cpp.

{
    struct DumpStackToFileData *data = (DumpStackToFileData *)lpdata;
    DWORD ret ;

    // Suspend the calling thread, dump his stack, and then resume him.
    // He's currently waiting for us to finish so now should be a good time.
    ret = ::SuspendThread( data->thread );
    if (ret == -1) {
        PrintError("ThreadSuspend", data->stream);
    }
    else {
        if (_StackWalk64)
            DumpStackToFileMain64(data);
        else
            DumpStackToFileMain(data);
        ret = ::ResumeThread(data->thread);
        if (ret == -1) {
            PrintError("ThreadResume", data->stream);
        }
    }

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 146 of file nsStackFrameWin.cpp.

{
    static PRBool gInitialized = PR_FALSE;

    if (gInitialized)
        return gInitialized;

    // Create a mutex with no initial owner.
    hStackWalkMutex = CreateMutex(
      NULL,                       // default security attributes
      FALSE,                      // initially not owned
      NULL);                      // unnamed mutex

    if (hStackWalkMutex == NULL) {
        PrintError("CreateMutex", NULL);
        return PR_FALSE;
    }

    HMODULE module = ::LoadLibrary("DBGHELP.DLL");
    if (!module) {
        module = ::LoadLibrary("IMAGEHLP.DLL");
        if (!module) return PR_FALSE;
    }

    _SymSetOptions = (SYMSETOPTIONSPROC) ::GetProcAddress(module, "SymSetOptions");
    if (!_SymSetOptions) return PR_FALSE;

    _SymInitialize = (SYMINITIALIZEPROC) ::GetProcAddress(module, "SymInitialize");
    if (!_SymInitialize) return PR_FALSE;

    _SymCleanup = (SYMCLEANUPPROC)GetProcAddress(module, "SymCleanup");
    if (!_SymCleanup) return PR_FALSE;

#ifdef USING_WXP_VERSION
    _StackWalk64 = (STACKWALKPROC64)GetProcAddress(module, "StackWalk64");
#endif
    _StackWalk = (STACKWALKPROC)GetProcAddress(module, "StackWalk");
    if (!_StackWalk64  && !_StackWalk) return PR_FALSE;

#ifdef USING_WXP_VERSION
    _SymFunctionTableAccess64 = (SYMFUNCTIONTABLEACCESSPROC64) GetProcAddress(module, "SymFunctionTableAccess64");
#endif
    _SymFunctionTableAccess = (SYMFUNCTIONTABLEACCESSPROC) GetProcAddress(module, "SymFunctionTableAccess");
    if (!_SymFunctionTableAccess64 && !_SymFunctionTableAccess) return PR_FALSE;

#ifdef USING_WXP_VERSION
    _SymGetModuleBase64 = (SYMGETMODULEBASEPROC64)GetProcAddress(module, "SymGetModuleBase64");
#endif
    _SymGetModuleBase = (SYMGETMODULEBASEPROC)GetProcAddress(module, "SymGetModuleBase");
    if (!_SymGetModuleBase64 && !_SymGetModuleBase) return PR_FALSE;

    _SymGetSymFromAddr = (SYMGETSYMFROMADDRPROC)GetProcAddress(module, "SymGetSymFromAddr");
#ifdef USING_WXP_VERSION
    _SymFromAddr = (SYMFROMADDRPROC)GetProcAddress(module, "SymFromAddr");
#endif
    if (!_SymFromAddr && !_SymGetSymFromAddr) return PR_FALSE;

#ifdef USING_WXP_VERSION
    _SymLoadModule64 = (SYMLOADMODULE64)GetProcAddress(module, "SymLoadModule64");
#endif
    _SymLoadModule = (SYMLOADMODULE)GetProcAddress(module, "SymLoadModule");
    if (!_SymLoadModule64 && !_SymLoadModule) return PR_FALSE;

    _SymUnDName = (SYMUNDNAME)GetProcAddress(module, "SymUnDName");
    if (!_SymUnDName) return PR_FALSE;

#ifdef USING_WXP_VERSION
    _SymGetModuleInfo64 = (SYMGETMODULEINFO64)GetProcAddress(module, "SymGetModuleInfo64");
#endif
    _SymGetModuleInfo = (SYMGETMODULEINFO)GetProcAddress(module, "SymGetModuleInfo");
    if (!_SymGetModuleInfo64 && !_SymGetModuleInfo) return PR_FALSE;

#ifdef USING_WXP_VERSION
    _EnumerateLoadedModules64 = (ENUMLOADEDMODULES64)GetProcAddress(module, "EnumerateLoadedModules64");
#endif
    _EnumerateLoadedModules = (ENUMLOADEDMODULES)GetProcAddress(module, "EnumerateLoadedModules");
    if (!_EnumerateLoadedModules64 && !_EnumerateLoadedModules) return PR_FALSE;

#ifdef USING_WXP_VERSION
    _SymGetLineFromAddr64 = (SYMGETLINEFROMADDRPROC64)GetProcAddress(module, "SymGetLineFromAddr64");
#endif
    _SymGetLineFromAddr = (SYMGETLINEFROMADDRPROC)GetProcAddress(module, "SymGetLineFromAddr");
    if (!_SymGetLineFromAddr64 && !_SymGetLineFromAddr) return PR_FALSE;

    return gInitialized = PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 415 of file nsStackFrameWin.cpp.

{
    PRBool retStat;

    if (!EnsureImageHlpInitialized())
        return PR_FALSE;

    _SymSetOptions(SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
    retStat = _SymInitialize(GetCurrentPIDorHandle(), NULL, TRUE);
    if (!retStat)
        PrintError("SymInitialize", NULL);
    return retStat;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 406 of file nsStackFrameWin.cpp.

{
    if (_SymGetModuleBase64)
        return GetCurrentProcess();  // winxp and friends use process handle

    return (HANDLE) GetCurrentProcessId(); // winme win98 win95 etc use process identifier
}

Here is the caller graph for this function:

PR_END_EXTERN_C void PrintError ( char *  prefix,
FILE out 
)

Definition at line 126 of file nsStackFrameWin.cpp.

{
    LPVOID lpMsgBuf;
    DWORD lastErr = GetLastError();
    FormatMessage(
      FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL,
      lastErr,
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
      (LPTSTR) &lpMsgBuf,
      0,
      NULL
    );
    fprintf(stderr, "### ERROR: %s: %s", prefix, lpMsgBuf);
    if (out)
        fprintf(out, "### ERROR: %s: %s\n", prefix, lpMsgBuf);
    LocalFree( lpMsgBuf );
}

Here is the call graph for this function:

BOOL SymGetModuleInfoEspecial ( HANDLE  aProcess,
DWORD  aAddr,
PIMAGEHLP_MODULE  aModuleInfo,
PIMAGEHLP_LINE  aLineInfo 
)

Definition at line 305 of file nsStackFrameWin.cpp.

{
    BOOL retval = FALSE;

    /*
     * Init the vars if we have em.
     */
    aModuleInfo->SizeOfStruct = sizeof(IMAGEHLP_MODULE);
    if (nsnull != aLineInfo) {
      aLineInfo->SizeOfStruct = sizeof(IMAGEHLP_LINE);
    }

    /*
     * Give it a go.
     * It may already be loaded.
     */
    retval = _SymGetModuleInfo(aProcess, aAddr, aModuleInfo);

    if (FALSE == retval) {
        BOOL enumRes = FALSE;

        /*
         * Not loaded, here's the magic.
         * Go through all the modules.
         */
        enumRes = _EnumerateLoadedModules(aProcess, callbackEspecial, (PVOID)&aAddr);
        if (FALSE != enumRes)
        {
            /*
             * One final go.
             * If it fails, then well, we have other problems.
             */
            retval = _SymGetModuleInfo(aProcess, aAddr, aModuleInfo);
        }
    }

    /*
     * If we got module info, we may attempt line info as well.
     * We will not report failure if this does not work.
     */
    if (FALSE != retval && nsnull != aLineInfo && nsnull != _SymGetLineFromAddr) {
        DWORD displacement = 0;
        BOOL lineRes = FALSE;
        lineRes = _SymGetLineFromAddr(aProcess, aAddr, &displacement, aLineInfo);
    }

    return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

ENUMLOADEDMODULES _EnumerateLoadedModules

Definition at line 106 of file nsStackFrameWin.cpp.

STACKWALKPROC _StackWalk

Definition at line 62 of file nsStackFrameWin.cpp.

SYMCLEANUPPROC _SymCleanup

Definition at line 60 of file nsStackFrameWin.cpp.

SYMFUNCTIONTABLEACCESSPROC _SymFunctionTableAccess

Definition at line 69 of file nsStackFrameWin.cpp.

SYMGETLINEFROMADDRPROC _SymGetLineFromAddr

Definition at line 113 of file nsStackFrameWin.cpp.

SYMGETMODULEBASEPROC _SymGetModuleBase

Definition at line 76 of file nsStackFrameWin.cpp.

SYMGETMODULEINFO _SymGetModuleInfo

Definition at line 99 of file nsStackFrameWin.cpp.

SYMGETSYMFROMADDRPROC _SymGetSymFromAddr

Definition at line 83 of file nsStackFrameWin.cpp.

SYMINITIALIZEPROC _SymInitialize

Definition at line 58 of file nsStackFrameWin.cpp.

SYMLOADMODULE _SymLoadModule

Definition at line 90 of file nsStackFrameWin.cpp.

PR_BEGIN_EXTERN_C SYMSETOPTIONSPROC _SymSetOptions

Definition at line 56 of file nsStackFrameWin.cpp.

SYMUNDNAME _SymUnDName

Definition at line 97 of file nsStackFrameWin.cpp.

Definition at line 120 of file nsStackFrameWin.cpp.