Author Topic: Custom Watch Script Pluggins  (Read 38210 times)

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Custom Watch Script Pluggins
« on: January 23, 2006, 05:26:49 pm »
Currently the debbugger has the ability to automatically detect things such as wxStrings and produce cleaner watch output.  I think it would be greate to be able to add support for more custom watches through angel scripts.  The script define would the value necessary to determine that the variable we are watching is indeed of the right of type, then it could just supply a watch script.  When the debugger starts up it could run each script to register each custom variable type, and then call the script when ever the variable is seen to get the proper watch commands with which to display the variable.

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: Custom Watch Script Pluggins
« Reply #1 on: January 23, 2006, 06:19:41 pm »
Very nice idea, indeed. Thanks :)
Be patient!
This bug will be fixed soon...

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: Custom Watch Script Pluggins
« Reply #2 on: January 23, 2006, 06:45:25 pm »
If you need any help on this feature just let me know, I think something like this is vital to easy of use.  It will turn that sometimes obscure tree into something very usefull.  I would love to be able to write custom watches for all the key classes in my applications.  That would make debugging quite easy.
« Last Edit: January 23, 2006, 06:53:23 pm by Game_Ender »

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: Custom Watch Script Pluggins
« Reply #3 on: January 23, 2006, 07:01:41 pm »
If you need any help on this feature just let me know, I think something like this is vital to easy of use.  It will turn that sometimes obscure tree into something very usefull.  I would love to be able to write custom watches for all the key classes in my applications.  That would make debugging quite easy.

No kidding, I loved the idea :lol: (besides, I really want to put scripting into wide use).
I already moved wxString type recognition and parsing into its own script and will now implement the binding.
Be patient!
This bug will be fixed soon...

Offline 280Z28

  • Regular
  • ***
  • Posts: 397
  • *insert unicode here*
Re: Custom Watch Script Pluggins
« Reply #4 on: January 23, 2006, 07:32:06 pm »
std::map<> and other STL enumerations automatically in the debugger is only available in Visual Studio 2005 right now. If we get that in a script it's another push for Code::Blocks as a first class IDE.
78 280Z, "a few bolt-ons" - 12.71@109.04
99 Trans Am, "Daily Driver" - 525rwhp/475rwtq
 Check out The Sam Zone :cool:

Offline yop

  • Regular
  • ***
  • Posts: 387
Re: Custom Watch Script Pluggins
« Reply #5 on: January 23, 2006, 07:46:17 pm »
We are talking about a major improvement here. Game_Ender it is an excellent idea. The scripting support proves to be very powerfull indeed. And I was wondering what it could do...
Life would be so much easier if we could just look at the source code.

Offline rickg22

  • Lives here!
  • ****
  • Posts: 2283
Re: Custom Watch Script Pluggins
« Reply #6 on: January 24, 2006, 01:10:32 am »
Hey, if we're onto scripting for debugging, how about changing the watches depending on the context? I hate it when i exit a function and i have 3864* watches that suddenly go undefined.

* Value may vary.

sethjackson

  • Guest
Re: Custom Watch Script Pluggins
« Reply #7 on: January 24, 2006, 03:20:09 am »
I hate it when i exit a function and i have 3864* watches that suddenly go undefined.

* Value may vary.


:lol:

Offline duncanka

  • Multiple posting newcomer
  • *
  • Posts: 53
Re: Custom Watch Script Pluggins
« Reply #8 on: January 24, 2006, 04:52:45 am »
I'd like to add to this suggestion that there should be a way of configuring each variable type to display a certain data member as the value, as is possible in Visual C++.  It's a bit annoying to have to travel down several layers of tree just to look at a simple std::string's content.  (Or was that obvious?  :) )

By the way, will any of this affect saved watch files?  Are those going to be script-ified also?  I guess that would kind of be what Rick is talking about - having predefined watch files or something to be activated at different lines/breakpoints/whatevers.

EDIT - OK, apparently I can't read.  Sorry for stating the glaringly obvious  :oops:...
« Last Edit: January 24, 2006, 08:36:50 pm by duncanka »

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: Custom Watch Script Pluggins
« Reply #9 on: January 24, 2006, 05:40:02 am »
I'd like to add to this suggestion that there should be a way of configuring each variable type to display a certain data member as the value, as is possible in Visual C++.  It's a bit annoying to have to travel down several layers of tree just to look at a simple std::string's content.  (Or was that obvious?  :) )

Yeah that was way obvious because that is exactly what I said.  The Debugger pluggin asks the script to register the its custom variable, in this case a string.  Then when ever that variable is encountered the script is called and either returns the needed debugger print commands or is allowed to call them on the debugger itself.  For a string this would be something like "print myStringVar._M_impl_.m_Stuff._MObscureLayers._content_".  That result would be shown in the watch wind as "myStringVar = content".

Offline yop

  • Regular
  • ***
  • Posts: 387
Re: Custom Watch Script Pluggins
« Reply #10 on: January 24, 2006, 09:33:26 am »
And then we could provide ready to use scrips for various APIs that we use. It's going to be beautiful :)
Life would be so much easier if we could just look at the source code.

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: Custom Watch Script Pluggins
« Reply #11 on: January 24, 2006, 10:33:24 am »
Implemented it in GDB :lol:
I will have to study CDB a little more before I can implement it there too...

I have not committed it yet because I was in the middle of some other debugger changes. I will finish them all and then commit.

Here's the script that adds wxString support in GDB:

Code: cpp
////////////////////////////////////////////////////////////////////////////////
// Parses GDB's output of unicode wxString and turns it to human-readable
////////////////////////////////////////////////////////////////////////////////
//
// Example input:
// {38 '&', 69 'E', 110 'n', 97 'a', 98 'b', 108 'l', 101 'e'}
//
// Example output:
// "&Enable"
////////////////////////////////////////////////////////////////////////////////

// Entry point for testing.
// This is here only for testing the parsing function inside the IDE (while writing it).
// It is *not* used when the script runs in the debugger...
// So, it can safely be removed.
int main()
{
    wxString r;
    GDB_ParseWXString("{38 '&', 69 'E', 110 'n', 97 'a', 98 'b', 108 'l', 101 'e'}", r);
    Log(r);

    return 0;
}

void RegisterTypes(DebuggerDriver@ driver)
{
    driver.RegisterType(
        // The type's name (must be unique, the debugger driver won't accept duplicates).
        "wxString",
        // Regular expression for type matching.
        "[^[:alnum:]_]*wxString[^[:alnum:]_]*",
        // Parser function's name (defined below).
        "GDB_ParseWXString",
        // Define the print function body (this will become a GDB function named print_wxstring).
        // Note that we 're using the m_pchData member of wxString to access
        // its actual data...
        // Also note that we 'll be printing at most 100 chars, i.e. we 're setting a limit.
        "output /c (*$arg0.m_pchData)@(($slen=(unsigned int)$arg0.Len())>100?100:$slen)"
    );
}

// This function parses GDB's output.
// When it returns, the "result" argument contains the parsing result.
void GDB_ParseWXString(const wxString& in a_str, wxString& out result)
{
    result = "\"";
    uint len = a_str.length();
    uint c = 0;
    while (c < len)
    {
        switch (a_str[c])
        {
            case '\'':
                ++c;
                while (c < len)
                {
                    switch (a_str[c])
                    {
                        case '\\':
                            result += a_str[c++];
                            result += a_str[c++];
                            break;
                        default:
                            result += a_str[c++];
                            break;
                    }
                    if (a_str[c] == '\'')
                        break;
                }
                break;

            default:
                break;
        }
        ++c;
    }
    result += "\"";
}
Be patient!
This bug will be fixed soon...

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5490
Re: Custom Watch Script Pluggins
« Reply #12 on: January 24, 2006, 11:03:28 am »
what will be the name of the function in GDB ??
parse_wxstring ?
ParseWXString ?
GDB_ParseWXString ?

Unclear beacuse of the type, print function ..

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: Custom Watch Script Pluggins
« Reply #13 on: January 24, 2006, 11:22:18 am »
what will be the name of the function in GDB ??
parse_wxstring ?
ParseWXString ?
GDB_ParseWXString ?

Unclear beacuse of the type, print function ..

GDB_ParseWXString is the script's function that does the parsing (arbitrarily chosen - unique of course).
When registering the type, wxString in this case, the debugger prepends "print_" to it and converts it to lowercase so the final gdb function will be 'print_wxstring'. You don't need this info, unless you want to call it yourself by using "Debug->Send command".
Be patient!
This bug will be fixed soon...

Offline Urxae

  • Regular
  • ***
  • Posts: 376
Re: Custom Watch Script Pluggins
« Reply #14 on: January 24, 2006, 11:29:47 am »
Implemented it in GDB :lol:
I will have to study CDB a little more before I can implement it there too...

I have not committed it yet because I was in the middle of some other debugger changes. I will finish them all and then commit.

Here's the script that adds wxString support in GDB:

**snip**

Some points:
  • It looks like it gives a query to run and defines a function to parse the output. Would it not be simpler (and possibly more powerful) if the script could ask the debugger driver to run certain queries? That way you can run multiple queries and the script logic can even dynamically adjust which ones and/or how many times. It also allows for more abstraction from the actual queries, which might allow the same scripts to be used by both GDB and CDB.
  • Is the output only allowed to be a string? What if one wanted to define a script for a container type (such as std::vector or std::list instantiations) and have them be expandable to an enumerated list of the content of the container?
    I'm thinking of something like this:
    + myvec : std::vector<std::string>
    +-[0] "This"
    +-[1] "is"
    +-[2] "a"
    +-[3] "test"
    in the watches area (collapsable to just the first line, of course.
  • Is there any way these scripts can call each other or otherwise make use of each other? A vector script may want to the elements according to their own type's script, for instance.
  • Does this mechanism allow you to watch multiple instantiations of the same template with only one script? (The regex looks promising)
    For example: Would it be possible to write a script that parses std::vector<int>, std::vector<std::string> as well as std::vector<wxString>?

Combining some of the above suggestions, maybe the scripts should create a list as output, with elements like (Name, <Watch expression (or string)>). For instance the vector example would output something like
Code
(("[0]", <string at address0>), ("[1]", <string at address1>), ("[2]", <string at address2>), ("[3]", <string at address3>))
(in a data structure, not a string) and then the debugger driver or whatever calls the scripts can use the script for std::string to produce the representation of each individual string.
Preferably this would of course be done without the script needing to know what a std::string even is.