Code::Blocks Forums

User forums => Using Code::Blocks => Topic started by: Feneck91 on January 28, 2010, 07:18:13 am

Title: GDB & Code::Blocks : Is it possible to add own registering classes ?
Post by: Feneck91 on January 28, 2010, 07:18:13 am
When the debugger started, we can see :
Registered new type: wxString
Registered new type: STL String
Registered new type: STL Vector

I have my own string class derived from std::wstring (unicode string).
Problem, I cannot see it into the compiler as wxString (wxString with wxWidgets 2.9.0 couldn't be see too).
Could we add own registered type and how to add it ?
I have tryed to modify gdb_types.script  without any success.
I know we can add initialized commands to debugger in debugger settings but I don't know how to add own class reader into gdb and I think it is not the good topic to ask this kind of question for gdb configuration...

Is it possible to add own class into Code::Blocks ?
Thanks for reply.
Title: Re: GDB & Code::Blocks : Is it possible to add own registering classes ?
Post by: oBFusCATed on January 28, 2010, 09:47:24 am
Look here: http://wiki.codeblocks.org/index.php?title=Debugger_scripts
Title: Re: GDB & Code::Blocks : Is it possible to add own registering classes ?
Post by: Feneck91 on January 28, 2010, 04:47:38 pm
I have modified this file to be able to see std::string and std::wstring (unicode strings) based on wxString.
If it could help someone.
For my class, derived from std::wstring, it don't work, it make gdb crash !

Code
/*
 * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
 * http://www.gnu.org/licenses/gpl-3.0.html
 *
 * $Revision: 5783 $
 * $Id: gdb_types.script 5783 2009-09-14 15:17:56Z mortenmacfly $
 * $HeadURL: http://svn.berlios.de/svnroot/repos/codeblocks/trunk/src/scripts/gdb_types.script $
 */

// Registers new types with driver
function RegisterTypes(driver)
{
//    signature:
//    driver.RegisterType(type_name, regex, eval_func, parse_func);

    // STL WString
    driver.RegisterType(
        _T("STL WString"),
        _T("[^[:alnum:]_]*(wstring)[^[:alnum:]_]*"),
        _T("Evaluate_StlWString"),
        _T("Parse_StlWString")
    );

    // wxString
    driver.RegisterType(
        _T("wxString"),
        _T("[^[:alnum:]_]*wxString[^[:alnum:]_]*"),
        _T("Evaluate_wxString"),
        _T("Parse_wxString")
    );

    // STL String
    driver.RegisterType(
        _T("STL String"),
        _T("[^[:alnum:]_]*string[^[:alnum:]_]*"),
        _T("Evaluate_StlString"),
        _T("Parse_StlString")
    );

    // STL Vector
    driver.RegisterType(
        _T("STL Vector"),
        _T("[^[:alnum:]_]*vector<.*"),
        _T("Evaluate_StlVector"),
        _T("Parse_StlVector")
    );

    Log(_T("Registering types for the debugger."));
}

////////////////////////////////////////////////////////////////////////////////
// wxString
////////////////////////////////////////////////////////////////////////////////

// This function tells the driver how to evaluate this type.
// a_str contains the variable.
// start contains the starting position. Useful for arrays.
// count contains the count of evaluation. Useful for arrays. If 0, evaluate from start (variable) to end of array.
// result must contain the debugger's command when it returns.
function Evaluate_wxString(type, a_str, start, count)
{
    local oper = _T(".");

    if (type.Find(_T("*"), false) > 0)
        oper = _T("->");

    local result = _T("output /c ") + a_str + oper + _T("m_pchData[") + start + _T("]@");
    if (count != 0)
        result = result + count;
    else
        result = result + _T("((wxStringData*)") + a_str + oper + _T("m_pchData - 1)->nDataLength");
    return result;
}

// This function parses driver's output.
// When it returns, the _T("result") argument contains the parsing result.
function Parse_wxString(a_str, start)
{
    local result = _T("\"");
    local len = a_str.length();
    local c = 0;
    while (c < len)
    {
        switch (a_str.GetChar(c))
        {
            case '\'':
                ++c;
                while (c < len)
                {
                    switch (a_str.GetChar(c))
                    {
                        case '\\':
                            result.AddChar(a_str.GetChar(c++));
                            result.AddChar(a_str.GetChar(c++));
                            break;
                        default:
                            result.AddChar(a_str.GetChar(c++));
                            break;
                    }
                    if (a_str.GetChar(c) == '\'')
                        break;
                }
                break;

            default:
                break;
        }
        ++c;
    }
    result = result + _T("\"");
    return result;
}

////////////////////////////////////////////////////////////////////////////////
// STL String
////////////////////////////////////////////////////////////////////////////////

function Evaluate_StlString(type, a_str, start, count)
{
    local oper = _T(".");

    if (type.Find(_T("*"), false) > 0)
        oper = _T("->");

    local result = _T("output ") + a_str + oper + _T("c_str()[") + start + _T("]@");
    if (count != 0)
        result = result + count;
    else
        result = result + a_str + oper + _T("size()");
    return result;
}

function Parse_StlString(a_str, start)
{
    // nothing needs to be done
    return a_str;
}

////////////////////////////////////////////////////////////////////////////////
// STL Vector
////////////////////////////////////////////////////////////////////////////////

function Evaluate_StlVector(type, a_str, start, count)
{
    local result = _T("pvector ") + a_str;
    return result;
}

function Parse_StlVector(a_str, start)
{
    local size_pos = a_str.Find(_T("Vector size = "));

    if (size_pos < 0)
        return _T("");

    // copy the end of the a_str, so we don't search the whole string when we look for capacity
    local vector_info_str = a_str.Mid(size_pos, a_str.length() - size_pos);
    size_pos = 0;

    local capacity_pos = vector_info_str.Find(_T("Vector capacity = "));
    if (capacity_pos < 0)
        return _T("");

    local size_value = vector_info_str.Mid(14, capacity_pos - 15);
    local size = wxString_ToLong(size_value);

    local capacity_end_pos = vector_info_str.Find(_T("Element"));
    if(capacity_end_pos < 0)
        return _T("");
    capacity_pos += 18;
    local capacity_value = vector_info_str.Mid(capacity_pos, capacity_end_pos - capacity_pos - 1);
    local element_type_value = vector_info_str.Mid(capacity_end_pos + 15,
                                                   vector_info_str.length() - capacity_end_pos - 15);

    local result = _T("[size] = ") + size_value + _T(",\n");
    result += _T("[capacity] = ") + capacity_value + _T(",\n");
    result += _T("[element type] = ") + element_type_value;

    if(size > 0)
        result += _T(",\n");

    local value_str = a_str;
    for(local item = 0; item < size; item += 1)
    {
        local elem_str = _T("elem[") + item + _T("]: ");
        local elem_start = value_str.Find(elem_str);
        local elem_end = 0;
        if(item == size - 1)
            elem_end = value_str.Find(_T("Vector size"));
        else
            elem_end = value_str.Find(_T("elem[") + (item + 1) + _T("]: "));

        if(elem_start >= 0 && elem_end >= 0)
        {
            local elem_value = value_str.Mid(elem_start, elem_end - elem_start);
            local equal_pos = elem_value.Find(_T(" = "));
            if(equal_pos >= 0)
                elem_value.Remove(0, equal_pos + 3);
            if(item > 0)
                result += _T(",");
            result += _T("[") + item + _T("] = ") + elem_value + _T("\n");
        }
        else
            break;

        value_str.Remove(0, elem_end);
    }
    if(result.length() > 0)
    {
        return _T("{ " ) + result + _T(" } ");
    }
    return "";
}

////////////////////////////////////////////////////////////////////////////////
// STL WString
////////////////////////////////////////////////////////////////////////////////
function Evaluate_StlWString(type, a_str, start, count)
{
    local oper = _T(".");

    if (type.Find(_T("*"), false) > 0)
        oper = _T("->");

    local result = _T("output /c ") + a_str + oper + _T("c_str()[") + start + _T("]@");
    if (count != 0)
        result = result + count;
    else
        result = result + a_str + oper + _T("size()");
    return result;
}

function Parse_StlWString(a_str, start)
{
    local result = _T("\"");
    local len = a_str.length();
    local c = 0;
    while (c < len)
    {
        switch (a_str.GetChar(c))
        {
            case '\'':
                ++c;
                while (c < len)
                {
                    switch (a_str.GetChar(c))
                    {
                        case '\\':
                            result.AddChar(a_str.GetChar(c++));
                            result.AddChar(a_str.GetChar(c++));
                            break;
                        default:
                            result.AddChar(a_str.GetChar(c++));
                            break;
                    }
                    if (a_str.GetChar(c) == '\'')
                        break;
                }
                break;

            default:
                break;
        }
        ++c;
    }
    result = result + _T("\"");
    return result;
}
Title: Re: GDB & Code::Blocks : Is it possible to add own registering classes ?
Post by: oBFusCATed on January 28, 2010, 09:52:10 pm
For my class, derived from std::wstring, it don't work, it make gdb crash !
That is a gdb problem, it has crashed :) // you can try to report it to the gdb devs
What is your gdb version?
Title: Re: GDB & Code::Blocks : Is it possible to add own registering classes ?
Post by: Feneck91 on January 29, 2010, 06:18:44 am
I use GNU gdb (GDB) 7.0.1
For my class, when I write same command directly with gdb it's working but with the script that executed same things it crashed.
1> Do you think it is possible to add into Code::Blocks release the std::wstring script ? I think more and more peaple will use Unicode compilation and so will use wstring...
2> When arabic character are used, GDB don't write these characters... :-(
3> Yesterday, I read that this script will probably splitted into more files : One for predefined script (gived with Code::Blocks) and another for user, I think it is a very good idea !
Title: Re: GDB & Code::Blocks : Is it possible to add own registering classes ?
Post by: Jenna on January 29, 2010, 07:01:24 am
I use GNU gdb (GDB) 7.0.1
If you are on windows, switch to 7.0.2, because 7.0.1 is known to have problems.
Title: Re: GDB & Code::Blocks : Is it possible to add own registering classes ?
Post by: eeghem on May 03, 2010, 03:09:17 pm
I've been recently using C::B and Qt, hence my interest in adding types to the gdb_types.script file. After some experimenting I was able to neatly print the QString. In case anyone is interesed, I solved it using the following steps:

1. in the RegisterTypes function I added:
Code
driver.RegisterType (_T("Qt String"), _T("[^[:alnum:]_]*QString[^[:alnum:]_]*"), _T("Evaluate_QtString"), _T("Parse_QtString"))

2. in the file I added the functions Evaluate_QtString and Parse_QtString like this:
Code
function Evaluate_QtString (type, a_str, start, count) {
    // determine the method of accessing the variable (if it is a reference use the
    // '.' else use the '->'.
    local oper = _T(".");
    if (type.Find(_T("*"), false) > 0)
        oper = _T("->");

    // create the output string send to the debugger
    // since it is a qstring we actually want the debugger to do the following
    // (char*) stringvar.d
    local result = _T("output /c ") + a_str + oper + _T("d.data[0]@") + a_str + oper + _T("d.size");
    return result;
}

function Parse_QtString (a_str, start) {
    return Parse_wxString (a_str, start);
}

Note that I reuse the Parse_wxString. No need to reinvent the wheel. The result is quite satisfactoring  :D.

Ruud
Title: Re: GDB & Code::Blocks : Is it possible to add own registering classes ?
Post by: ollydbg on May 05, 2010, 10:31:08 am
I've been recently using C::B and Qt, hence my interest in adding types to the gdb_types.script file. After some experimenting I was able to neatly print the QString. In case anyone is interesed, I solved it using the following steps:

I just find some discussion about viewing the Qt string, see here:
Re: Debugging QString (http://forums.codeblocks.org/index.php/topic,11184.msg76208.html#msg76208)