|
Boost : |
Subject: Re: [boost] Interest check: Boost.Debug
From: Zachary Turner (divisortheory_at_[hidden])
Date: 2009-06-02 18:14:04
On Tue, Jun 2, 2009 at 4:47 PM, Christian Holmquist
<c.holmquist_at_[hidden]>wrote:
> >
> > - Loading debug info either for the currently running executable or from
> an
> > offline executable
>
>
>
> Care to elaborate a bit, I don't follow exactly. How is this useful
> compared
> to attaching a debugger?
It's not that uncommon that one would be running a debug build of something
in an environment that doesn't have a debugger. Or perhaps a customer is
using a release build and you don't want to give them private symbols, but
you don't mind giving them public symbols. They can generate a useful stack
trace this way for you. (How to output this without integrating logging
facilities is, as you mention, something that would need to be worked out).
The reason that I originally thought of this entire debugging library is
actually because I thought it would be useful to add my own memory leak
detection facilities a program I was writing, because I was tracing a
difficult memory leak. (oh yea, might as well add memory corruption / leak
detection to the list of cool things that would be possible with a library
such as this). In Windows they have some CRT debugging functions that
enable this sort of thing inside the CRT, but they do this by #define'ing
new and delete to functions such as debug_new and debug_delete, this way
with #defines they can use __FILE__, __LINE__, etc to track the location of
allocations. It's preferable to overload operator new and delete instead,
this way you solve a lot of problems with order of #includes, but if you
overload operator new and delete you can't use the __FILE__ and __LINE__
macros or they will just refer to the source file / line number of the
implementation of the overloaded operators. With a structured stack trace
representation, you could simply move up 1 frame and get source / line
information from inside the operators, ultimately allowing advanced memory
leak / integrity checking via overloaded operators while still maintaining
accurate source / line information. When the process exits, you could dump
all detected memory leaks along with their entire stack traces, or if a
double delete was detected you could dump an entire stack trace for where it
was allocated.
This was the original use case I had in mind, I thought of the first case
(with private / public symbols) later. It also might be useful in a Q/A
environment where if they detect a program crash they can give you a stack
traec (although if the library is able to generate stack traces, even if
only through the unhandled_exception handler, in release mode that might be
sufficient to cover some of these other cases).
>
> > - Printing human readable stack traces from a running program
>
> IMO getting a stack-trace really quick, and defer the print-out (using the
> dbghelp on windows for instance) until the user requests it would be more
> useful than printout only. Like:
FWIW DbgHelp library turned out to be grossly insufficient for what I
needed, so my library is now using the DIA SDK. Which unfortunately relies
on COM, but I don't think that should be too much of a problem.
>
> > - Assuming symbol information is loaded either for the running program or
> > an
> > offline program, format a block of memory in a human readable format to
> > print the structure of the memory (for example, display member values of
> a
> > class with field names, given a block of memory representing an instance
> of
> > the class)
>
>
> Care to provide an example here?
The easiest example to understand here is that you're actually using this
library to _implement_ your own debugger. You have debug information for
the debugee because it was generated by your compiler, your process is the
debugger, you want to display the value of a symbol in the watch window.
You know that the virtual address of the symbol is 0x12345678. You look it
up in the symbol table and find that that the symbol at this location is of
type:
class foo
{
int a;
double d;
};
clearly sizeof(foo) == 12, so the above would be able to take the address
0x12345678, interpret the first 4 bytes as a signed integer, the last 8
bytes as a double precision floating point, and return those values to the
caller to display in a watch window. The best way to get this information
back to the caller is open for discussion. I was thinking it would just be
a simple string pre-formatted according to some rules of the library, but
it's not hard to imagine other possibilities. For example, a
"symbol_field_iterator" that returned objects which you could call
to_string() on, or value_as<T> so you could get the actual data in the
correct type.
> >
> > - launch process under a debugger and receive basic types of debugging
> > notifications.
> >
>
> What kind of notifications are you referring to?
The types needed in order to implement a debugger. module was loaded into
the process, thread was just created, exception just occurred, etc. I've no
idea how debuggers are implemented under Linux, but in windows there's a
debug api that provides these events very easily. I'm sure there's
something similar under Linux, even if it's difficult, because GDB does some
fairly advanced things.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk