Как вы можете использовать CaptureStackBackTrace для захвата стека исключений, а не стека вызовов?

Я разметил следующий код:

#include "stdafx.h"
#include <process.h>
#include <iostream>
#include <Windows.h>
#include "dbghelp.h"

using namespace std;

#define TRACE_MAX_STACK_FRAMES 1024
#define TRACE_MAX_FUNCTION_NAME_LENGTH 1024

int printStackTrace()
{
    void *stack[TRACE_MAX_STACK_FRAMES];
    HANDLE process = GetCurrentProcess();
    SymInitialize(process, NULL, TRUE);
    WORD numberOfFrames = CaptureStackBackTrace(0, TRACE_MAX_STACK_FRAMES, stack, NULL);
    SYMBOL_INFO *symbol = (SYMBOL_INFO *)malloc(sizeof(SYMBOL_INFO)+(TRACE_MAX_FUNCTION_NAME_LENGTH - 1) * sizeof(TCHAR));
    symbol->MaxNameLen = TRACE_MAX_FUNCTION_NAME_LENGTH;
    symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    DWORD displacement;
    IMAGEHLP_LINE64 *line = (IMAGEHLP_LINE64 *)malloc(sizeof(IMAGEHLP_LINE64));
    line->SizeOfStruct = sizeof(IMAGEHLP_LINE64);
    for (int i = 0; i < numberOfFrames; i++)
    {
        DWORD64 address = (DWORD64)(stack[i]);
        SymFromAddr(process, address, NULL, symbol);
        if (SymGetLineFromAddr64(process, address, &displacement, line))
        {
            printf("\tat %s in %s: line: %lu: address: 0x%0X\n", symbol->Name, line->FileName, line->LineNumber, symbol->Address);
        }
        else
        {
            printf("\tSymGetLineFromAddr64 returned error code %lu.\n", GetLastError());
            printf("\tat %s, address 0x%0X.\n", symbol->Name, symbol->Address);
        }
    }
    return 0;
}

void function2()
{
    int a = 0;
    int b = 0;
    throw new exception;
}

void function1()
{
    int a = 0;
    function2();
}

void function0()
{
    function1();
}

static void threadFunction(void *param)
{
    try
    {
        function0();
    }
    catch (...)
    {
        printStackTrace();
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    _beginthread(threadFunction, 0, NULL);
    printf("Press any key to exit.\n");
    cin.get();
    return 0;
}

Он регистрирует трассировку стека, но проблема в том, что записываемая трассировка стека не дает мне номера строк, которые я хочу. Я хочу, чтобы он записывал номера строк мест, которые вызывали исключение, на стек вызовов и вверх, как в C #. Но то, что он на самом деле делает сейчас, это выводит следующее:

        at printStackTrace in c:\users\<yourusername>\documents\visual studio 2013\pr
ojects\stacktracing\stacktracing\stacktracing.cpp: line: 17: address: 0x10485C0
        at threadFunction in c:\users\<yourusername>\documents\visual studio 2013\pro
jects\stacktracing\stacktracing\stacktracing.cpp: line: 68: address: 0x10457C0
        SymGetLineFromAddr64 returned error code 487.
        at beginthread, address 0xF9431E0.
        SymGetLineFromAddr64 returned error code 487.
        at endthread, address 0xF9433E0.
        SymGetLineFromAddr64 returned error code 487.
        at BaseThreadInitThunk, address 0x7590494F.
        SymGetLineFromAddr64 returned error code 487.
        at RtlInitializeExceptionChain, address 0x7713986A.
        SymGetLineFromAddr64 returned error code 487.
        at RtlInitializeExceptionChain, address 0x7713986A.

Проблема, с которой я сталкиваюсь, еще раз заключается в том, чтоline: 68 в этом следе соответствует строке, которая вызывает методprintStackTrace();, в то время как я хотел бы дать мне строку 45, которая соответствует строке, которая выдает исключение:throw new exception; и затем продолжайте дальше вверх по стеку.

Как я могу добиться такого поведения и проникнуть в этот поток именно тогда, когда он генерирует это исключение, чтобы получить правильную трассировку стека?

PS Приведенный выше код был запущен для консольного приложения, использующего MSVC ++ с включенным Юникодом на компьютере под управлением Windows 8.1 x64, причем приложение запускается как приложение Win32 в режиме отладки.

Ответы на вопрос(2)

Ваш ответ на вопрос