epasveer / seer

Seer - a gui frontend to gdb
GNU General Public License v3.0
2.11k stars 67 forks source link

Ada System.Address type does not work with the visualizers #134

Closed henrikglass closed 1 year ago

henrikglass commented 1 year ago

I'm debugging a program in Ada, and I noticed that the visualizers don't work with Ada's built in System.Address type. If I add a variable foo_addr of type System.Address to the memory visualizer i get the message "not an address". I tried the image visualizer and got the same message - presumably this issue affects all visualizers. If I add foo_addr to the logger/tracker it's value shows up as (System.Address) <the address>. If I enter <the address> manually into the "starting address" field of a visualizer I get the result I expect.

epasveer commented 1 year ago

Hi Henrik,

Thanks for trying Seer out. I'm no expert with Ada. I know gdb has a whole section dedicated to supporting Ada.

Perhaps you can give me a simple Ada program that has a list of values. I can then attempt to compile it and use it to make Seer more Ada capable. If native gdb can support it, then Seer should too.

Thanks.

epasveer commented 1 year ago

Actually, can you include a screenshot of how the visualizer looks when you see the "not an address" message?

Sometimes, you need to prefix the variable name with a "&" or a "*", depending on the language.

epasveer commented 1 year ago

To be more specific, The variable name should equate to an address. So in the C++ code shown here, "float_array" is a pointer. Which easily equates to "0x414e40". The "64" and "float32" specify the underlying datatype and array size.

image

I'm curious what you enter instead of "float_array". Whatever that is, Seer gives it to gdb to resolve. If the return value from gdb is in the form of "0x....", then Seer is happy. It can then get the contents of memory that is being pointed to.

So a screenshot of what text you're putting in as the name of the variable will help me.

epasveer commented 1 year ago

it's value shows up as (System.Address)

What is a real-life example of ""? Is it in the form of "0x.....".

So my example above may be?

(System.Address) <0x414e40>

If so, I think I can get the visualizers to easily accept that.

henrikglass commented 1 year ago

Yes, sorry, I should've made that part more clear. It evaluates to (System.Address) 0x7ffff5a77010, e.g., no angle brackets.

To be honest, I'm not very familiar with Ada myself, but I'll see if I can put together an example. It has a very strong typesystem, and there are a few ways to represent what is effectively a pointer, so (System.Address) 0x7ffff5a77010 might not be the only case.

epasveer commented 1 year ago

Thanks for the example. It helps.

I think I can make it be more generic by doing a regex on the string that gdb returns. To extract a '0x.....' address from it.

I agree, there are likely other Ada related cases. I'll tackle them as people report them.

I'll get a fix out shortly.

henrikglass commented 1 year ago

Here's an example with different address/pointer/access types (there might be more, who knows):

with Text_IO; use Text_IO;
with System;
with System.Address_Image;
with System.Address_To_Access_Conversions;

procedure Example is

    -- a type describing a float array of length 256.
    type Float_Array_T is array(0..255) of Float;

    -- an "access type" for the above type.
    type Float_Array_Access_T is access all Float_Array_T;

    -- idek...
    package Conversions is new System.Address_To_Access_Conversions(Float_Array_T);
    use Conversions;

    -- some variables.
    My_Float_Array         : aliased Float_Array_T;
    My_Float_Array_Address : System.address;
    My_Float_Array_Access  : Float_Array_Access_T;
    My_Float_Array_Obj_Ptr : Conversions.Object_Pointer;
begin
    -- Fill My_Float_Array with data
    for i in 0 .. 64 loop
        My_Float_Array(i) := 1.3 * Float(i);
    end loop;

    My_Float_Array_Address := My_Float_Array'Address;
    My_Float_Array_Access  := My_Float_Array'Access;
    My_Float_Array_Obj_Ptr := Conversions.To_Pointer(My_Float_Array_Address);

    Put_Line(System.Address_Image(My_Float_Array_Address));
    Put_Line(Float'Image(My_Float_Array(3)));
end Example;

I put this into a file example.adb and built it with gnatmake -g -O0 example.adb. Curiously, the System.Address case seems to be the only variant acting up, the other variants in my example work fine. I put a breakpoint on the last Put_Line:

var_logger

Off-topic suggestion: Add a formatting option for values in the tracker and logger (Auto, Hex, octal, decimal, etc.). It's literally the only thing I'm missing (and perhaps the ability to send sigint with Ctrl-C). Other than that I'm super happy to finally have a sane gdb frontend that just works and isn't ddd.

epasveer commented 1 year ago

Awesome. Thanks!

The example program, and the screenshot of the Logger, helps me better understand how gdb handles Ada.

I'm not sure about Auto, Hex, Decimal in the Logger/Tracker. I'll see if gdb can help out here.

The Ctrl-C should be easy to add.

Thanks for the suggestions!

epasveer commented 1 year ago

Hi Henrik,

I've fixed Seer up to handle Ada's "System.Address" type. You can grab the latest snapshot.

Below is the Array Visualizer. It handles "My_Float_Array_Address" correctly now. To handle "My_Float_Array", just prefix the variable name with a "&". You can see they both resolve to the same memory address. (There are 2 line plots, they just happen to overlay each other.)

image

epasveer commented 1 year ago

Hi,

I added a key shortcut to send the Interrupt to the running program. I've defaulted it to Ctrl-I. You can change it in the config settings for "Keys". Make sure to save the settings after changing them.

I'm a little worried that using Ctrl-C will interfere with Copy-N-Paste operations. But you can try it if you want.

image

epasveer commented 1 year ago

I looked into the Logger/Tracker to add other format types. I'm not seeing anything available in the gdb api to do that.

epasveer commented 1 year ago

On a different thread, I did see gdb support for Ada Tasks. I don't know what there are. I can add support for them, though.

https://sourceware.org/gdb/current/onlinedocs/gdb.html/GDB_002fMI-Ada-Tasking-Commands.html#GDB_002fMI-Ada-Tasking-Commands

epasveer commented 1 year ago

Same goes for Ada exception listing.

https://sourceware.org/gdb/current/onlinedocs/gdb.html/GDB_002fMI-Ada-Exceptions-Commands.html#GDB_002fMI-Ada-Exceptions-Commands

henrikglass commented 1 year ago

I'm not sure what parts of GDB the logger/tracker use for their implementations, and this might not be applicable, but getting this behavior in plain GDB is easy. If I have a variable color_rgba_magenta, i can print it in hex format using p/x color_rgba_magenta and get something like this back: 0xFF00FFFF (see https://sourceware.org/gdb/onlinedocs/gdb/Output-Formats.html. Maybe this part of the API is what you're looking for: https://sourceware.org/gdb/onlinedocs/gdb/Pretty-Printing-API.html ?). Afaik, if i want this behavior in seergdb, my only option is to write this command manually into the "Manually enter a gdb/mi command..." box. Either way, i'm straying off topic....

As for the Ada stuff, that sounds great, but don't feel like you have to give them high priority. Ada debugging is already working pretty well!

epasveer commented 1 year ago

There's a different gdb api I can use. I'll look into it to see if will work for Logger and Tracker.

I'll close this task and create a task for that. It applies to all languages, not just Ada.

Thanks for your input.