Metadata-Version: 2.1
Name: gdb2dict
Version: 1.0.0
Summary: A converter from GDB values to python dict
Author-email: Zakaria FADLI <zakaria1193@gmail.com>
Maintainer-email: Zakaria FADLI <zakaria1193@gmail.com>
License: Copyright (c) 2016 The Python Packaging Authority (PyPA)
        
        Permission is hereby granted, free of charge, to any person obtaining a copy of
        this software and associated documentation files (the "Software"), to deal in
        the Software without restriction, including without limitation the rights to
        use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
        of the Software, and to permit persons to whom the Software is furnished to do
        so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/zakaria1193/gdb2dict
Project-URL: Bug Reports, https://github.com/zakaria1193/gdb2dict/issues
Project-URL: Funding, https://donate.pypi.org
Project-URL: Say Thanks!, http://saythanks.io/to/example
Project-URL: Source, https://github.com/zakaria1193/gdb2dict
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Build Tools
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Provides-Extra: dev
Requires-Dist: check-manifest; extra == "dev"
Provides-Extra: test
Requires-Dist: coverage; extra == "test"

# GDB.value to python dict converter

This tool extends GDB python scripting capabilities.

gdb (GNU Debugger) use a specific format to print C/C++ programs data, this format is not easy to parse, so this tool converts the output of gdb to python dictionaries.

So it can also be used to serialize C data structures to JSON objects, or to any other format.

Example of conversion:

If you have a structure like this in you C code:

```c
struct Shape {
    int id;
    enum {
        RED,
        GREEN,
        BLUE
    } color;
    union {
        int intValue;
        float floatValue;
    }; // unnamed union (C11)
    struct {
        int x;
        int y;
    } center;
    union {
        int intValue;
        float floatValue;
    } data;
};
```

When you print an instance of this struct in python gdb script (or in the classic gdb console),
both will give this printable string that is not a native python object

```gdb
(gdb) p my_struct
OR
(gdb) python print(gdb.parse_and_eval("my_struct"))
{
  id = 0x1,
  color = RED,
  {
    intValue = 0x2a,
    floatValue = 5.88545355e-44
  },
  center = {
    x = 0x1e,
    y = 0x28
  },
  data = {
    intValue = 0x6c6c6548,
    floatValue = 1.14313912e+27,
  }
}
```

gdb2dict lets convert the output of gdb to a python dictionary.

```python
import gdb2dict
```

Simply call the function `gdb_value_to_dict` with the value to convert,
and it will return a python dictionary.

```python
> output_dict = gdb2dict.gdb_value_to_dict(gdb.parse_and_eval("my_struct"))

output_dict =
{
    'id': '0x1',
    'color': 'RED',
    '::unnamed_field_1::union':
    {
        'floatValue': '5.88545355e-44',
        'intValue': '0x2a'
    },
    'center::struct': {'x': '0x1e', 'y': '0x28'},
    'data::union':
    {
        'floatValue': '1.14313912e+27',
        'intValue': '0x6c6c6548'
    },
}

```

### Metatada

As you can see some field names (keys after conversion) have added metadata **::struct**, **::union**
That's needed to differentiate between fields that are structs and fields that are unions.

Another metadata can be added to the keys, it's **::unnamed_field_1::struct**,
**::unnamed_field_2::union** etc...

That's to cover for [ C11's unnanmed fields ](https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html)
that can be sub-structs or sub-unions without a name.

## Use cases

Imagine you are trying to automatize the debugging of a measuring, and you want to parse the output of a measure function that returns a structure, you can use this tool to convert the output of gdb to a JSON format,
you can do that manually by reading field by and field and making your own python dictionary, but this tool does that for you.

It comes handy when you have a lot of structures and unions to parse, and you don't want to write a lot of code to parse them, since gdb already knows how to parse them.

The printer can be used in your custom breakpoints, or your custom commands, or in your custom pretty printers.

If you don't know how to make those, refer to the [GDB documentation](https://sourceware.org/gdb/onlinedocs/gdb/Python-API.html#Python-API).

Or this article from [Memfault](https://interrupt.memfault.com/blog/automate-debugging-with-gdb-python-api)

## Usage example: Parse TLV data from breakpoint and write to file

Let's use it in a python scripted gdb breakpoint handler.
The idea is catch the functions that identifies the TLV type and value,
then cast to a structure and write to a file in JSON format.

```python my_script.py

import gdb2dict

OUTPUT_LIST = []

class MyCustomBreakpoint(gdb.Breakpoint):
    def stop(self):
        # Access arguments
        arg1_payload = gdb.parse_and_eval("arg1_payload")
        arg2_payload_type = gdb.parse_and_eval("arg2_paytload_type")
        arg3_payload_size = gdb.parse_and_eval("arg3_payload_size") # Not needed here

        # Convert the payload type to a structure using some custom mapping function
        type_to_cast = my_custom_payload_type_to_struct(arg2_payload_type)

        # Cast to a structure pointer
        arg1_payload = arg1_payload.cast(type_to_cast)

        OUTPUT_LIST.append(gdb2dict.gdb_value_to_dict(arg1_payload))

        # Return False to not halt (Automatically continue)
        return False

with open("output.json", "w") as f:
    f.write("{\"output\": [\n")
    f.write(",\n".join(OUTPUT_LIST))
    f.write("]}")

```

Source this script in gdb will set the breakpoint and fill the output file with the parsed values.

```bash
$ gdb -x my_script.py --batch --nw --nx --return-child-result
```

`--batch --nw --nx --return-child-result` are recommended for automated gdb scripting,
see `gdb --help` for more information.

Then you can post process the output file with your favorite language.
