-
-
Notifications
You must be signed in to change notification settings - Fork 6.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GDB pretty printing support #1952
Comments
O.M.G., thank you!!! (btw, I notice that in CLion it seems to include a bolded \n after each would-be line that gets pretty-printed... my python-fu is weak and I don't know how to eliminate the newlines from the Python's output?) |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
You are very welcome! :) |
Hi @aaaaaaaaargh! Sorry for not checking back sooner. I tried to use the approach you described, but it seems my gdb knowledge is not sufficient. What I tried:
Then I run gdb:
Any idea how to make this work? |
Hi Niels, I think you need to do a couple of things. Below is a copypasta of my very own .gdbinit, I hope this will help you get things running :)
|
Thanks for the quick response! I am still struggling though. Is there some kind of beginner's guide? What I tried:
# Pretty printing support for nlohmann::basic_json objects.
import gdb.printing
class NlohmannJsonPrinter(object):
"Print a json"
def __init__(self, val):
self.val = val
def to_string(self):
eval_string = "(*("+str(self.val.type)+"*)("+str(self.val.address)+")).dump(2, ' ', false, nlohmann::detail::error_handler_t::strict).c_str()"
result = gdb.parse_and_eval(eval_string)
return result.string()
def display_hint(self):
return 'JSON'
def build_pretty_printer():
pp = gdb.printing.RegexpCollectionPrettyPrinter(
"nlohmann::basic_json")
pp.add_printer('JSON', '^nlohmann::basic_json<.*>$', NlohmannJsonPrinter)
return pp
def register_json_printer():
gdb.printing.register_pretty_printer(
gdb.current_objfile(),
build_pretty_printer()) Yet I now get the following error in gdb:
|
Huh.. that looks really strange. Can you please show the main method you use for testing? I'm afraid as with GDB related things there isn't a ton of documentation about this. I did learn about this by a bit by looking at the Unreal Engine pretty printer and the ones shipped with GCC. But I'm sure we can find a way to solve this. |
Also please let me know what compiler you are using and whether you have any kind of optimization enabled (-O flags in GCC). |
The only difference I see between your gdbinit and mine (for the pretty printing) is that I also register the stdc++ library pretty printers. Otherwise mine is working fine using gdb 8.2.1 and gcc 8.3 (although I do build those tools locally and there are more than a few available build config options on them). |
Sure: main.cpp #include "json.hpp"
using json = nlohmann::json;
int main()
{
json j = 1;
j["foo"] = 2;
} Compiled with
|
Thank you for sharing so quickly. Luckily this one was not too hard to track down. The reason this is not working is simply because For reference, I changed your main.cpp to look like this and it worked:
|
Same error:
|
Hi, I gave a shot to this a while a go on SO, see https://stackoverflow.com/questions/55316620/c-debug-print-custom-type-with-gdb-the-case-of-nlohmann-json-library I ended up defining a simple gdb macro that calls the dump(). I'm currently working on a 100% python printer, but that is a huge task (coding a RB-tree-stl-map memory explorer in python blindly iterating with gdb tests is just a pain ... and I'm not aware yet if what I do will allow to use a core dump or be better than the dump() call in any way... but since I'm locked at home, I'll play around a bit). I basically managed to print simple data (i.e. using the Ada-like variant record definition |
For what its worth, I finally got something not requiring the call to the dump() method using a python gdb script. See the SO post for details. There are lots of things that could be improved, but that's a first step. I did not print the memory addresses of each field, since I focused on the JSON readable stuff, but we can definitly improve prints to include the addresses of the objects (I suspec that it is what #1554 was refereing to) standalone github repo https://github.com/LoneWanderer-GH/nlohmann-json-gdb |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Niels, sorry for not answering before, I was pretty busy with other stuff. |
I've made a simple json pretty printer that just reuses the libstdc++ pretty printers for std::string/vector/map (obviously they have to be available in gdb already). |
@ssbssa Thanks for reporting. I would love to include such a pretty printer in the library, but I always failed to use it, let alone describe how to use it. Could you please add a small step-by-step description how to use the pretty printer when debugging a program with gdb? |
Simplest way is to source the py file in your |
@ssbssa Sorry, but I still can't get it to work. I'm using Ubuntu. Here is what I tried:
#include "single_include/nlohmann/json.hpp"
int main()
{
nlohmann::json j;
j["foo"] = 1;
std::string s = j["foo"];
}
This is my output:
What do I do wrong? |
Now it works. Maybe I messed up something in between. Thanks so much! Would it be OK to add the pretty-printer to this repo? It would be MIT licensed, but I would of course mention your name in the README. |
Yes, that's fine. |
@ssbssa I would be glad if you could provide any feedback concerning my solution. I tried to make it STL-gdb-scripts independent. It is very different from the merged gist, but since it seems you reused some of the C++ code samples I guess you had a look at it (the "Jean-Baptiste Emmanuel Zorg" part is pretty much my signature, taken from Fifth Element movie :) and in my 2019 stackoverflow post). And since you seem to be pretty active in the GDB community, I would appreciate any feedback : it was the first time I digged into serious GDB stuff, and had no feedback yet. |
@LoneWanderer-GH Yes, I used your json example code, since it showed all json types. As for your pretty printer, since your goal was to make the output look the same as the dump() function, it's doing its job nicely. |
Should I reopen the issue? Anything left to do here? |
I've tried GDB printer from here and it only worked for me when I replaced this line: if re.search("^nlohmann::basic_json<.*>$", val.type.strip_typedefs().name): with this: if re.search("^nlohmann::basic_json<.*>$", str(val.type.strip_typedefs().name)): Otherwise GDB (9.2) has said this to me:
|
@eliasdaler Would you mind opening a PR for that change? |
Sure, I'll do it soon. |
I had this error too on Fedora 33, GCC 10.2 (and GDB 10.2) |
Hi @aaaaaaaaargh! Thank you for posting this code, this makes debugging so much easier than dropping dumps everywhere. I did want to ask if this works for VSCode, or if I messed something up along the way. For reference, I'm on Windows 10 OS, and I have the gdb environment HOME set to C:\Users\jason, where I put the .gdbinit file. I then appended the path all the way back to my working directory, where I have the python script (I used backslash instead of forward slash for the filepath just for sake of Windows). Unfortunately, in VSCode's gdb debugger, I cannot get the json objects to report anything other than m_value, which contains the addresses of each type. I would greatly appreciate any guidance on this! In the meantime, I'm going to go back to dropping dumps. |
@jasonabuzzell You can source your Also, reminder to myself: Fix the GDB pretty printer in #3590. For anyone else finding this thread: Please use the pretty printer from here as the code posted in this thread won't work with 3.11.0+. |
Thank you for the quick response, @falbrechtskirchinger! This does help clear up a lot. I added "text": "source ${workspaceFolder/.gdbinit" to "setupCommands" in launch.json, and I think it is now finding .gdbinit. If you don't mind me following up, I am seeing this though now, and I think it's not understanding that it's looking at a python file:
And also this: This may be unrelated, but I did add the execution line Also, let me know if I should jump into a different thread for this, thank you! |
You need to source your Python file from Check the |
Ah sorry, I forgot to mention that! I added simply |
Hm. I'm not sure. I'll be working on the pretty printer code soon and will have to set it up in VSCode as well. Maybe I can help you then. |
Sounds good, no rush! I'll keep an eye on this thread. |
You don't actually need the local The
This indicates that GDB is not recognizing the sourced file as a Python script or has been built without Python support. The file should have a You mentioned you added I don't know where you get your GDB executable from. I assume it's automatically downloaded by the |
Hello, I've being trying the example but I think for my knowledge i'm missing something.
I'm using eclipse for c/c++ for developing and I have just placed the json.hpp file in the source directory of my eclipse project. |
Hi. I am using Clion as my main IDE for writing C++. All running configurations are adopted to be working on WSL. So I've added the /home/<user_name>/.gdbinit file with a source command to start the script. When I run one of my tests within Debug mode I can see that gdb actually tries to run the script but I am getting the following error:
Will be appreaciate to get any idea about that error. If there is need to bring more information just let me know. Thanks :) |
Looks like this was broken by bbe337c, since it moved both |
Thanks for replying. After reviewing your response, I have come to the realization that I do not have enough knowledge to fix the issue myself. Based on your feedback, it seems like the bug is reasonably fixable or at least reportable. Will appreciate any advice on it or at least to create a detailed report of the issue, including any relevant information that may help in resolving it. |
Replace |
Debugging JSON objects with GDB is very tedious and in some cases (e.g. from within CLion) not even possible due to the complexity of the type. I've created a small pretty printer that takes care of this issue by utilising the libraries
.dump()
method.I hope some of you may find that useful. Feel free to use this any way you like, including incorporation in the library codebase :)
How to use:
~/Dev/.gdb
..gdbinit
system paths, import and register the printer as usual:Have fun!
The text was updated successfully, but these errors were encountered: