3

次のコードがあります。

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

using namespace std;

int LogStackTrace()
{
    void *stack[1024];
    HANDLE process = GetCurrentProcess();
    SymInitialize(process, NULL, TRUE);
    WORD numberOfFrames = CaptureStackBackTrace(0, 1000, stack, NULL);
    SYMBOL_INFO *symbol = (SYMBOL_INFO *)malloc(sizeof(SYMBOL_INFO));
    symbol->MaxNameLen = 1024;
    symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    IMAGEHLP_LINE *line = (IMAGEHLP_LINE *)malloc(sizeof(IMAGEHLP_LINE));
    line->SizeOfStruct = sizeof(IMAGEHLP_LINE);
    printf("Caught exception ");
    for (int i = 0; i < numberOfFrames; i++)
    {
        SymFromAddr(process, (DWORD64)(stack[i]), NULL, symbol);
        SymGetLineFromAddr(process, (DWORD)(stack[i]), NULL, line);
        printf("at %s in %s, address 0x%0X\n", symbol->Name, line->FileName, symbol->Address);
    }
    return 0;
}

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

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

void function0()
{
    function1();
}

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

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

問題は、次の行で常にエラーが発生することです。printf("at %s in %s, address 0x%0X\n", symbol->Name, line->FileName, symbol->Address);

理由は、行の FileName が NULL のように見えるためです。実際、ライン構造全体がめちゃくちゃです。エラー時にスタック トレースを表示するアプリケーションを作成しようとしています。しかし、それはなぜですか?上記のコードを使用して動作するべきではありませんか? PS 私は単純な MSVC++ コンソール アプリケーションとして、Win32 に対してコンパイルしました。

4

2 に答える 2

2
SYMBOL_INFO *symbol = (SYMBOL_INFO *)malloc(sizeof(SYMBOL_INFO));
symbol->MaxNameLen = 1024;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);

状態のドキュメントSizeOfStruct:

構造体のサイズ (バイト単位)。このメンバーは sizeof(SYMBOL_INFO) に設定する必要があります。 データの合計サイズは、SizeOfStruct + (MaxNameLen - 1) * sizeof(TCHAR) であることに注意してください。1 を引く理由は、名前の最初の文字が構造体のサイズに含まれるためです。

鉱山を強調します。少なくともsizeof(SYMBOL_INFO) + MaxNameLen + 1バイトのストレージを割り当てる必要があります。sizeof(SYMBOL_INFO)バイトのみを割り当てています。

于 2014-03-17T21:18:17.977 に答える