Skip to content
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

Add a GDB pretty printer to aid in debugging #91280

Merged
merged 1 commit into from
May 11, 2024

Conversation

Mitten-O
Copy link
Contributor

@Mitten-O Mitten-O commented Apr 28, 2024

The GDB debugger supports pretty-printing of a project's custom types using a python script.
This PR adds a GDB pretty-printer script that can pretty-print Godot's String, StringName and Vector.
This significantly increses the readability, especially of the two latter objects, as the payload is deep in them.

Before:

gdb bin/godot.linuxbsd.editor.dev.x86_64
(gdb) break gdscript.cpp:1079
(gdb) set args --test --test-suite="*GDScript*"
(gdb) run
...
(gdb) print sourcef
$1 = {write = {<No data fields>}, _cowdata = {static MAX_INT = <optimized out>, static REF_COUNT_OFFSET = <optimized out>, static SIZE_OFFSET = <optimized out>, 
    static DATA_OFFSET = <optimized out>, _ptr = 0x5555624edd40 "const dictionary := {0: [0]}\n\nfunc test():\n\tvar array := dictionary[0]\n\tvar key: int = 0\n\tarray[key] = 0\n"}}
(gdb) print p_path
$2 = (const String &) @0x7fffffffcf60: {_cowdata = {static MAX_INT = <optimized out>, static REF_COUNT_OFFSET = <optimized out>, static SIZE_OFFSET = <optimized out>, 
    static DATA_OFFSET = <optimized out>, _ptr = 0x555562365f50 U"/mnt/SSD-General2/projects/godot/godot/modules/gdscript/tests/scripts/runtime/errors/constant_dictionary_is_deep.gd"}, 
  static _null = 0 U'\000', static _replacement_char = 65533 U'�'}

After:

(gdb) source misc/scripts/godot_gdb_pretty_print.py
(gdb) print sourcef
$3 = Vector<unsigned char> [106] = {99 'c', 111 'o', 110 'n', 115 's', 116 't', 32 ' ', 100 'd', 105 'i', 99 'c', 116 't', 105 'i', 111 'o', 110 'n', 97 'a', 114 'r', 121 'y', 32 ' ', 58 ':', 
  61 '=', 32 ' ', 123 '{', 48 '0', 58 ':', 32 ' ', 91 '[', 48 '0', 93 ']', 125 '}', 10 '\n', 10 '\n', 102 'f', 117 'u', 110 'n', 99 'c', 32 ' ', 116 't', 101 'e', 115 's', 116 't', 40 '(', 
  41 ')', 58 ':', 10 '\n', 9 '\t', 118 'v', 97 'a', 114 'r', 32 ' ', 97 'a', 114 'r', 114 'r', 97 'a', 121 'y', 32 ' ', 58 ':', 61 '=', 32 ' ', 100 'd', 105 'i', 99 'c', 116 't', 105 'i', 
  111 'o', 110 'n', 97 'a', 114 'r', 121 'y', 91 '[', 48 '0', 93 ']', 10 '\n', 9 '\t', 118 'v', 97 'a', 114 'r', 32 ' ', 107 'k', 101 'e', 121 'y', 58 ':', 32 ' ', 105 'i', 110 'n', 116 't', 
  32 ' ', 61 '=', 32 ' ', 48 '0', 10 '\n', 9 '\t', 97 'a', 114 'r', 114 'r', 97 'a', 121 'y', 91 '[', 107 'k', 101 'e', 121 'y', 93 ']', 32 ' ', 61 '=', 32 ' ', 48 '0', 10 '\n', 0 '\000'}
(gdb) print p_path
$4 = (const String &) @0x7fffffffcf60: U"/mnt/SSD-General2/projects/godot/godot/modules/gdscript/tests/scripts/runtime/errors/constant_dictionary_is_deep.gd"

You can enable the pretty printer by default in VS code by adding this to your configuration in launch.json:

"setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "Load custom pretty-printers for Godot types.",
                    "text": "source ${workspaceRoot}/misc/scripts/godot_gdb_pretty_print.py"
                }
]

Vector<StringName> in VS code without this:
vs_code_debug_godot_vector_string_name_before

Vector<StringName> in VS code with this:
vs_code_debug_godot_vector_string_name_after

GDB supports some ways of loading the pretty printer automatically, but all of the would require adding the source of
the script to the safe autoload path. If the user needs to do configuration anyway, best to let them specify the loading of pretty printing explicitly, instead of making them enable magic that does the loading implicitly.

@Mitten-O Mitten-O requested a review from a team as a code owner April 28, 2024 15:34
@Calinou Calinou added this to the 4.x milestone Apr 28, 2024
@@ -0,0 +1,109 @@
# Load this file to your GDB session to enable pretty-printing
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add shebang (and make file executable with chmod +x):

Suggested change
# Load this file to your GDB session to enable pretty-printing
#!/usr/bin/env python3
#
# Load this file to your GDB session to enable pretty-printing

Also, remember to format the file with black -l120 path/to/file.py (it's what we use for other scripts in the repository). I also suggest running isort path/to/file.py.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@Mitten-O Mitten-O force-pushed the topic/gdb-pretty-printer branch 2 times, most recently from 7fc39b9 to b251efe Compare May 4, 2024 16:09
@AThousandShips
Copy link
Member

Your commit seems not to be linked to your GitHub account. See: Why are my commits linked to the wrong user? for more info.

@Mitten-O Mitten-O force-pushed the topic/gdb-pretty-printer branch from b251efe to 00c70d1 Compare May 4, 2024 16:33
@Mitten-O
Copy link
Contributor Author

Mitten-O commented May 4, 2024

Your commit seems not to be linked to your GitHub account. See: Why are my commits linked to the wrong user? for more info.

The email in the commits had different capitalization than in my profile. They still appeared as linked to me, but regardless, I updated the capitalizations to match. Thanks for the heads up!

@AThousandShips
Copy link
Member

AThousandShips commented May 4, 2024

Still not linked, are you sure that email address is used for this account? As you can see the commits don't have your profile picture

My bad the icon was just scaled and invisible

@akien-mga
Copy link
Member

Thanks for the contribution, this is really great! I've spent countless time trying to print Strings and StringNames in gdb and figuring out where's a hint of what the actual human-readable string is.

For your Vector printing example, it does make sense to me, but I notice that we're losing some convenience where gdb used to actually print the _ptr as a readable string:

_ptr = 0x5555624edd40 "const dictionary := {0: [0]}\n\nfunc test():\n\tvar array := dictionary[0]\n\tvar key: int = 0\n\tarray[key] = 0\n"

Not sure why, and that's probably only applicable for Vector<unsigned char>, so I don't know if we can (or should) preserve some of that behavior?


Could you also squash the commits? See PR workflow for instructions.

Copy link
Member

@akien-mga akien-mga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested with command line gdb, works great!

@akien-mga akien-mga modified the milestones: 4.x, 4.3 May 6, 2024
@akien-mga akien-mga added the cherrypick:4.2 Considered for cherry-picking into a future 4.2.x release label May 6, 2024
@Calinou
Copy link
Member

Calinou commented May 6, 2024

Remember to open a PR to document this on https://github.com/godotengine/godot-docs/blob/master/contributing/development/configuring_an_ide/visual_studio_code.rst 🙂

@Mitten-O
Copy link
Contributor Author

Mitten-O commented May 7, 2024

GDB supports custom pretty-printers implemented in Python.
When debugging Godot, checking the values of Strings and StringNames
in the debugger was very inconvenient as the data is fairly deep
in the structure. This makes the values immediately visible.

The custom pretty printer can be taken into use manually by calling
`source misc/scripts/godot_gdb_pretty_print.py` in the GDB console.
In VS code, it can be activated by default by adding the source
command to the `setupCommands` of the configuration in launch.json.

Like this:
```json
// launch.json
{
    "configurations": [
        {
            "name": "C/C++: debug,
            "type": "cppdbg",
	    ...
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "Load custom pretty-printers for Godot types.",
                    "text": "source ${workspaceRoot}/misc/scripts/godot_gdb_pretty_print.py"
                }
            ],
            "miDebuggerPath": "gdb"
        }
    ],
    "version": "2.0.0"
}
```

Extended the pretty-printer python script to support Vectors.
The printer needs to be uncomfortably aware of CowData
implementation details, but I don't think there is any
way around that.
@akien-mga akien-mga force-pushed the topic/gdb-pretty-printer branch from 00c70d1 to 829c33a Compare May 11, 2024 10:34
@akien-mga akien-mga merged commit eff0600 into godotengine:master May 11, 2024
15 checks passed
@akien-mga
Copy link
Member

Thanks! And congrats for your first merged Godot contribution 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cherrypick:4.2 Considered for cherry-picking into a future 4.2.x release enhancement topic:buildsystem
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants