Author Topic: Custom Watch Script Pluggins  (Read 38189 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.

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: Custom Watch Script Pluggins
« Reply #15 on: January 24, 2006, 12:03:27 pm »
Quote
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.

(I 'm gonna use gdb examples here)

Before evaluating a variable, the driver runs a "whatis <var>" which gives the variable's type. This is then checked for matches by any script-registered type using the script-supplied regular expression.

If a script that matches is found, the previously defined "print_<typename>" gdb function is called. That would be "print_wxstring" in the above code case.
When we receive output from this command, the script's parse function (GDB_ParseWXString in the code above) is called.

The second argument will be filled with the result in a format similar to gdb's "output" command (the watches parsing works with this). So it will always be a string. I can elaborate on the format if you want it...

The first argument that is passed to the script is more interesting though. It contains the driver's output of the previously run command (print_wxstring in this case).
Depending on print_wxstring's definition, this string might be multiline but it doesn't matter. The parser function (GDB_ParseWXString) should parse it correctly and put the parsing result in the second function argument we talked about earlier.

All the above mean that you can parse practically whatever. If you want, I can post an example for parsing a std::vector. It's perfectly possible with this setup.

Finally, I haven't settled with this design yet. I 'm still evaluating it...
Thanks for the feedback though :)
Be patient!
This bug will be fixed soon...

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5490
Re: Custom Watch Script Pluggins
« Reply #16 on: January 24, 2006, 12:26:58 pm »
Quote
All the above mean that you can parse practically whatever. If you want, I can post an example for parsing a std::vector. It's perfectly possible with this setup.

Please do.

Offline Urxae

  • Regular
  • ***
  • Posts: 376
Re: Custom Watch Script Pluggins
« Reply #17 on: January 24, 2006, 01:57:04 pm »
In the script you posted I noticed you called $arg0.Len(). Does this mean the debugger can call member functions? That would be a great help when generalizing/porting scripts to multiple implementations (such as different standard libraries, or different versions of libraries with the same interface but different implementation), as long as variables of that type can be completely described by calls to member functions (which is true for a lot of types).

Quote
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.

(I 'm gonna use gdb examples here)

Before evaluating a variable, the driver runs a "whatis <var>" which gives the variable's type. This is then checked for matches by any script-registered type using the script-supplied regular expression.

If a script that matches is found, the previously defined "print_<typename>" gdb function is called. That would be "print_wxstring" in the above code case.
When we receive output from this command, the script's parse function (GDB_ParseWXString in the code above) is called.

Does this mean these things would have to be rewritten for each debugger? Is there maybe a way to abstract this a bit more, even if it's just the most basic functionality?
If the output needs to be in the same representation as a debugger output command, maybe the script should have access to some helper functions that produce the output in a more high-level way. This would not only be helpful in providing a more understandable way to create the output, but also allows for more uniform access to output formats for different debuggers.
This would basically entail some helper functions and/or classes. (Does AngelScript even have classes?)

Quote
The second argument will be filled with the result in a format similar to gdb's "output" command (the watches parsing works with this). So it will always be a string. I can elaborate on the format if you want it...

Hmm... I don't know much about gdb, but does this mean you could already write such a generic vector parsing script that would be parsed by C::B into a tree representation? (taking into account the scripts for the element type etc.)

Quote
The first argument that is passed to the script is more interesting though. It contains the driver's output of the previously run command (print_wxstring in this case).
Depending on print_wxstring's definition, this string might be multiline but it doesn't matter. The parser function (GDB_ParseWXString) should parse it correctly and put the parsing result in the second function argument we talked about earlier.

But some types may not be easy to print in one command, especially for people who've never used gdb directly (like me). I'm especially thinking about containers here.
Here a few parsing helper functions/classes would probably also be helpful. (Presumably, different debuggers write out different formats)

Quote
All the above mean that you can parse practically whatever. If you want, I can post an example for parsing a std::vector. It's perfectly possible with this setup.

I guess that already answers one of my questions. As often noted on these forums, you guys are fast :lol:.
Seriously, that would probably be quite instructional, especially with extensive comments that explain everything.

Quote
Finally, I haven't settled with this design yet. I 'm still evaluating it...
Thanks for the feedback though :)

I presumed you hadn't settled on it yet. Actually, that's why I gave the feedback. I just wanted to make sure this would work for more complex structures that are best presented as multiple values. Best to do so before anything is settled on, right? ;)
« Last Edit: January 24, 2006, 02:02:43 pm by Urxae »

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: Custom Watch Script Pluggins
« Reply #18 on: January 24, 2006, 02:05:13 pm »
Quote
All the above mean that you can parse practically whatever. If you want, I can post an example for parsing a std::vector. It's perfectly possible with this setup.

Please do.

Here it is:

Code: cpp
void RegisterTypes(DebuggerDriver@ driver)
{
    driver.RegisterType(
        "StdVector",

        "[^[:alnum:]_]*vector<.*",

        "GDB_ParseStdVector",

        "set $vec = ($arg0)\n"
        "set $vec_size = $vec->_M_impl._M_finish - $vec->_M_impl._M_start\n"
        "if ($vec_size != 0)\n"
        "  set $i = 0\n"
        "  while ($i < $vec_size)\n"
        "    p *($vec->_M_impl._M_start+$i)\n"
        "    set $i++\n"
        "  end\n"
        "end\n"
    );
}

void GDB_ParseStdVector(const wxString& in a_str, wxString& out result)
{
    result = "{" + a_str + "}";
    result.Replace("\n", ",", true);
}

EDIT: The attached image shows a std::vector<float> being watched.
Still needs some work, but as you see it is possible :)

[attachment deleted by admin]
« Last Edit: January 24, 2006, 02:11:15 pm by mandrav »
Be patient!
This bug will be fixed soon...

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: Custom Watch Script Pluggins
« Reply #19 on: January 24, 2006, 02:17:49 pm »
Quote
In the script you posted I noticed you called $arg0.Len(). Does this mean the debugger can call member functions?

Yes, you can call functions, do casts, basically whatever the language allows. As long as the debugger has full info on the type that is...

Quote
Does this mean these things would have to be rewritten for each debugger?

As it is now, yes. But I plan change this. I 'm rethinking the whole process. In the std::vector example I posted above, I doubt it would work with wxStrings (well it would work, but not using the print_wxstring function).
So maybe I will expose some debugger commands to the scripts so they can call the debugger directly as needed. I 'm thinking it over...

Quote
Hmm... I don't know much about gdb, but does this mean you could already write such a generic vector parsing script that would be parsed by C::B into a tree representation? (taking into account the scripts for the element type etc.)

See my post above.
Be patient!
This bug will be fixed soon...

Offline Urxae

  • Regular
  • ***
  • Posts: 376
Re: Custom Watch Script Pluggins
« Reply #20 on: January 24, 2006, 03:55:30 pm »
Code: cpp
void RegisterTypes(DebuggerDriver@ driver)
{
    driver.RegisterType(
        "StdVector",

        "[^[:alnum:]_]*vector<.*",

        "GDB_ParseStdVector",

        "set $vec = ($arg0)\n"
        "set $vec_size = $vec->_M_impl._M_finish - $vec->_M_impl._M_start\n"
        "if ($vec_size != 0)\n"
        "  set $i = 0\n"
        "  while ($i < $vec_size)\n"
        "    p *($vec->_M_impl._M_start+$i)\n"
        "    set $i++\n"
        "  end\n"
        "end\n"
    );
}

void GDB_ParseStdVector(const wxString& in a_str, wxString& out result)
{
    result = "{" + a_str + "}";
    result.Replace("\n", ",", true);
}

That seems to do most of the work in some weird gdb script though. It looks like the angelscript is mostly just a wrapper because it needs to be done in angelscript ;).

Quote
In the script you posted I noticed you called $arg0.Len(). Does this mean the debugger can call member functions?

Yes, you can call functions, do casts, basically whatever the language allows. As long as the debugger has full info on the type that is...

That opens up some possibilities once the script gets direct access to debugger commands, I think. (Though it's probably possible through that gdb script)

For instance, the use of _M_start isn't portable, but accessing the elements through a standard interface should work for every implementation of std::vector. So []/.operator[]() (if possible), .at() or even iterators (if possible) would make for a much more portable script. And it would be even better if this could be done from a script independent of the compiler and debugger used.

Quote
Quote
Does this mean these things would have to be rewritten for each debugger?

As it is now, yes. But I plan change this. I 'm rethinking the whole process. In the std::vector example I posted above, I doubt it would work with wxStrings (well it would work, but not using the print_wxstring function).
So maybe I will expose some debugger commands to the scripts so they can call the debugger directly as needed. I 'm thinking it over...

That sounds like a good idea.

Quote
Quote
Hmm... I don't know much about gdb, but does this mean you could already write such a generic vector parsing script that would be parsed by C::B into a tree representation? (taking into account the scripts for the element type etc.)

See my post above.

But it doesn't use the custom wxString representation, correct?

I'd like vector script to look more like this:

Code: cpp
void RegisterTypes(DebuggerDriver@ driver)
{
    // Notice: No debugger-dependent code
    driver.RegisterType(
        "StdVector",

        "[^[:alnum:]_]*vector<.*",

        "ParseStdVector"
    );
}

void ParseStdVector(DebuggerDriver@ driver, wxString vecname, DebuggerTree@ tree)
{
    for (size_t i = 0; i < vecname.length(); ++i) {
        wxString index;
        index << "[" << i << "]";
        tree.addChild(index, vecname + index);  // (<label>, <watch expression>)
    }
}

Which would then work for any type of vector (and use custom representations).
DebuggerTree would be a representation of the tree in the watch window.
Maybe addChild() should have an overload for a single string argument too, to allow complete control over the text being shown.

Note: I don't know much about angelscript, if any syntax is wrong please feel free to ignore that and just get the general idea anyway :P. In particular, if operator overloads don't work please imagine I used .Append() (on copies of the string) and .Printf() instead of << and + ;).
If it's not easy to get vector[0] etc. to be evaluated by the debugger, imagine I used .at() or something.

And if gdb/cdb are advanced enough (especially w.r.t. operator overloads) to allow access to and use of iterators, this might be done in an even cooler way: imagine using only one script for ALL stl containers without special cases being necessary (except maybe std::string and variants, which have a more natural representation). 8)

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: Custom Watch Script Pluggins
« Reply #21 on: January 25, 2006, 09:02:34 pm »
Update: for those that haven't noticed, I have committed this WIP feature in a new branch (branches/ym_gdb). So if you want to test-drive it, just use this branch.

Ah, almost forgot. This branch has a nifty little bonus: compiler parallel builds :)
Be patient!
This bug will be fixed soon...

Offline rickg22

  • Lives here!
  • ****
  • Posts: 2283
Re: Custom Watch Script Pluggins
« Reply #22 on: January 25, 2006, 11:17:14 pm »
Yiannis: I don't think it'd be wise to watch *ALL* the members of a vector. I think it'd be more useful to open a watch window for each vector you want to see (this is also known as "Inspect"). But having vectors of 70,000 items, we'd need "start and end" modifiers, too.

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Custom Watch Script Pluggins
« Reply #23 on: January 25, 2006, 11:20:46 pm »
I have the feeling the debugger is getting terribly slow... someone should optimize it.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

sethjackson

  • Guest
Re: Custom Watch Script Pluggins
« Reply #24 on: January 25, 2006, 11:22:09 pm »
I have the feeling the debugger is getting terribly slow... someone should optimize it.

You are the one to talk with the sig you have.  :lol: :lol: :lol:

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: Custom Watch Script Pluggins
« Reply #25 on: January 25, 2006, 11:24:52 pm »
Yiannis: I don't think it'd be wise to watch *ALL* the members of a vector. I think it'd be more useful to open a watch window for each vector you want to see (this is also known as "Inspect"). But having vectors of 70,000 items, we'd need "start and end" modifiers, too.

Rick, these are just prototypes :)
Be patient!
This bug will be fixed soon...

Offline rickg22

  • Lives here!
  • ****
  • Posts: 2283
Re: Custom Watch Script Pluggins
« Reply #26 on: January 25, 2006, 11:25:42 pm »
Pardon me, don Corleone, I was just making a suggestion, please don't kill me :lol:

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Custom Watch Script Pluggins
« Reply #27 on: January 25, 2006, 11:29:31 pm »
Rick, you don't own a horse, do you :)
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

sethjackson

  • Guest
Re: Custom Watch Script Pluggins
« Reply #28 on: January 25, 2006, 11:30:59 pm »
Pardon me, don Corleone, I was just making a suggestion, please don't kill me :lol:

Bye, bye rick have a nice trip. :lol:

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: Custom Watch Script Pluggins
« Reply #29 on: January 25, 2006, 11:45:25 pm »
I have the feeling the debugger is getting terribly slow... someone should optimize it.

I going to take one of these dangerous stabs in the dark, but does having to comunicate over stdin/stdout put an upper limit on performance?  Is that our current bottleneck?

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Custom Watch Script Pluggins
« Reply #30 on: January 25, 2006, 11:48:24 pm »
I have the feeling the debugger is getting terribly slow... someone should optimize it.

I going to take one of these dangerous stabs in the dark, but does having to comunicate over stdin/stdout put an upper limit on performance?  Is that our current bottleneck?
For heaven's sake! Don't tempt him any further, or he'll really start off! :lol:
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline rickg22

  • Lives here!
  • ****
  • Posts: 2283
Re: Custom Watch Script Pluggins
« Reply #31 on: January 26, 2006, 01:13:38 am »
has somebody tried to profile codeblocks while debugging a program?

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: Custom Watch Script Pluggins
« Reply #32 on: January 26, 2006, 03:57:40 am »
I have had the worst time profiling a shared library.  I have gotten as far as generating libdebuggergdb.so.profile .  But I am sure I need a tool called "sprof" to get the actual profile graph.  But I can't find it anywhere.  In other notes the Main Code::Blocks app spends about 30-40% of its time processing events.

EDIT- I found sprof, it was in the libstdc-prof package, but It comes back with a very small mangled named graph.  On windows you could try using AMD Code Analyzer.
« Last Edit: January 26, 2006, 05:15:00 am by Game_Ender »

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: Custom Watch Script Pluggins
« Reply #33 on: January 27, 2006, 12:52:18 pm »
How does this look?

Code: cpp
// Registers new types with driver
void RegisterTypes(DebuggerDriver@ driver)
{
    driver.RegisterType(
        // The type's name (must be unique, the debugger driver won't accept duplicates).
        "STL String",
        // Regular expression for type matching.
        "[^[:alnum:]_]*string[^[:alnum:]_]*",
        // Evaluate function's name (defined below).
        "Evaluate_StlString",
        // Parser function's name (defined below).
        "Parse_StlString"
    );
}

// This function tells the driver how to evaluate this type.
// a_str contains the variable and result must contain the debugger's command when it returns.
void Evaluate_StlString(const wxString& in a_str, wxString& out result)
{
    result = "output " + a_str + ".c_str()";
}

// This function parses driver's output.
// When it returns, the "result" argument contains the parsing result.
void Parse_StlString(const wxString& in a_str, wxString& out result)
{
    // nothing needs to be done
    result = a_str;
}
Be patient!
This bug will be fixed soon...

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: Custom Watch Script Pluggins
« Reply #34 on: January 27, 2006, 05:39:12 pm »
That is very cool, awesome job Mandrav.  That looks like it is clean and should be pretty independent.  But like mentioned above, when you are doing some complicated like STL vectors and such you might have to use library specific names, is there some way to for script to detect what compiler you are using so it can react accordingly?

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: Custom Watch Script Pluggins
« Reply #35 on: January 27, 2006, 05:51:51 pm »
That is very cool, awesome job Mandrav.  That looks like it is clean and should be pretty independent.  But like mentioned above, when you are doing some complicated like STL vectors and such you might have to use library specific names, is there some way to for script to detect what compiler you are using so it can react accordingly?

My tests with std::vector show that there is no other way than using vector._M_impl._M_start to access its elements, which binds the script to a specific compiler implementation (gcc-3.4.4 in this case).

BUT

I could add some script constants for the used compiler/debugger so the script could return different data for different compilers.
I believe this will be settled this weekend.
Be patient!
This bug will be fixed soon...

takeshimiya

  • Guest
Re: Custom Watch Script Pluggins
« Reply #36 on: January 27, 2006, 06:07:41 pm »
You mean, not really based on the compiler, but based on the stl implementation, right? Like detecting if it's libstdc++, stlport, sgi stl, etc.

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: Custom Watch Script Pluggins
« Reply #37 on: January 27, 2006, 06:14:52 pm »
Yes, all it comes down to is the STL implementation.
Be patient!
This bug will be fixed soon...

Offline Game_Ender

  • Lives here!
  • ****
  • Posts: 551
Re: Custom Watch Script Pluggins
« Reply #38 on: January 27, 2006, 07:31:51 pm »
You mean, not really based on the compiler, but based on the stl implementation, right? Like detecting if it's libstdc++, stlport, sgi stl, etc.

Would there be an easy way to do this through scripting?  I know it will be pretty to easy to check the constants as Mandrav posted above and then you can infer the stl implementation based on the compiler.  You would probably have to code some new methods into the debugger so that it searches the library include paths, checks all the linker settings, and checks compiler version to figure out the proper STL version.  That would get complicated and might not be worth the effort.

takeshimiya

  • Guest
Re: Custom Watch Script Pluggins
« Reply #39 on: January 27, 2006, 07:37:25 pm »
You mean, not really based on the compiler, but based on the stl implementation, right? Like detecting if it's libstdc++, stlport, sgi stl, etc.

Would there be an easy way to do this through scripting?  I know it will be pretty to easy to check the constants as Mandrav posted above and then you can infer the stl implementation based on the compiler.  You would probably have to code some new methods into the debugger so that it searches the library include paths, checks all the linker settings, and checks compiler version to figure out the proper STL version.  That would get complicated and might not be worth the effort.

A good source would be to see how STL decryptor detects the different stl implementations.

Offline duncanka

  • Multiple posting newcomer
  • *
  • Posts: 53
Re: Custom Watch Script Pluggins
« Reply #40 on: January 27, 2006, 09:13:57 pm »
That is very cool, awesome job Mandrav.  That looks like it is clean and should be pretty independent.  But like mentioned above, when you are doing some complicated like STL vectors and such you might have to use library specific names, is there some way to for script to detect what compiler you are using so it can react accordingly?

My tests with std::vector show that there is no other way than using vector._M_impl._M_start to access its elements, which binds the script to a specific compiler implementation (gcc-3.4.4 in this case).
Why can't you just use operator[] for STL vectors?  I had no problem accessing vector elements using this syntax in my watches, even if the element I was referencing did not exist (i.e. accessing v[5] didn't cause an access violation even when v only had 1 element allocated).

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: Custom Watch Script Pluggins
« Reply #41 on: January 27, 2006, 09:45:04 pm »
Why can't you just use operator[] for STL vectors?  I had no problem accessing vector elements using this syntax in my watches, even if the element I was referencing did not exist (i.e. accessing v[5] didn't cause an access violation even when v only had 1 element allocated).

This is partly true. You see, adding a watch on one vector element is possible with operator[]. But trying to watch a series of vector elements as an array, it doesn't work. You can't do the following, for example (v is a vector), to watch the first 100 elements:
Code
output v[0]@100
Be patient!
This bug will be fixed soon...

Offline duncanka

  • Multiple posting newcomer
  • *
  • Posts: 53
Re: Custom Watch Script Pluggins
« Reply #42 on: January 27, 2006, 10:15:18 pm »
Why can't you just use operator[] for STL vectors?  I had no problem accessing vector elements using this syntax in my watches, even if the element I was referencing did not exist (i.e. accessing v[5] didn't cause an access violation even when v only had 1 element allocated).

This is partly true. You see, adding a watch on one vector element is possible with operator[]. But trying to watch a series of vector elements as an array, it doesn't work. You can't do the following, for example (v is a vector), to watch the first 100 elements:
Code
output v[0]@100
Granted, but even so, wouldn't it be far easier to write a script that just asks GDB for multiple elements using standard operators than to start trying to make a different script for each STL implementation?  I guess this would require multiple commands to GDB, but I would think that that would still be simpler to implement.  (Maybe have the Evaluate_<type> functions place their results in a wxArrayString, instead of a wxString?)

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: Custom Watch Script Pluggins
« Reply #43 on: January 27, 2006, 10:22:56 pm »
Granted, but even so, wouldn't it be far easier to write a script that just asks GDB for multiple elements using standard operators than to start trying to make a different script for each STL implementation?  I guess this would require multiple commands to GDB, but I would think that that would still be simpler to implement.  (Maybe have the Evaluate_<type> functions place their results in a wxArrayString, instead of a wxString?)

I don't know what this means, performance-wise. I guess I will run some tests and we 'll see.
Be patient!
This bug will be fixed soon...

Offline rickg22

  • Lives here!
  • ****
  • Posts: 2283
Re: Custom Watch Script Pluggins
« Reply #44 on: January 30, 2006, 05:04:21 pm »
Yes, but doesn't operator[] actually ADD elements for STL maps?

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Custom Watch Script Pluggins
« Reply #45 on: January 30, 2006, 05:37:13 pm »
Luckily not, std::vector would be quite inefficient if it did. operator[] is not bounds-checked in release build (it may throw an error in debug build), so working with a std::vector offers the same performance as an old-style C array. It is just more comfortable.

EDIT:
Hey wait a second... did you say map? :lol:
I could swear I read vector... anyway: STL maps are not supposed to do that, but wxHashMap does.
« Last Edit: January 30, 2006, 05:40:30 pm by thomas »
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline duncanka

  • Multiple posting newcomer
  • *
  • Posts: 53
Re: Custom Watch Script Pluggins
« Reply #46 on: January 31, 2006, 01:33:34 am »
EDIT:
Hey wait a second... did you say map? :lol:
I could swear I read vector... anyway: STL maps are not supposed to do that, but wxHashMap does.
Actually, according the specifications in Mark Nelson's STL book, operator[] does insert the element in an STL map, although it does not for an STL vector.  If the operator makes people nervous, though, the command to GDB could always just use vector::at().
I'm pretty sure you can also use and dereference iterators in GDB, though, so even for a map, it might be possible to write a compiler-independent script that steps through each map element using iterators - it would presumably ask GDB for (*(iter + element#) ).first and (*(iter + element#) ).second, then combine the two into a single string, for each map element.  Although this would probably take a serious toll in terms of performance, to send and process all these GDB commands and output.
Mandrav, any results on performance using such multiple GDB commands?

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: Custom Watch Script Pluggins
« Reply #47 on: January 31, 2006, 08:39:45 am »
Quote
Mandrav, any results on performance using such multiple GDB commands?

Yes, expect an update today :)
Actually I tested it with vectors and it's almost instantaneous for about 30 elements. I have added "start from" and "count" for array types anyway so the user can watch only the items of interest without sacrificing performance...
Be patient!
This bug will be fixed soon...