Author Topic: Debugging of 32 and 64-bit targets (built with TDM64-GCC) with GDB 64-bit  (Read 7833 times)

Offline eranon

  • Almost regular
  • **
  • Posts: 180
Hello,

I've recently switched to Windows 7 64-bit and installed TDM64-GCC to be able to build both 32-bit and 64-bit targets. Until now, all sounds right unless on debugging side with GDB.

Here are my problems :

1) About 32-bit debug target : impossible to breakpoint !

I can run a debug session (my app starts, I can use it and exit normally), but without breakpoint only. If I set a breakpoint (say in MyApp::OnInit), my app is running but it just shows a one line callstack at "Function : ?? ()" and not any highlight of code on which it's supposed to stop.

Here is the end of full debug log :
Code
[debug][New Thread 5084.0x6dc]
[debug][New Thread 5084.0x15f0]
[debug]Do you need "set solib-search-path" or "set sysroot"?
[debug]Do you need "set solib-search-path" or "set sysroot"?
[debug]Do you need "set solib-search-path" or "set sysroot"?
[debug]Do you need "set solib-search-path" or "set sysroot"?
[debug]Do you need "set solib-search-path" or "set sysroot"?
[debug][New Thread 5084.0x1110]
[debug]Program received signal ?, Unknown signal.
[debug]0x0008da98 in ?? ()
[debug]>>>>>>cb_gdb:

In ?? () ()

[debug]> bt 30
[debug]#0  0x0008da98 in ?? ()
[debug]>>>>>>cb_gdb:
[debug]> x/32xb 0x0
[debug]Cannot access memory at address 0x0
[debug]0x0: >>>>>>cb_gdb:
[debug]> info threads
[debug]  Id   Target Id         Frame
[debug]  3    Thread 5084.0x1110 0xfeeefeee in ?? ()
[debug]  2    Thread 5084.0x15f0 0x0000002b in ?? ()
[debug]* 1    Thread 5084.0x6dc 0x0008da98 in ?? ()
[debug]>>>>>>cb_gdb:

EDIT#1 : OK, this first case is solved. I've installed last GDB 32-bit (not installed the compiler, binutils, etc., but  only the debugger under C:\MinGW32 - while TDM64-GCC is under C:\MinGW64 - and without adding nothing in PATH) coming with "tdm-gcc-4.7.1-2" package (i.e. 32-bit only). Then created a new debugger config in CodeBlocks and associated it with a GCC 32-bit only compiler entry in C::B's compilers settings. Now breakpoint works :)

EDIT #2 : also, since this GCC 7.5 (from TDM-GCC 4.7) seems to be delivered no python-enabled (a "python print sys.version" at GDB prompt returns "Python scripting is not supported in this copy of GDB"), I've replaced gdb.exe and gdbserver.exe with the 7.2.50 I used in my previous C::B install (under Windows 7 32-bit). This way, pretty printing works too for 32-bit targets.

--

2) About 64-bit debug target : impossible to watch a wxString !

All sounds right (it run and I can set breakpoints), unless the pretty printing. I've tried to watch a wxString (precisely something like : wxString strTest = "C:/some/path/somewhere/test.txt") and it shows nothing pertinent.

Is that normal ? Does DBG 64-bit unable to manage 32-bit executables ? Does DBG 64-bit unable to pretty print against 64-bit executables yet ?

EDIT #3 : a "python print sys.version" at GDB prompt returns "2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)]". So, it *seems* this 64-bit GCC 7.5 is python enabled (but why not the GCC 7.5 32-bit appeared to be not (see EDIT#2) ? Strange !). Well, maybe the problem comes from print.py or the intitialization commands from C::B.

EDIT #4 : following of this thread (reduced to remaining question) is here : http://forums.codeblocks.org/index.php/topic,17502.0.html.

--
I'm using this debugger, coming with "tdm64-gcc-4.7.1-3" package :
Code
GNU gdb (GDB) 7.5
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-w64-mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.

which is python-enabled using this print.py :
Code
##############################################
# Name:         misc/gdb/print.py
# Purpose:      pretty-printers for wx data structures: this file is meant to
#               be sourced from gdb using "source -p" (or, better, autoloaded
#               in the future...)
# Author:       Vadim Zeitlin
# Created:      2009-01-04
# RCS-Id:       $Id$
# Copyright:    (c) 2009 Vadim Zeitlin
# Licence:      wxWindows licence
##################################################

# Define wxFooPrinter class implementing (at least) to_string() method for each
# wxFoo class we want to pretty print. Then just add wxFoo to the types array
# in wxLookupFunction at the bottom of this file.

import datetime

# shamelessly stolen from std::string example
class wxStringPrinter:
    def __init__(self, val):
        self.val = val

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

    def display_hint(self):
        return 'string'

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

    def to_string(self):
        # A value of type wxLongLong can't be used in Python arithmetic
        # expressions directly so we need to convert it to long long first and
        # then cast to int explicitly to be able to use it as a timestamp.
        msec = self.val['m_time'].cast(gdb.lookup_type('long long'))
        if msec == 0x8000000000000000:
            return 'NONE'
        sec = int(msec / 1000)
        return datetime.datetime.fromtimestamp(sec).isoformat(' ')

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

    def to_string(self):
        # It is simpler to just call the internal function here than to iterate
        # over m_dirs array ourselves. The disadvantage of this approach is
        # that it requires a live inferior process and so doesn't work when
        # debugging using only a core file. If this ever becomes a serious
        # problem, this should be rewritten to use m_dirs and m_name and m_ext.
        return gdb.parse_and_eval('((wxFileName*)%s)->GetFullPath(0)' %
                                  self.val.address)

class wxXYPrinterBase:
    def __init__(self, val):
        self.x = val['x']
        self.y = val['y']

class wxPointPrinter(wxXYPrinterBase):
    def to_string(self):
        return '(%d, %d)' % (self.x, self.y)

class wxSizePrinter(wxXYPrinterBase):
    def to_string(self):
        return '%d*%d' % (self.x, self.y)

class wxRectPrinter(wxXYPrinterBase):
    def __init__(self, val):
        wxXYPrinterBase.__init__(self, val)
        self.width = val['width']
        self.height = val['height']

    def to_string(self):
        return '(%d, %d) %d*%d' % (self.x, self.y, self.width, self.height)


# The function looking up the pretty-printer to use for the given value.
def wxLookupFunction(val):
    # Using a list is probably ok for so few items but consider switching to a
    # set (or a dict and cache class types as the keys in it?) if needed later.
    types = ['wxString',
             'wxDateTime',
             'wxFileName',
             'wxPoint',
             'wxSize',
             'wxRect']

    for t in types:
        if val.type.tag == t:
            # Not sure if this is the best name to create the object of a class
            # by name but at least it beats eval()
            return globals()[t + 'Printer'](val)

    return None

gdb.pretty_printers.append(wxLookupFunction)

and these commands in CodeBlock's debugger initialization setting :
Code
python
import sys
import gdb
sys.path.insert(0,'C:/MinGW64/bin/print')
import print
end
set print pretty 1
« Last Edit: February 11, 2013, 03:27:50 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"]