www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Blog post about printing associative arrays from GDB

reply Johannes Riecken <johannes.riecken gmail.com> writes:
I've written a blog post about printing custom data structures 
from GDB using dlopen that I hope some of you find interesting 
and I'd also be happy to discuss it:

https://medium.com/dunnhumby-data-science-engineering/how-to-simplify-debugging-unit-tests-in-d-a2b52c5c1fa

Please let me know if there are any better ways to print data 
structures like associative arrays from GDB, maybe by using 
functions from the runtime library. Another exciting idea would 
be to automate the pretty printing, maybe also by looking how the 
pretty-printers for C++ in GDB 7+ are defined. I sadly haven't 
read much D code from outside our company; is there a Phobos 
function to automatically print expected and actual values for 
failed assertions? In our company we use ocean's test!("==").
Oct 23 2019
next sibling parent reply Dennis <dkorpel gmail.com> writes:
Thanks for spitting through the GDB manual so I don't have to!
I would've guessed something like this was possible with GDB, but 
never bothered until now.

On Wednesday, 23 October 2019 at 20:52:55 UTC, Johannes Riecken 
wrote:
 is there a Phobos function to automatically print expected and 
 actual values for failed assertions? In our company we use 
 ocean's test!("==").
Not a phobos function, a compiler switch. In recent LDC and DMD, you can use -checkaction=context and an attempt is made to print the actual values involved in the assertion. It is still young so you might still encounter bugs or limitations, but it does the job really well for most asserts.
Oct 23 2019
parent Johannes Riecken <johannes.riecken gmail.com> writes:
On Wednesday, 23 October 2019 at 21:07:24 UTC, Dennis wrote:
 Thanks for spitting through the GDB manual so I don't have to!
 I would've guessed something like this was possible with GDB, 
 but never bothered until now.

 On Wednesday, 23 October 2019 at 20:52:55 UTC, Johannes Riecken 
 wrote:
 is there a Phobos function to automatically print expected and 
 actual values for failed assertions? In our company we use 
 ocean's test!("==").
Not a phobos function, a compiler switch. In recent LDC and DMD, you can use -checkaction=context and an attempt is made to print the actual values involved in the assertion. It is still young so you might still encounter bugs or limitations, but it does the job really well for most asserts.
That looks promising. In the version I have installed (dmd 2.087.0) compilation crashes when using the flag and also stdio.writeln, but playing around with the newest version in run.dlang.io, it seems to work well with the cases I've tried, cool!
Oct 24 2019
prev sibling next sibling parent kinke <noone nowhere.com> writes:
Hi,

 Now wouldn’t it be even more useful if we knew why the unit 
 test failed? Apparently D doesn’t print that information 
 automatically on assertion failure, supposedly for performance 
 reasons.
Off-topic, but recent frontends feature a `--checkaction=context` switch, which for your example yields something like: onlineapp.d(5): [unittest] [3: 30, 2: 20, 1: 10] != [1: 10] 1/1 unittests FAILED https://run.dlang.io/is/XZy5PN
Oct 23 2019
prev sibling parent reply Mihails <none none.none> writes:
GDB has some dedicated functionality to improve pretty-printing 
and expression evaluation of things that too complex to figure 
out automatically:

- https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html
- 
https://sourceware.org/gdb/onlinedocs/gdb/Writing-an-Xmethod.html

GCC, for example, provides such scripts for improved debugging of 
C++ standard library as part of its distribution. Writing 
something similar for DMD/GDC/LDC shouldn't be too hard.
Oct 24 2019
parent reply Johannes Riecken <johannes.riecken gmail.com> writes:
On Thursday, 24 October 2019 at 11:20:07 UTC, Mihails wrote:
 GDB has some dedicated functionality to improve pretty-printing 
 and expression evaluation of things that too complex to figure 
 out automatically:

 - https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing.html
 - 
 https://sourceware.org/gdb/onlinedocs/gdb/Writing-an-Xmethod.html

 GCC, for example, provides such scripts for improved debugging 
 of C++ standard library as part of its distribution. Writing 
 something similar for DMD/GDC/LDC shouldn't be too hard.
GDB uses internal functions of C++'s runtime to do the pretty-printing for C++. Implementing that for D's runtime library in its current form would seem like a considerable effort to me, since D's runtime library seems to be a bit hairier with respect to the internal fields, no?
Oct 24 2019
parent reply Mihails <none none.none> writes:
On Thursday, 24 October 2019 at 13:16:39 UTC, Johannes Riecken 
wrote:
 GDB uses internal functions of C++'s runtime to do the 
 pretty-printing for C++. Implementing that for D's runtime 
 library in its current form would seem like a considerable 
 effort to me, since D's runtime library seems to be a bit 
 hairier with respect to the internal fields, no?
That wouldn't be a considerable effort on its own (I think all necessary machinery is already part of druntime.rt package) but right now you would need to have druntime built with debugging symbols to get anything done. For C++ standard containers it is not a problem because those are defined in header files. If AA implementation was switched to templates, it would "just work" for druntime too.
Oct 24 2019
parent reply Johannes Riecken <johannes.riecken gmail.com> writes:
On Thursday, 24 October 2019 at 14:20:42 UTC, Mihails wrote:
 On Thursday, 24 October 2019 at 13:16:39 UTC, Johannes Riecken 
 wrote:
 GDB uses internal functions of C++'s runtime to do the 
 pretty-printing for C++. Implementing that for D's runtime 
 library in its current form would seem like a considerable 
 effort to me, since D's runtime library seems to be a bit 
 hairier with respect to the internal fields, no?
That wouldn't be a considerable effort on its own (I think all necessary machinery is already part of druntime.rt package) but right now you would need to have druntime built with debugging symbols to get anything done. For C++ standard containers it is not a problem because those are defined in header files. If AA implementation was switched to templates, it would "just work" for druntime too.
Cool, if you (or someone else) can give me the fields or functions in the druntime.rt package that can be used to print associative arrays from GDB, then I can try my hand at building a pretty-printer using GDB's Python API next week.
Oct 24 2019
parent reply Mihails <none none.none> writes:
 Cool, if you (or someone else) can give me the fields or 
 functions in the druntime.rt package that can be used to print 
 associative arrays from GDB, then I can try my hand at building 
 a pretty-printer using GDB's Python API next week.
AA implementation is provided by https://github.com/dlang/druntime/blob/master/src/rt/aaA.d, and you can either try reimplementing key logic in Python (more work but cleaner impl) or just call relevant functions via gdb python api and parse results. It should actually be possible to call functions like __aaGetX even with release build of druntime, you just to do a manual cast to the correct function type from a raw pointer.
Oct 25 2019
parent reply Johannes Riecken <johannes.riecken gmail.com> writes:
I created an initial version and would be glad to get some 
feedback. I couldn't figure out how to call the _AAGetX-style 
functions, so I just went with the approach in my blog post to 
get something working that can be refactored later.

Here is the code. It currently works with gdc, but not with dmd, 
because dmd calls the type like _AArray_int_int, not int[int]. 
Also note that it creates (or overwrites) two files in the 
directory, libhelpers.so and helpers.d:

https://github.com/johannes-riecken-dunnhumby/pretty

I kept the generated files in there to ease experimentation 
(which I would take out later) and still it's very little code. 
To get it working I had to add the directory containing the code 
to my .gdbinit with `add-auto-load-safe-path ~/workspace/pretty`
gdb can auto-load python files related to an executable if they 
are named as <executable_name>-gdb.py, so I did that for my 
example executable foo (which i create with `gdc-9 -g -o foo 
foo.d`. To check if my code works I used the command

     PYTHONPATH=. gdb ./foo -ex 'b 3' -ex run -ex 'p dict'

For troubleshooting, check the output of `info pretty-printer` in 
gdb.
Support for custom structs should be easy enough to add, but I 
need to work now. Cheers!
Nov 12 2019
parent Johannes Riecken <johannes.riecken gmail.com> writes:
I'd also be very interested in how to get this working with dmd.
Nov 12 2019