linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #04278
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2570: crash logger: write the return value & parameters of functions
------------------------------------------------------------
revno: 2570
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Mon 2011-06-27 17:44:45 +0200
message:
crash logger: write the return value & parameters of functions
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 2011-06-26 21:38:15 +0000
+++ win32/CrashLogger.cpp 2011-06-27 15:44:45 +0000
@@ -143,6 +143,62 @@
return 0;
}
+// utility function that retrieves the name of a DIE.
+bool getName(Dwarf_Debug dbg, Dwarf_Die die, string& ret, Dwarf_Error& error) {
+ char* name;
+ if(dwarf_diename(die, &name, &error) == DW_DLV_OK) {
+ ret = name;
+ dwarf_dealloc(dbg, name, DW_DLA_STRING);
+ return true;
+ }
+ return false;
+}
+
+// utility function that follows a reference-type attribute (one that points to another DIE).
+Dwarf_Die followRef(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attribute, Dwarf_Error& error) {
+ Dwarf_Die ret = 0;
+ Dwarf_Attribute attr;
+ if(dwarf_attr(die, attribute, &attr, &error) == DW_DLV_OK) {
+ Dwarf_Off offset;
+ if(dwarf_global_formref(attr, &offset, &error) == DW_DLV_OK) {
+ dwarf_offdie(dbg, offset, &ret, &error);
+ }
+ dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
+ }
+ return ret;
+}
+
+/* retrieve the name of the DIE pointed to by the "type" attribute of a DIE. for a function DIE,
+this is the return value of the function (section 3.3.2 of the DWARF 2 spec). for an object DIE,
+this is the type of that object (section 4.1.4 of the DWARF 2 spec). */
+string getType(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Error& error, bool recursing = false) {
+ string ret;
+
+ // follow section 5 of the DWARF 2 spec. multiple type DIEs may be chained together.
+ if(recursing && getName(dbg, die, ret, error)) {
+ return ret;
+ }
+ Dwarf_Die type_die = followRef(dbg, die, DW_AT_type, error);
+ if(type_die) {
+ ret = getType(dbg, type_die, error, true);
+ Dwarf_Half tag;
+ if(dwarf_tag(die, &tag, &error) == DW_DLV_OK) {
+ switch(tag) {
+ case DW_TAG_const_type: ret += " const"; break;
+ case DW_TAG_pointer_type: ret += '*'; break;
+ case DW_TAG_reference_type: ret += '&'; break;
+ case DW_TAG_volatile_type: ret += " volatile"; break;
+ }
+ }
+ dwarf_dealloc(dbg, type_die, DW_DLA_DIE);
+ }
+
+ if(ret.empty())
+ ret = "void/unknown";
+
+ return ret;
+}
+
void getDebugInfo(string path, DWORD addr, string& file, int& line, int& column, string& function) {
if(path.empty())
return;
@@ -241,11 +297,7 @@
/* could not get a precise statement within this CU; resort to showing
the global name of this CU's DIE which, according to section 3.1 of the
DWARF 2 spec, is almost what we want. */
- char* name;
- if(dwarf_diename(cu_die, &name, &error) == DW_DLV_OK) {
- file = name;
- dwarf_dealloc(dbg, name, DW_DLA_STRING);
- }
+ getName(dbg, cu_die, file, error);
}
/* to find the enclosing function, skim through the children and siblings
@@ -256,25 +308,45 @@
/* check if the DIE has a "specification" attribute which, according to
section 5.5.5 of the DWARF 2 spec, is a pointer to the DIE that
actually describes the function. */
- Dwarf_Attribute attr;
- if(dwarf_attr(die, DW_AT_specification, &attr, &error) == DW_DLV_OK) {
- Dwarf_Off spec_offset;
- if(dwarf_global_formref(attr, &spec_offset, &error) == DW_DLV_OK) {
- Dwarf_Die spec_die;
- if(dwarf_offdie(dbg, spec_offset, &spec_die, &error) == DW_DLV_OK) {
- // replace the previous DIE by this new one.
- dwarf_dealloc(dbg, die, DW_DLA_DIE);
- die = spec_die;
- }
- }
- }
+ Dwarf_Die spec_die = followRef(dbg, die, DW_AT_specification, error);
/* as specified in section 3.3.1 of the DWARF 2 spec, the name of this
function-representing DIE should be what we are looking for. */
- char* name;
- if(dwarf_diename(die, &name, &error) == DW_DLV_OK) {
- function = name;
- dwarf_dealloc(dbg, name, DW_DLA_STRING);
+ getName(dbg, spec_die ? spec_die : die, function, error);
+
+ if(!function.empty()) {
+ /* according to section 3.3.2 of the DWARF 2 spec, the type of this
+ function-representing DIE is the return value of the function. */
+ function = getType(dbg, spec_die ? spec_die : die, error) + ' ' + function + '(';
+
+ /* now get the parameters of the function. each parameter is
+ represented by a DIE that is a child of the function-representing
+ DIE (section 3.3.4 of the DWARF 2 spec). */
+ Dwarf_Die child;
+ if(dwarf_child(die, &child, &error) == DW_DLV_OK) {
+ Dwarf_Die next = 0;
+ string name;
+ while(true) {
+ if(getName(dbg, child, name, error)) {
+ if(next) // not the first iteration
+ function += ", ";
+ function += getType(dbg, child, error) + ' ' + name;
+ }
+ bool ok = dwarf_siblingof(dbg, child, &next, &error) == DW_DLV_OK;
+ dwarf_dealloc(dbg, child, DW_DLA_DIE);
+ if(ok) {
+ child = next;
+ } else {
+ break;
+ }
+ }
+ }
+
+ function += ')';
+
+ if(spec_die) {
+ dwarf_dealloc(dbg, spec_die, DW_DLA_DIE);
+ }
}
dwarf_dealloc(dbg, die, DW_DLA_DIE);
@@ -468,7 +540,7 @@
fputs(")", f);
}
if(!function.empty()) {
- fprintf(f, " in function %s", function.c_str());
+ fprintf(f, ", function: %s", function.c_str());
}
fputs("\n", f);
}