linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #06719
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3238: crash logger: understand relative high_pc attribs (GCC 4.8 seems to use some) and work on x64
------------------------------------------------------------
revno: 3238
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Mon 2013-03-25 21:50:31 +0100
message:
crash logger: understand relative high_pc attribs (GCC 4.8 seems to use some) and work on x64
modified:
win32/CrashLogger.cpp
--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk
Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'win32/CrashLogger.cpp'
--- win32/CrashLogger.cpp 2013-01-18 21:28:38 +0000
+++ win32/CrashLogger.cpp 2013-03-25 20:50:31 +0000
@@ -27,7 +27,10 @@
FILE* f;
-#if defined(__MINGW32__) && !defined(_WIN64)
+#if defined(__MINGW32__)
+
+/* All MinGW variants (even x64 SEH ones) store debug information as DWARF. We use libdwarf to
+parse it. */
#include <imagehlp.h>
@@ -108,12 +111,40 @@
DIE that specifically describes the enclosing function of the given address. */
Dwarf_Die browseDIE(Dwarf_Debug dbg, Dwarf_Addr addr, Dwarf_Die die, Dwarf_Error& error) {
- Dwarf_Addr lowpc, highpc;
- if(dwarf_lowpc(die, &lowpc, &error) == DW_DLV_OK && dwarf_highpc(die, &highpc, &error) == DW_DLV_OK && addr >= lowpc && addr <= highpc) {
- // found one! make sure it represents a function (section 3.3 of the DWARF 2 spec).
- Dwarf_Half tag;
- if(dwarf_tag(die, &tag, &error) == DW_DLV_OK && (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine)) {
- return die;
+ /* only care about DIEs that represent functions (section 3.3 of the DWARF 4 spec). */
+ Dwarf_Half tag;
+ if(dwarf_tag(die, &tag, &error) == DW_DLV_OK && (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine)) {
+
+ /* get the low_pc & high_pc attributes of this DIE to see if it contains the address we are
+ looking for. can't use dwarf_highpc here because that function only accepts absolute
+ high_pc values; however, section 2.17.2 of the DWARF 4 spec mandates that the high_pc value
+ may also be a constant relative to low_pc. */
+ Dwarf_Addr lowpc, highpc;
+ Dwarf_Attribute high_attr;
+ if(dwarf_lowpc(die, &lowpc, &error) == DW_DLV_OK && addr >= lowpc &&
+ dwarf_attr(die, DW_AT_high_pc, &high_attr, &error) == DW_DLV_OK)
+ {
+
+ Dwarf_Half form;
+ if(dwarf_whatform(high_attr, &form, &error) == DW_DLV_OK) {
+ bool got_high = false;
+ if(form == DW_FORM_addr) { // absolute ref, we can use dwarf_highpc.
+ got_high = dwarf_highpc(die, &highpc, &error) == DW_DLV_OK;
+ } else { // relative ref.
+ Dwarf_Unsigned offset;
+ if(dwarf_formudata(high_attr, &offset, &error) == DW_DLV_OK) {
+ highpc = lowpc + offset;
+ got_high = true;
+ }
+ }
+
+ if(got_high && addr < highpc) {
+ dwarf_dealloc(dbg, high_attr, DW_DLA_ATTR);
+ return die;
+ }
+ }
+
+ dwarf_dealloc(dbg, high_attr, DW_DLA_ATTR);
}
}
@@ -399,24 +430,11 @@
}
}
-// add some x64 defs that MinGW is missing.
-#define DWORD64 DWORD
-#define IMAGEHLP_LINE64 IMAGEHLP_LINE
-#define IMAGEHLP_MODULE64 IMAGEHLP_MODULE
-#define IMAGEHLP_SYMBOL64 IMAGEHLP_SYMBOL
-#define STACKFRAME64 STACKFRAME
-#define StackWalk64 StackWalk
-#define SymFunctionTableAccess64 SymFunctionTableAccess
-#define SymGetLineFromAddr64 SymGetLineFromAddr
-#define SymGetModuleBase64 SymGetModuleBase
-#define SymGetModuleInfo64 SymGetModuleInfo
-#define SymGetSymFromAddr64 SymGetSymFromAddr
-
-#elif defined(_MSC_VER) || defined(__MINGW64__)
+#elif defined(_MSC_VER)
#include <dbghelp.h>
-// MSVC & MinGW64 use SEH. Nothing special to add besides that include file.
+// MSVC uses SEH. Nothing special to add besides that include file.
#else
@@ -473,7 +491,7 @@
HANDLE const process = GetCurrentProcess();
HANDLE const thread = GetCurrentThread();
-#if defined(__MINGW32__) && !defined(_WIN64)
+#if defined(__MINGW32__)
SymSetOptions(SYMOPT_DEFERRED_LOADS);
#else
SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_LOAD_LINES | SYMOPT_UNDNAME);
@@ -528,7 +546,7 @@
continue;
fprintf(f, "%s: ", module.ModuleName);
-#if defined(__MINGW32__) && !defined(_WIN64)
+#if defined(__MINGW32__)
// read DWARF debugging info if available.
if(module.LoadedImageName[0] ||
// LoadedImageName is not always correctly filled in XP...