2010-10-02 4 views
4

Кто-нибудь знает, как лучше или быстрее получить стек вызовов, чем «StackWalk»? Я также думаю, что stackwalk также может быть медленнее на методах с большим количеством переменных ... (Интересно, что делают коммерческие профилировщики?) Я использую C++ для окон. :) спасибо :)быстрее, чем Stackwalk

+1

Valgrind? http://stackoverflow.com/questions/413477/is-there-a-good-valgrind-substitute-for-windows – t0mm13b

+0

hmmm ... не valgrind только для unix? – Idov

+0

и valgrind - это инструмент, я ищу лучший способ пробовать стек ... – Idov

ответ

0

Я не знаю, если это быстрее, и он не покажет вам никаких символов, и я уверен, что вы можете сделать лучше, чем это, но это какой-то код, который я написал некоторое время назад, когда мне нужна эта информация (работает только для Windows):

struct CallStackItem 
{ 
    void* pc; 
    CallStackItem* next; 

    CallStackItem() 
    { 
     pc = NULL; 
     next = NULL; 
    } 
}; 

typedef void* CallStackHandle; 

CallStackHandle CreateCurrentCallStack(int nLevels) 
{ 
    void** ppCurrent = NULL; 

    // Get the current saved stack pointer (saved by the compiler on the function prefix). 
    __asm { mov ppCurrent, ebp }; 

    // Don't limit if nLevels is not positive 
    if (nLevels <= 0) 
     nLevels = 1000000; 

    // ebp points to the old call stack, where the first two items look like this: 
    // ebp -> [0] Previous ebp 
    //  [1] previous program counter 
    CallStackItem* pResult = new CallStackItem; 
    CallStackItem* pCurItem = pResult; 
    int nCurLevel = 0; 

    // We need to read two pointers from the stack 
    int nRequiredMemorySize = sizeof(void*) * 2; 
    while (nCurLevel < nLevels && ppCurrent && !IsBadReadPtr(ppCurrent, nRequiredMemorySize)) 
    { 
     // Keep the previous program counter (where the function will return to) 
     pCurItem->pc = ppCurrent[1]; 
     pCurItem->next = new CallStackItem; 

     // Go the the previously kept ebp 
     ppCurrent = (void**)*ppCurrent; 
     pCurItem = pCurItem->next; 
     ++nCurLevel; 
    } 

    return pResult; 
} 

void PrintCallStack(CallStackHandle hCallStack) 
{ 
    CallStackItem* pCurItem = (CallStackItem*)hCallStack; 
    printf("----- Call stack start -----\n"); 
    while (pCurItem) 
    { 
     printf("0x%08x\n", pCurItem->pc); 
     pCurItem = pCurItem->next; 
    } 
    printf("----- Call stack end -----\n"); 
} 

void ReleaseCallStack(CallStackHandle hCallStack) 
{ 
    CallStackItem* pCurItem = (CallStackItem*)hCallStack; 
    CallStackItem* pPrevItem; 
    while (pCurItem) 
    { 
     pPrevItem = pCurItem; 
     pCurItem = pCurItem->next; 
     delete pPrevItem; 
    } 
} 
1

Я использую Jochen Kalmbachs StackWalker (http://stackwalker.codeplex.com/).

Я speedet it up так:

  • самое время теряется в ищет PDB files в каталогах по умолчанию и PDB серверов.

  • Я использую только one PDB path и не реализовал white list для изображений, которые я хочу, чтобы разрешить (нет необходимости для меня, чтобы искать user32.pdb)

  • Иногда мне не нужно нырять на дно, так что я Определена max deep

изменения кода:

BOOL StackWalker::LoadModules() 
{ 

    ... 

    // comment this line out and replace to your pdb path 
    // BOOL bRet = this->m_sw->Init(szSymPath); 
    BOOL bRet = this->m_sw->Init(<my pdb path>); 

    ... 

} 

BOOL StackWalker::ShowCallstack(int iMaxDeep /* new parameter */ ...) 
{ 

    ... 

// define a maximal deep 
// for (frameNum = 0; ; ++frameNum) 
    for (frameNum = 0; frameNum < iMaxDeep; ++frameNum) 
    { 

     ... 

    } 
} 

новейшая версия (supporti g VS2010) от StackWalker находится на Codeplex. Документация все еще находится на CodeProject.

 Смежные вопросы

  • Нет связанных вопросов^_^