Author Topic: GDB 64-bit and pretty printing against 64-bit target  (Read 18578 times)

Offline eranon

  • Almost regular
  • **
  • Posts: 180
GDB 64-bit and pretty printing against 64-bit target
« on: February 11, 2013, 03:25:02 pm »
I started to talk about GDB 64-bit and pretty printing at http://forums.codeblocks.org/index.php/topic,17495.0.html, but there were several subjects and it remains only one now : so, a new clear fresh thread !

Well, I'm under Windows 7 64-bit. My project is compiled using the compiler delivered with the TDM64GCC 4.7.1-3 package. The debugger in use is GDB 7.5 (x86_64-w64-mingw32) coming with this same package. This debugger is Python-enabled.

My project being wxWidgets-based, to be able to watch data like wxString, I've followed the guide at http://code.google.com/p/qp-gcc/wiki/GDB. Thus, I've added the wxWidgets-dedicated "print.py" Python script beside "gdb.exe" (under "C:\MinGW64\bin") and added the required initialization commands in CodeBlocks settings about debugger.

The problem is that the returned value look "undreadable" (directly I mean).

For example, watching this wxString :
Code
wxString strTest = "C:/some/path/somewhere/test.txt";

I see :
Code
L"C\000:\000/\000s\000o\000m\000e\000/\000p\000a\000t\000h\000/\000s\000o\000m\000e\000w\000h\000e\000r\000e\000/\000t\000e\000s\000t\000.\000t\000x\000t\000"

It's obvious the data are here : original "C" is shown as "C\000", ":" as ":\000", "/" as "/\000", etc. And the first idea is just to strip out these extra "\000" for every character, but the things are maybe more complex to manage others wx data classes covered by print.py (i.e. wxDateTime, wxFileName, wxPoint, wxSize, wxRect)...

So, is there a print.py script around which would be ready for 64-bit target ?

--
EDIT : OK, solved modifying the to_string() function of wxStringPrinter class in Python script like shown below.

Was :
Code
   def to_string(self):
        return self.val['m_impl']['_M_dataplus']['_M_p']

And is now :
Code
    def to_string(self):
        buff = self.val['m_impl']['_M_dataplus']['_M_p'].string()
        return buff.decode('utf-16', 'ignore')

Also, at the beginning of script, I've added "import string". Now, wxString is displayed correctly in watching window.



« Last Edit: February 11, 2013, 07:25:44 pm by eanon »
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]

Offline eranon

  • Almost regular
  • **
  • Posts: 180
Re: GDB 64-bit and pretty printing against 64-bit target
« Reply #1 on: March 17, 2013, 12:30:02 pm »
I'm back on this subject. Yesterday, I've add to watch and follow a path (something like "E:\TMP\blah")under GDB (for 64-bit target) and the way I gave above (see the EDIT of previous post) didn't worked... I got this Python error :

Code
Python Exception <type 'exceptions.UnicodeEncodeError'> 'latin-1' codec can't encode characters in position 0-1: ordinal not in range(256):

So, the status is that this "solution" seems to not cover all the cases :(

Do you have an idea of the reason why ?
Am I alone in wanting to be able to debug some wxWidgets 2.9.4 's wxString ?
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]

Offline eranif

  • Regular
  • ***
  • Posts: 256
Re: GDB 64-bit and pretty printing against 64-bit target
« Reply #2 on: March 17, 2013, 12:51:36 pm »
Hi,

I am using this wxStringPrinter:

Code
class wxStringPrinter:

    def __init__(self, val):
        self.val = val

    def to_string(self):
        ret = ""
        wx29 = 0
        try:
            # wx-28 has m_pchData
            self.val['m_pchData']
        except Exception:
            wx29 = 1

        try:
            if wx29:
                dataAsCharPointer = self.val['m_impl']['_M_dataplus']['_M_p']
            else:
                dataAsCharPointer = self.val['m_pchData']
            ret = dataAsCharPointer
        except Exception:
            # swallow the exception and return empty string
            pass
        return ret

    def display_hint (self):
        return 'wxString'

With this printer, the script knows if you are running wx29 or wx28 which is useful on some cases

HTH,
Eran

Offline eranon

  • Almost regular
  • **
  • Posts: 180
Re: GDB 64-bit and pretty printing against 64-bit target
« Reply #3 on: March 17, 2013, 03:37:58 pm »
Thanks for sharing, Eranif. Your solution is quite similar to the one I've taken about 32-target (see this thread in which I've posted today : http://forums.wxwidgets.org/viewtopic.php?f=19&t=37037), but it doesn't works (at least here, on my dev-station) for the 64-bit targets (for which I've had to add an UTF-16 decoding).

Also, in both cases (x86 and x64), I've still some cases where it fails (i.e. exception for 64-bit target and showing raw bytes values rather than string glyphs for 32-bit one)... Don't succeeded to determine the special context which produces theses wrong behaviors at this time :-\

--
EDIT : may be important : I'm talking about project with wxWidgets 2.9.4 only here ; I don't have any project using 2.8.
« Last Edit: March 17, 2013, 03:39:47 pm by eranon »
[Independent dev. - wxWidgets 3.0.0 under "Win 7 Pro 64-bit, C::B SVN 9435 & wxSmith, TDM64-GCC 4.7 & MSVC9" + "OS X 10.8, FSF GCC 4.7 & C::B SVN 8909"]