예제 #1
0
static void DumpType(IDiaSymbol *symbol, int deep)
{
    IDiaEnumSymbols *   enumChilds = NULL;
    HRESULT             hr;
    const char *        nameStr = NULL;
    const char *        type;
    LONG                offset;
    ULONGLONG           length;
    ULONG               celt = 0;
    ULONG               symtag;
    DWORD               locType;
    bool                typeSeen;

#if 0
    if (deep > 2)
        return;
#endif

    if (symbol->get_symTag(&symtag) != S_OK)
        return;

    nameStr = GetTypeName(symbol);

    g_typesSeen.Intern(nameStr, &typeSeen);
    if (typeSeen)
        return;

    symbol->get_length(&length);
    symbol->get_offset(&offset);

    if (SymTagData == symtag) {
        if (symbol->get_locationType(&locType) != S_OK)
            return; // must be a symbol in optimized code

        // TODO: use get_offsetInUdt (http://msdn.microsoft.com/en-us/library/dd997149.aspx) ?
        // TODO: use get_type (http://msdn.microsoft.com/en-US/library/cwx3656b(v=vs.80).aspx) ?
        // TODO: see what else we can get http://msdn.microsoft.com/en-US/library/w8ae4k32(v=vs.80).aspx
        if (LocIsThisRel == locType) {
            g_report.AppendFmt("%s%s|%d\n", spaces(deep), nameStr, (int)offset);
        }
    } else if (SymTagUDT == symtag) {
        // TODO: why is it always "struct" even for classes?
        type = GetUdtType(symbol);
        g_report.AppendFmt("%s%s|%s|%d\n", spaces(deep), type, nameStr, (int)length);
        hr = symbol->findChildren(SymTagNull, NULL, nsNone, &enumChilds);
        if (!SUCCEEDED(hr))
            return;
        IDiaSymbol* child;
        while (SUCCEEDED(enumChilds->Next(1, &child, &celt)) && (celt == 1))
        {
            DumpType(child, deep+1);
            child->Release();
        }
        enumChilds->Release();
    } else {
        if (symbol->get_locationType(&locType) != S_OK)
            return; // must be a symbol in optimized code
        // TODO: assert?
    }
}
예제 #2
0
static void GetGraphicsDriverInfo(str::Str<char>& s)
{
    // the info is in registry in:
    // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}\0000\
    //   Device Description REG_SZ (same as DriverDesc, so we don't read it)
    //   DriverDesc REG_SZ
    //   DriverVersion REG_SZ
    //   UserModeDriverName REG_MULTI_SZ
    //
    // There can be more than one driver, they are in 0000, 0001 etc.
    for (int i=0; ; i++)
    {
        ScopedMem<WCHAR> key(str::Format(GFX_DRIVER_KEY_FMT, i));
        ScopedMem<WCHAR> v1(ReadRegStr(HKEY_LOCAL_MACHINE, key, L"DriverDesc"));
        // I assume that if I can't read the value, there are no more drivers
        if (!v1)
            break;
        ScopedMem<char> v1a(str::conv::ToUtf8(v1));
        s.AppendFmt("Graphics driver %d\r\n", i);
        s.AppendFmt("  DriverDesc:         %s\r\n", v1.Get());
        v1.Set(ReadRegStr(HKEY_LOCAL_MACHINE, key, L"DriverVersion"));
        if (v1) {
            v1a.Set(str::conv::ToUtf8(v1));
            s.AppendFmt("  DriverVersion:      %s\r\n", v1a.Get());
        }
        v1.Set(ReadRegStr(HKEY_LOCAL_MACHINE, key, L"UserModeDriverName"));
        if (v1) {
            v1a.Set(str::conv::ToUtf8(v1));
            s.AppendFmt("  UserModeDriverName: %s\r\n", v1a.Get());
        }
    }
}
예제 #3
0
void GetThreadCallstack(str::Str<char>& s, DWORD threadId)
{
    if (threadId == GetCurrentThreadId())
        return;

    s.AppendFmt("\r\nThread: %x\r\n", threadId);

    DWORD access = THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION | THREAD_SUSPEND_RESUME;
    HANDLE hThread = OpenThread(access, false, threadId);
    if (!hThread) {
        s.Append("Failed to OpenThread()\r\n");
        return;
    }

    DWORD res = SuspendThread(hThread);
    if (-1 == res) {
        s.Append("Failed to SuspendThread()\r\n");
    } else {
        CONTEXT ctx = { 0 };
        ctx.ContextFlags = CONTEXT_FULL;
        BOOL ok = GetThreadContext(hThread, &ctx);
        if (ok)
            GetCallstack(s, ctx, hThread);
        else
            s.Append("Failed to GetThreadContext()\r\n");

        ResumeThread(hThread);
    }
    CloseHandle(hThread);
}
예제 #4
0
static void AppendVal(const char *val, char escapeChar, bool compact, str::Str<char>& res)
{
    const char *start = val;
    const char *s = start;
    char escaped = 0;
    while (*s) {
        char c = *s++;
        if (escapeChar == c)
            escaped = escapeChar;
        else if (']' == c)
            escaped = ']';
        else if ('[' == c)
            escaped = '[';
        else if ('\n' == c)
            escaped = 'n';
        else if ('\r' == c)
            escaped = 'r';
        if (0 == escaped)
            continue;

        size_t len = s - start - 1;
        res.Append(start, len);
        res.Append(escapeChar);
        res.Append(escaped);
        start = s;
        escaped = 0;
    }
    size_t len = s - start;
    res.Append(start, len);
    if (!compact)
        res.Append(NL);
}
예제 #5
0
static void DumpSection(IDiaSectionContrib *item)
{
    DWORD           sectionNo;
    DWORD           offset;
    DWORD           length;

    item->get_addressSection(&sectionNo);
    item->get_addressOffset(&offset);
    item->get_length(&length);

    //DWORD compilandId;
    //item->get_compilandId(&compilandId);

    const char *sectionType = GetSectionType(item);
    const char *objFileName = GetObjFileName(item);

    if (g_compact) {
        // type | sectionNo | length | offset | objFileId
        int objFileId = InternString(objFileName);
        g_report.AppendFmt("%s|%d|%d|%d|%d\n", sectionType, sectionNo, length, offset, objFileId);
    } else {
        // type | sectionNo | length | offset | objFile
        g_report.AppendFmt("%s|%d|%d|%d|%s\n", sectionType, sectionNo, length, offset, objFileName);
    }
}
예제 #6
0
static void GetOsVersion(str::Str<char>& s)
{
    OSVERSIONINFOEX ver;
    ZeroMemory(&ver, sizeof(ver));
    ver.dwOSVersionInfoSize = sizeof(ver);
#pragma warning(push)
#pragma warning(disable: 4996) // 'GetVersionEx': was declared deprecated
    // starting with Windows 8.1, GetVersionEx will report a wrong version number
    // unless the OS's GUID has been explicitly added to the compatibility manifest
    BOOL ok = GetVersionEx((OSVERSIONINFO*)&ver);
#pragma warning(pop)
    if (!ok)
        return;
    const char *os = OsNameFromVer(ver);
    int servicePackMajor = ver.wServicePackMajor;
    int servicePackMinor = ver.wServicePackMinor;
    int buildNumber = ver.dwBuildNumber & 0xFFFF;
#ifdef _WIN64
    const char *arch = "64-bit";
#else
    const char *arch = IsRunningInWow64() ? "Wow64" : "32-bit";
#endif
    if (0 == servicePackMajor)
        s.AppendFmt("OS: Windows %s build %d %s\r\n", os, buildNumber, arch);
    else if (0 == servicePackMinor)
        s.AppendFmt("OS: Windows %s SP%d build %d %s\r\n", os, servicePackMajor, buildNumber, arch);
    else
        s.AppendFmt("OS: Windows %s %d.%d build %d %s\r\n", os, servicePackMajor, servicePackMinor, buildNumber, arch);
}
예제 #7
0
static void PrettyPrintNode(TxtNode *curr, int nest, str::Str<char>& res)
{
    if (TextNode == curr->type) {
        PrettyPrintKeyVal(curr, nest, res);
        return;
    }

    if (StructNode == curr->type) {
        PrettyPrintKeyVal(curr, nest, res);
        res.Append(" + [\n");
    } else if (nest >= 0) {
        CrashIf(ArrayNode != curr->type);
        AppendNest(res, nest);
        res.Append("[\n");
    }

    TxtNode *child;
    for (size_t i = 0; i < curr->children->Count(); i++) {
        child = curr->children->At(i);
        PrettyPrintNode(child, nest + 1, res);
    }

    if (nest >= 0) {
        AppendNest(res, nest);
        res.Append("]\n");
    }
}
예제 #8
0
static void AppendAddress(str::Str<char>& s, DWORD64 addr)
{
#ifdef _WIN64
    s.AppendFmt("%016I64X", addr);
#else
    s.AppendFmt("%08X", (DWORD)addr);
#endif
}
예제 #9
0
// the result doesn't have to be free()d but is only valid until the next call to this function
static const char *GetTypeName(IDiaSymbol *symbol)
{
    static str::Str<char> strTmp;
    BSTR name = NULL;
    symbol->get_name(&name);
    BStrToString(strTmp, name, "<noname>", true);
    SysFreeStringSafe(name);
    return strTmp.Get();
}
예제 #10
0
static const char *GetSourceFileName(IDiaSymbol *symbol)
{
    static str::Str<char> strTmp;
    BSTR   name = 0;
    symbol->get_sourceFileName(&name);
    BStrToString(strTmp, name, "<nosrcfile>");
    SysFreeStringSafe(name);
    return strTmp.Get();
}
예제 #11
0
static const char *GetLibraryName(IDiaSymbol *symbol)
{
    static str::Str<char> strTmp;
    BSTR   name = 0;
    symbol->get_libraryName(&name);
    BStrToString(strTmp, name, "<nolibfile>");
    SysFreeStringSafe(name);
    return strTmp.Get();
}
static void AppendNewline(str::Str<WCHAR>& extracted, Vec<RectI>& coords, const WCHAR *lineSep)
{
    if (extracted.Count() > 0 && ' ' == extracted.Last()) {
        extracted.Pop();
        coords.Pop();
    }
    extracted.Append(lineSep);
    coords.AppendBlanks(str::Len(lineSep));
}
예제 #13
0
static void GetInternedStringsReport(str::Str<char>& resOut)
{
    resOut.Append("Strings:\n");
    int n = g_strInterner.StringsCount();
    for (int i = 0; i < n; i++) {
        resOut.AppendFmt("%d|%s\n", i, g_strInterner.GetByIndex(i));
    }
    resOut.Append("\n");
}
예제 #14
0
void GetProgramInfo(str::Str<char>& s)
{
    s.AppendFmt("Ver: %s", QM(CURR_VERSION));
#ifdef SVN_PRE_RELEASE_VER
    s.AppendFmt(".%s pre-release", QM(SVN_PRE_RELEASE_VER));
#endif
#ifdef DEBUG
    s.Append(" dbg");
#endif
    s.Append("\r\n");
}
예제 #15
0
void GetProgramInfo(str::Str<char>& s)
{
    s.AppendFmt("Ver: %s", CURR_VERSION_STRA);
#ifdef SVN_PRE_RELEASE_VER
    s.AppendFmt(" pre-release");
#endif
#ifdef DEBUG
    if (!str::EndsWith(s.Get(), " (dbg)"))
        s.Append(" (dbg)");
#endif
    s.Append("\r\n");
}
예제 #16
0
static void PrettyPrintKeyVal(TxtNode *curr, int nest, str::Str<char>& res)
{
    AppendNest(res, nest);
    if (curr->keyStart) {
        AppendWsTrimEnd(res, curr->keyStart, curr->keyEnd);
        if (StructNode != curr->type)
            res.Append(" + ");
    }
    AppendWsTrimEnd(res, curr->valStart, curr->valEnd);
    if (StructNode != curr->type)
        res.Append("\n");
}
예제 #17
0
static void DumpSymbol(IDiaSymbol *symbol)
{
    DWORD               section, offset, rva;
    DWORD               dwTag;
    enum SymTagEnum     tag;
    ULONGLONG           length = 0;
    const char *        typeName = NULL;
          char *        dataTypeName = NULL;
    const char *        thunkTypeName = NULL;

    symbol->get_symTag(&dwTag);
    tag = (enum SymTagEnum)dwTag;
    typeName = GetSymTypeName(tag);

    symbol->get_relativeVirtualAddress(&rva);
    symbol->get_addressSection(&section);
    symbol->get_addressOffset(&offset);

    // for data, get length from type
    if (SymTagData == tag)
    {
        IDiaSymbol *type = NULL;
        if (symbol->get_type(&type) == S_OK) // no SUCCEEDED test as may return S_FALSE!
        {
            type->get_length(&length);
            const char *s = GetUndecoratedSymbolName(type, "");
            if (s && *s)
                dataTypeName = str::Dup(s);
            type->Release();
        }
    } if (SymTagThunk == tag) {
        DWORD dwThunkKind;
        if (S_OK == symbol->get_thunkOrdinal(&dwThunkKind))
            thunkTypeName = GetThunkTypeName(dwThunkKind);
    } else {
        symbol->get_length(&length);
    }

    const char *nameStr = GetUndecoratedSymbolName(symbol);
    if (SymTagData == tag) {
        // type | section | length | offset | rva | name | dataTypeName
        char *tmp = dataTypeName ? dataTypeName : "";
        g_report.AppendFmt("%s|%d|%d|%d|%d|%s|%s\n", typeName, (int)section, (int)length, (int)offset, (int)rva, nameStr, tmp);
        free(dataTypeName);
    } else if (SymTagThunk == tag) {
        const char *tmp = thunkTypeName ? thunkTypeName : "";
        // type | section | length | offset | rva | name | thunkTypeName
        g_report.AppendFmt("%s|%d|%d|%d|%d|%s|%s\n", typeName, (int)section, (int)length, (int)offset, (int)rva, nameStr, tmp);
    } else {
        // type | section | length | offset | rva | name
        g_report.AppendFmt("%s|%d|%d|%d|%d|%s\n", typeName, (int)section, (int)length, (int)offset, (int)rva, nameStr);
    }
}
 virtual void Visit(const WCHAR *name, const WCHAR *url, int level) {
     if (!url || IsExternalUrl(url))
         return;
     ScopedMem<WCHAR> plainUrl(str::ToPlainUrl(url));
     if (added.FindI(plainUrl) != -1)
         return;
     ScopedMem<char> urlUtf8(str::conv::ToUtf8(plainUrl));
     size_t pageHtmlLen;
     ScopedMem<unsigned char> pageHtml(doc->GetData(urlUtf8, &pageHtmlLen));
     if (!pageHtml)
         return;
     html.AppendFmt("<pagebreak page_path=\"%s\" page_marker />", urlUtf8);
     html.AppendAndFree(doc->ToUtf8(pageHtml, ExtractHttpCharset((const char *)pageHtml.Get(), pageHtmlLen)));
     added.Append(plainUrl.StealData());
 }
예제 #19
0
// the result doesn't have to be free()d but is only valid until the next call to this function
static const char *GetObjFileName(IDiaSectionContrib *item)
{
    static str::Str<char> strTmp;
    BSTR            name = 0;

    IDiaSymbol *    compiland = 0;
    item->get_compiland(&compiland);
    if (compiland) {
        compiland->get_name(&name);
        compiland->Release();
    }
    BStrToString(strTmp, name, "<noobjfile>");
    SysFreeStringSafe(name);
    return strTmp.Get();
}
예제 #20
0
static void AppendNest(str::Str<char>& s, int nest)
{
    while (nest > 0) {
        s.Append("  ");
        --nest;
    }
}
예제 #21
0
static void GetLanguage(str::Str<char>& s)
{
    char country[32] = { 0 }, lang[32] = { 0 };
    GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, country, dimof(country) - 1);
    GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, lang, dimof(lang) - 1);
    s.AppendFmt("Lang: %s %s\r\n", lang, country);
}
    char *GetHtml() {
        // first add the homepage
        const char *index = doc->GetHomePath();
        ScopedMem<WCHAR> url(doc->ToStr(index));
        Visit(NULL, url, 0);

        // then add all pages linked to from the table of contents
        doc->ParseToc(this);

        // finally add all the remaining HTML files
        Vec<char *> *paths = doc->GetAllPaths();
        for (size_t i = 0; i < paths->Count(); i++) {
            char *path = paths->At(i);
            if (str::EndsWithI(path, ".htm") || str::EndsWithI(path, ".html")) {
                if (*path == '/')
                    path++;
                url.Set(str::conv::FromUtf8(path));
                Visit(NULL, url, -1);
            }
        }
        FreeVecMembers(*paths);
        delete paths;

        return html.StealData();
    }
예제 #23
0
static void DumpTypes(IDiaSession *session)
{
    IDiaSymbol *        globalScope = NULL;
    IDiaEnumSymbols *   enumSymbols = NULL;
    IDiaSymbol *        symbol = NULL;

    HRESULT hr = session->get_globalScope(&globalScope);
    if (FAILED(hr))
        return;

    AddReportSepLine();
    g_report.Append("Types:\n");

    DWORD flags = nsfCaseInsensitive|nsfUndecoratedName; // nsNone ?
    hr = globalScope->findChildren(SymTagUDT, 0, flags, &enumSymbols);
    if (FAILED(hr))
        goto Exit;

    ULONG celt = 0;
    for (;;)
    {
        hr = enumSymbols->Next(1, &symbol, &celt);
        if (FAILED(hr) || (celt != 1))
            break;
        DumpType(symbol, 0);
        symbol->Release();
    }

Exit:
    UnkReleaseSafe(enumSymbols);
    UnkReleaseSafe(globalScope);
}
예제 #24
0
static bool GetStackFrameInfo(str::Str<char>& s, STACKFRAME64 *stackFrame,
                              CONTEXT *ctx, HANDLE hThread)
{
#if defined(_WIN64)
    int machineType = IMAGE_FILE_MACHINE_AMD64;
#else
    int machineType = IMAGE_FILE_MACHINE_I386;
#endif
    BOOL ok = _StackWalk64(machineType, GetCurrentProcess(), hThread,
        stackFrame, ctx, NULL, _SymFunctionTableAccess64,
        _SymGetModuleBase64, NULL);
    if (!ok)
        return false;

    DWORD64 addr = stackFrame->AddrPC.Offset;
    if (0 == addr)
        return true;
    if (addr == stackFrame->AddrReturn.Offset) {
        s.Append("GetStackFrameInfo(): addr == stackFrame->AddrReturn.Offset");
        return false;
    }

    GetAddressInfo(s, addr);
    return true;
}
bool DjVuEngineImpl::ExtractPageText(miniexp_t item, const WCHAR *lineSep, str::Str<WCHAR>& extracted, Vec<RectI>& coords)
{
    miniexp_t type = miniexp_car(item);
    if (!miniexp_symbolp(type))
        return false;
    item = miniexp_cdr(item);

    if (!miniexp_numberp(miniexp_car(item))) return false;
    int x0 = miniexp_to_int(miniexp_car(item)); item = miniexp_cdr(item);
    if (!miniexp_numberp(miniexp_car(item))) return false;
    int y0 = miniexp_to_int(miniexp_car(item)); item = miniexp_cdr(item);
    if (!miniexp_numberp(miniexp_car(item))) return false;
    int x1 = miniexp_to_int(miniexp_car(item)); item = miniexp_cdr(item);
    if (!miniexp_numberp(miniexp_car(item))) return false;
    int y1 = miniexp_to_int(miniexp_car(item)); item = miniexp_cdr(item);
    RectI rect = RectI::FromXY(x0, y0, x1, y1);

    miniexp_t str = miniexp_car(item);
    if (miniexp_stringp(str) && !miniexp_cdr(item)) {
        if (type != miniexp_symbol("char") && type != miniexp_symbol("word") ||
            coords.Count() > 0 && rect.y < coords.Last().y - coords.Last().dy * 0.8) {
            AppendNewline(extracted, coords, lineSep);
        }
        const char *content = miniexp_to_str(str);
        WCHAR *value = str::conv::FromUtf8(content);
        if (value) {
            size_t len = str::Len(value);
            // TODO: split the rectangle into individual parts per glyph
            for (size_t i = 0; i < len; i++)
                coords.Append(RectI(rect.x, rect.y, rect.dx, rect.dy));
            extracted.AppendAndFree(value);
        }
        if (miniexp_symbol("word") == type) {
            extracted.Append(' ');
            coords.Append(RectI(rect.x + rect.dx, rect.y, 2, rect.dy));
        }
        item = miniexp_cdr(item);
    }
    while (miniexp_consp(str)) {
        ExtractPageText(str, lineSep, extracted, coords);
        item = miniexp_cdr(item);
        str = miniexp_car(item);
    }
    return !item;
}
예제 #26
0
static void GetMachineName(str::Str<char>& s)
{
    WCHAR *s1 = ReadRegStr(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", L"SystemFamily");
    WCHAR *s2 = ReadRegStr(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\BIOS", L"SystemVersion");
    ScopedMem<char> s1u(s1 ? str::conv::ToUtf8(s1) : NULL);
    ScopedMem<char> s2u(s2 ? str::conv::ToUtf8(s2) : NULL);

    if (!s1u && !s2u)
        ; // pass
    else if (!s1u)
        s.AppendFmt("Machine: %s\r\n", s2u.Get());
    else if (!s2u || str::EqI(s1u, s2u))
        s.AppendFmt("Machine: %s\r\n", s1u.Get());
    else
        s.AppendFmt("Machine: %s %s\r\n", s1u.Get(), s2u.Get());

    free(s1);
    free(s2);
}
예제 #27
0
void BStrToString(str::Str<char>& strInOut, BSTR str, char *defString, bool stripWhitespace)
{
    strInOut.Reset();
    if (!str) {
        strInOut.Append(defString);
        return;
    }

    OLECHAR c;
    int len = SysStringLen(str);
    for (int i=0; i<len; i++)
    {
        c = str[i];
        if (stripWhitespace && isspace(c))
            continue;
        if (c < 32 || c >= 128)
            c = '?';
        strInOut.Append((char)c);
    }
}
예제 #28
0
static void GetProcessorName(str::Str<char>& s)
{
    WCHAR *name = ReadRegStr(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor", L"ProcessorNameString");
    if (!name) // if more than one processor
        name = ReadRegStr(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", L"ProcessorNameString");
    if (!name)
        return;

    ScopedMem<char> tmp(str::conv::ToUtf8(name));
    s.AppendFmt("Processor: %s\r\n", tmp);
    free(name);
}
예제 #29
0
static void GetAddressInfo(str::Str<char>& s, DWORD64 addr)
{
    static const int MAX_SYM_LEN = 512;

    char buf[sizeof(SYMBOL_INFO) + MAX_SYM_LEN * sizeof(char)];
    SYMBOL_INFO *symInfo = (SYMBOL_INFO*)buf;

    memset(buf, 0, sizeof(buf));
    symInfo->SizeOfStruct = sizeof(SYMBOL_INFO);
    symInfo->MaxNameLen = MAX_SYM_LEN;

    DWORD64 symDisp = 0;
    char *symName = NULL;
    BOOL ok = _SymFromAddr(GetCurrentProcess(), addr, &symDisp, symInfo);
    if (ok)
        symName = &(symInfo->Name[0]);

    char module[MAX_PATH] = { 0 };
    DWORD section, offset;
    if (GetAddrInfo((void*)addr, module, sizeof(module), section, offset)) {
        str::ToLower(module);
        const char *moduleShort = path::GetBaseName(module);
        AppendAddress(s, addr);
        s.AppendFmt(" %02X:", section);
        AppendAddress(s, offset);
        s.AppendFmt(" %s", moduleShort);

        if (symName)
            s.AppendFmt("!%s+0x%x", symName, (int)symDisp);
        IMAGEHLP_LINE64 line;
        line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
        DWORD disp;
        if (_SymGetLineFromAddr64(GetCurrentProcess(), addr, &disp, &line)) {
            s.AppendFmt(" %s+%d", line.FileName, line.LineNumber);
        }
    } else {
        AppendAddress(s, addr);
    }
    s.Append("\r\n");
}
예제 #30
0
// the result doesn't have to be free()d but is only valid until the next call to this function
static const char *GetUndecoratedSymbolName(IDiaSymbol *symbol, const char *defName = "<noname>")
{
    static str::Str<char> strTmp;

    BSTR name = NULL;

#if 0
    DWORD undecorateOptions = UNDNAME_COMPLETE;
#else
    DWORD undecorateOptions =  UNDNAME_NO_MS_KEYWORDS |
                                UNDNAME_NO_FUNCTION_RETURNS |
                                UNDNAME_NO_ALLOCATION_MODEL |
                                UNDNAME_NO_ALLOCATION_LANGUAGE |
                                UNDNAME_NO_THISTYPE |
                                UNDNAME_NO_ACCESS_SPECIFIERS |
                                UNDNAME_NO_THROW_SIGNATURES |
                                UNDNAME_NO_MEMBER_TYPE |
                                UNDNAME_NO_RETURN_UDT_MODEL |
                                UNDNAME_NO_ECSU;
#endif

    if (S_OK == symbol->get_undecoratedNameEx(undecorateOptions, &name)) {
        BStrToString(strTmp, name, "", true);
        if (str::Eq(strTmp.Get(), "`string'"))
            return "*str";
        strTmp.Replace("(void)", "()");
        // more ideas for undecoration:
        // http://google-breakpad.googlecode.com/svn/trunk/src/common/windows/pdb_source_line_writer.cc
    } else {
        // Unfortunately it does happen that get_undecoratedNameEx() fails
        // e.g. for RememberDefaultWindowPosition() in Sumatra code
        symbol->get_name(&name);
        BStrToString(strTmp, name, defName, true);
    }
    SysFreeStringSafe(name);

    return strTmp.Get();
}