relocs: smart reader
by Roland McGrath
DwarfTasks 4.3 says "relocatable values: smart reader".
Here's the brain dump on what that means.
Right now, the libdw code is completely ignorant of the relocatability of
the DWARF data. It reads straight DWARF encoding, and expects the values
it gets that way to make sense. The libdwfl/relocate.c machinery does full
relocation of all the data (blind to its formats) before libdw looks at it.
This will change in libdw internals. (I don't think the libdw.h interface
will change for this, thought some details in libdwfl and C++ will.)
The first step is to find each place in libdw that decodes a relocatable
quantity. This is anything that is offset-size or address-size. (The
dwarflint reloc work has recently enumerated all the spots not to forget.)
The libdw code has lots of things like:
if (attrp->cu->offset_size == 8)
off = read_8ubyte_unaligned (dbg, attrp->valp);
else
off = read_4ubyte_unaligned (dbg, attrp->valp);
Replace these with calls to new helpers, one for offset and one for address.
Of each, also a *_inc variant. These will take the Dwarf * and also a size
selection argument (either offset/address size, or bool of == 8). The
offset decoders take an IDX_debug_* argument saying which section the offset
points into. They need to be able to signal errors (e.g. return a bool
saying they've done __libdw_seterrno). Perhaps also both (offset and
address flavors) should take an IDX_debug_* argument saying where the
decoded data comes from (that's probably just for debugging).
To start with, just make the helpers trivial inlines wrapping
read_[48]ubyte_unaligned so nothing changes. Next, lift the offset validity
checks from existing code into these helpers. If there are cases that are
offset/address sized lengths instead of offsets/addrs, then we'll need
variants of the helpers for that.
A good testing hack would be to make the wrappers emit somewhere (stderr,
whatever) the idx:offset where each offset/address was decoded. Then you
could walk the data with a eu-readelf run or whatnot, sort -u that log and
compare it to what places dwarflint thinks relocs might be. Once we have
the right calls to these helpers in all the right places, we can fill them
in with hooks into reloc support.
I'll write more later on what the reloc support will be. For offset relocs
in ET_REL, they are always resolvable inside the file. For addresses the
idea is that it will do libdwfl for libdwfl-made Dwarf handles, old-fashioned
dwarf_formaddr et al will fail with "needs relocation", and new C++ reloc-savvy
interfaces will do something else.
Thanks,
Roland
14 years, 8 months
Re: <dwarf>: iteration over attributes swallows the last one
by Roland McGrath
I did a squash-commit of that. (So now you want to reset --hard your
branch instead of merge it, or remove it and refork later.)
But it crashed in tests. Now we do need that _m_attr initialization I told
you was superfluous in the begin () case--for the end () case not to be
uninitialized. (I did that, but with a proper initialization rather than
leaving the surely-won't-ever-be-touched fields garbage just in case.)
Thanks,
Roland
14 years, 8 months
<dwarf>: iteration over attributes swallows the last one
by Petr Machata
The scenario goes like this.
* end iterator has an offset of 1
* begin iterator has an offset of 0
* operator ++ does essentially the following:
_m_offset = ::dwarf_getattrs (&_m_die._m_die, &getattrs_callback,
(void *) this, _m_offset);
* operator == takes into account "parental" DIE and _m_offset
getattrs_callback is done such that it answers CB_OK when called the
first time (then it also initializes _m_attr.value), and CB_ABORT when
called the second time. This way dwarf_getattrs returns the position of
_next_ attribute in sequence. But that means that when the last
argument is loaded in _m_attr, _m_offset already has a value of 1, and
evaluates as equal to the end iterator.
As a fix for that, I propose to consider also NULL-ness of _m_attr.value
when doing the iterator comparison. On empty sequences, the callback is
never called, thus leaving _m_attr.value NULL. On sequence of one
element, _m_offset will end up being 1, but _m_attr.value will be
non-NULL. Only after the call to ++ will _m_attr.value become NULL, and
dwarf_getattrs, seeing offset of 1, will immediately return 1 again
without calling the callback. Etc.
Patch attached.
PM
From 3e9c7e605e666ef32d1dddd93f9d303ebd801e67 Mon Sep 17 00:00:00 2001
From: Petr Machata <pmachata(a)redhat.com>
Date: Tue, 24 Mar 2009 15:04:53 +0100
Subject: [PATCH] <dwarf>: Don't swallow last attribute
---
libdw/ChangeLog | 5 +++++
libdw/c++/dwarf | 11 ++++++++---
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index fc08176..d68075d 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2009-03-24 Petr Machata <pmachata(a)redhat.com>
+
+ * c++/dwarf (dwarf::debug_info_entry::raw_attributes):
+ Fix iteration over attributes.
+
2009-02-26 Roland McGrath <roland(a)redhat.com>
* c++/dwarf (dwarf::attr_value): Add _m_tag private member.
diff --git a/libdw/c++/dwarf b/libdw/c++/dwarf
index 862b9a1..33e7250 100644
--- a/libdw/c++/dwarf
+++ b/libdw/c++/dwarf
@@ -626,7 +626,10 @@ namespace elfutils
}
inline const_iterator (const debug_info_entry &die, ptrdiff_t offset)
- : _m_die (die), _m_offset (offset) {}
+ : _m_die (die), _m_offset (offset)
+ {
+ _m_attr.valp = NULL;
+ }
public:
inline const_iterator (const const_iterator &i)
@@ -643,7 +646,8 @@ namespace elfutils
inline bool operator== (const const_iterator &other) const
{
return (_m_die._m_die.addr == other._m_die._m_die.addr
- && _m_offset == other._m_offset);
+ && _m_offset == other._m_offset
+ && !_m_attr.valp == !other._m_attr.valp);
}
inline bool operator!= (const const_iterator &other) const
{
@@ -659,6 +663,7 @@ namespace elfutils
_m_offset = result;
return *this;
}
+
inline const_iterator operator++ (int) // postfix
{
const_iterator prev = *this;
@@ -668,7 +673,7 @@ namespace elfutils
inline attribute operator* () const
{
- if (unlikely (_m_offset == 1))
+ if (unlikely (_m_offset == 1 && _m_attr.valp == NULL))
throw std::runtime_error ("dereferencing end iterator");
return attribute (_m_die, _m_attr);
}
--
1.6.0.6
14 years, 8 months
tests/dwarf-print
by Roland McGrath
I added tests/dwarf-print for basic exercise of iterators and to_string.
Regression tests should be easy using this on some of our existing testfiles
to match expected output.
Thanks,
Roland
14 years, 8 months
Status 2009-03-23
by Petr Machata
= Work done last week:
* Time spent on elfutils: ~80%
* Mass testing. My debuginfo tree got somehow screwed up, and the
test failed on file-not-found errors quite often. Some files that were
supposed to be .debug.bz2 were plain .debug. Eventually got fed up with
having to manually compress fails and re-launch the test each time
around, and wrote a small script that found all such files and zipped them.
** In first round, I was focusing on catastrophic failures. The
test yielded two if I recall.
** In second round, I was actually looking at error messages.
At the beginning, almost literally all packages had failures. I
revisited each case that I found, and either confirmed that the file is
indeed buggy, or fixed dwarflint otherwise. Messages that were too
frequent ended up in exclusions file. I used that to grep -vf dwarflint
output.
** By friday afternoon, after fixing a handful of bugs, I had
dwarflint in a sort of stable point, where it didn't file thousands of
(bogus) failures per hour, so I let it run and went home. The test
eventually finished with "too many symlinks" error, and 31998 filed
failures.
= Work scheduled next:
* Expected time spent on elfutils: 80%.
* Finish mass testing.
* Roland, what's the next big item on our list?
PM
14 years, 8 months
[SPAM] Microsoft Customer Lists
by mike gordon
We are pleased to announce the availability of the following Microsoft customer lists:
Sharepoint
Dynamics
SQL
Exchange
Biztalk
FRX
CRM
System Center
Visual Studio
VAR
If you would like more information or a sample off any of our lists, please contact us at (905) 721-8456 or email us at repharm1(a)aol.com, Also we have the following lists as well
Below are just some of the lists available:
ERP (ENTERPRISE RESOURCE PLANNING):
Baan
JD Edwards
Lawson
Made2Manage
Mapics
Marcam
Oracle
Peoplesoft
SAP
SSA
E-BUSINESS APPLICATIONS:
Ariba
BMC
BroadVision
Commerce One
Webtrends
MIDDLEWARE/CONNECTIVITY/APP SERVERS/WEB SERVERS:
Bea Systems
Iona
Unisys
OPERATING SYSTEMS/HARDWARE/SOFTWARE:
COMPAQ
HP 3000
HP 9000
HP-UX
IBM AS/400
IBM OS/390
Lotus Notes
Microsoft
Sun Microsystems
DATABASE:
DB2
FileMaker
Informix
Oracle
SQL
SybaseCRM (CUSTOMER RELATIONSHIP MANAGEMENT):
Clarify
E.piphany
HNC
Onyx
Pivotal
Siebel
Vantive
Xchange
SUPPLY CHAIN:
Agile
i2 Technologies
Manugistics
QAD
Webplan
COMMUNICATIONS:
Nortel
Cisco
3com
Siemens
Alcatel
Telecom Vars
ASP’s
CLECS
ISP’s
E-COMMERCE:
Dot Com Directory
Consultant Directory
Software Directory
EXECUTIVE DIRECTORIES:
Chief Executive Officer
Chief Financial Officer
Chief Information Officer
Engineering
Human Resources
Purchasing
Sales/Marketing
INDUSTRY SPECIFIC LISTS:
Agriculture, Forestry and Fishing, Communications, Construction,
Finance, Insurance and Real Estate, Manufacturing, Mining, Public Administration,
Retail Trade, Services, Transportation,
Utilities, Wholesale Trade
14 years, 8 months
Help using elfutils to get function and line number
by Mihai Tarce
Hello,
I am writing an application which involves obtaining a backtrace, so I tried to find an easy way to get the backtrace for the running program. I used the glibc backtrace() function to get the return addresses from the stack. However, I need to convert those addresses into meaningful information (such as function name, file name and line number). I tried to use the addr2line code, but ran into problems when using dynamically loaded libraries, because the addresses (the one returned by backtrace(), and the actual address in the library -- the one returned by gdb, for instance) didn't match.
I also noticed that the libbfd documentation suggested libdwarf as a better solution for new programs, so I would like to use this library to get information from those addresses. I looked over libdwfl.h, and saw that it contains functions which could make my work easier. However, information about this library is pretty hard to find (at least for me), so I was hoping you could point me in the right direction. If you don't know of a tutorial either, could you please give some tips and starting points? I'd be happy to write a tutorial about what I've learned once I figure it out, which could then help other users.
Or maybe someone knows a better way to do this?
Thanks,
Mihai
14 years, 8 months
Status 2009-03-16
by Petr Machata
= Work done last _two_ weeks:
* Time spent on elfutils: ~40%
* Validate DW_AT_stmt_list and record references to .debug_line.
Check .debug_info->.debug_line references.
* Improve error messages and error message handling and filtering.
* Bugfixes
= Work scheduled next:
* Expected time spent on elfutils: 80%.
Right now, I'm running first mass-check swipe over dwarflint. This time
I completely ignore error messages, and only focus on discovering
catastrophic failures (SEGVs, assertion failures etc.). (Shell wrapper
that sends everything to dev null, and ignores exit status of 1.) This
already turned up two bugs. The plan is, obviously, to fix whatever
comes up.
When this passes, I'll focus on error messages themselves, that is
improving those that are not obvious, and getting rid of false positives.
This is the plan for next week.
PM
14 years, 8 months
Crash Feature to print dwarf debugging information
by Sharyathi Nagesh
Hi
I am working on a feature to provide crash tool an ability to print
function arguments. Currently the best way, architecture independent and
scalable, to implement the feature is through dwarf routines. I am
facing some challenges with the implementation and need your advice and
guidance to take it further from here.
I am facing challenges primarily in these 3 areas:
1. Design of the application:
Since I was not able to find a good documentation I was not able to
validate the code design. If some one can review and provide me guidance
it will help me immensely.
Challenges are
a. Efficient way of accessing the function/subprogram DIE (Debug
Information Entry) in an executable that contains multiple Complier
Units (CU)
b. Is the sequence of dwarf API calls appropriate
c. Scalability of the application, especially architecture dependency
I am attaching the code that I have developed please review it and let
me know if the design is appropriate. The code is not formatted but has
been written purely for understanding purpose.
2. Converting the address mentioned in DW_AT_location to actual address
of the local variable/arguments. System tap function
literal_stmt_for_local() has an implementation for this, I am going
thorough this some help in this direction will help me immensly.
3. Converting the address generated from DW_AT_location to actual
address in vmcore dump. I am assuming the address we get from the dwarf
tag will be a virtual address and that needs to be mapped to a location
at vmocre file. crash tool has a routine readmem(), I am currently
looking into it for probable solution.
Please let me know your thoughts and ideas on these and in general about
the implementation
Thanks
Yeehaw
14 years, 8 months
dwarflint: DW_AT_location being empty vs. missing check
by Jan Kratochvil
Hi,
a future FEAT, possibly to file it in some BZ?
http://dwarf.freestandards.org/Dwarf3.pdf 4.1.-4. (page 71/267) says about
DW_AT_location:
# In a variable entry representing the definition of a variable (that is, with
# no DW_AT_declaration attribute) if no location attribute is present, or if
# the location attribute is present but has a null description (as described
# in Section 2.6), the variable is assumed to exist in the source code but not
# in the executable program (but see number 10, below).
dwarflint could warn on existing zero-length DW_FORM_block* DW_AT_location for
DW_AT_variable with neither DW_AT_declaration nor DW_TAG_const_value. This
should mean the same as missing DW_AT_location - which has smaller DWARF code.
(GDB has a bug - it behaves differently to it as it _ignores_ variable with
DW_AT_location missing. It should consider it as _optimized-out_ as in the
case of the empty DW_FORM_block* of DW_AT_location).
Assuming for attributes like DW_AT_upper_bound the difference makes sense
- unbound array (missing DW_AT_upper_bound) vs. optimized-out bound of the
array (DW_AT_upper_bound with empty DW_FORM_block*).
Regards,
Jan
14 years, 9 months