Мне нужно получить трассировку стека из приложения C ++, и сериализовать его в строку, чтобы он мог быть проанализирован позже. Единственный API, о котором я слышал в Windows, — это StackWalk64, который, похоже, не поддерживается.
Как получить трассировку стека из C ++ в приложении Магазина Windows?
Единственный способ отладить сложные проблемы WINRT — это использовать ETW для отслеживания цепочек причинно-следственных связей. Хотя это довольно утомительно для настройки В этой статье (со ссылкой на c #) освещается метод:
Вот несколько приличных введений в ETW для C / C ++.
Используя этот метод, вы сможете создавать события ETW, а затем прослушивать их в приложении и включать их в виде сериализованной строки для последующего анализа.
То, что работает для меня, это код asm, как показано ниже Это работает только на платформе x86, поэтому полезно только при отладке на эмуляторе. Возвращенные указатели кадров можно использовать в окне разборки для перехода в исходный код. Я думаю, что должно быть возможно использовать файл карты, чтобы получить точное местоположение исходного кода.
Я использую этот код для поиска утечек памяти, в сочетании с crtdbg он очень хорошо работает в очень больших приложениях с большим количеством выделений. Профилировщик памяти VS 2013 может обрабатывать не более 1 минуты записи данных.
FINLINE static DWORD GetCallerFrameNum(int index) {
#if defined(_DEBUG) && defined(_MSC_VER) && defined(_M_IX86)
DWORD caller = 0;
__asm
{
mov ebx, ebp
mov ecx, index
inc ecx
xor eax, eax
StackTrace_getCaller_next :
mov eax, [ebx + 4]
mov ebx, [ebx]
dec ecx
jnz StackTrace_getCaller_next
mov caller, eax
}
return caller;
#else
return 0;
#endif
}
template<class T>
void RecordStackTrace(T& vecOut) {
vecOut.clear();
vecOut.reserve(32);
for (INT iInitLevel = 1; iInitLevel < 32; ++iInitLevel) {
DWORD dwFrameNum = GetCallerFrameNum(iInitLevel);
if (!dwFrameNum)
return;
vecOut.push_back(dwFrameNum);
}
}