public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* break on C++ global objects ctors
@ 2014-03-26 18:22 Daniel Gutson
  2014-03-31 12:24 ` Daniel Gutson
  0 siblings, 1 reply; 7+ messages in thread
From: Daniel Gutson @ 2014-03-26 18:22 UTC (permalink / raw)
  To: gdb-patches

Hi,

    AFAIK, there is no command to break and debug the construction of
global objects in C++.

I'm looking for an equivalent command to "start" but instead of temp
breaking at the
beginning of main(), breaks at the beginning of every global ctor.

The way I'm currently doing this in GNU Linux/x86_64 is:
  br __static_initialization_and_destruction_0
which is a workaround, with the nice side effect that when asking info br, gdb
shows all the source locations of the global object instances.

I'm not sure whether this could supported by a native gdb feature or by a python
extension.
If there is consensus about the former, I might create some patch.
However, I suspect that this might require some support from collect2 too,
or some libc internals knowledge by gdb.

    Daniel.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: break on C++ global objects ctors
  2014-03-26 18:22 break on C++ global objects ctors Daniel Gutson
@ 2014-03-31 12:24 ` Daniel Gutson
  2014-03-31 13:56   ` Paul_Koning
  0 siblings, 1 reply; 7+ messages in thread
From: Daniel Gutson @ 2014-03-31 12:24 UTC (permalink / raw)
  To: gdb-patches

PING for a maintainer please?

Thanks!

   Daniel.

On Wed, Mar 26, 2014 at 3:22 PM, Daniel Gutson
<daniel.gutson@tallertechnologies.com> wrote:
> Hi,
>
>     AFAIK, there is no command to break and debug the construction of
> global objects in C++.
>
> I'm looking for an equivalent command to "start" but instead of temp
> breaking at the
> beginning of main(), breaks at the beginning of every global ctor.
>
> The way I'm currently doing this in GNU Linux/x86_64 is:
>   br __static_initialization_and_destruction_0
> which is a workaround, with the nice side effect that when asking info br, gdb
> shows all the source locations of the global object instances.
>
> I'm not sure whether this could supported by a native gdb feature or by a python
> extension.
> If there is consensus about the former, I might create some patch.
> However, I suspect that this might require some support from collect2 too,
> or some libc internals knowledge by gdb.
>
>     Daniel.



-- 

Daniel F. Gutson
Chief Engineering Officer, SPD


San Lorenzo 47, 3rd Floor, Office 5

Córdoba, Argentina


Phone: +54 351 4217888 / +54 351 4218211

Skype: dgutson

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: break on C++ global objects ctors
  2014-03-31 12:24 ` Daniel Gutson
@ 2014-03-31 13:56   ` Paul_Koning
  2014-03-31 14:10     ` Daniel Gutson
  0 siblings, 1 reply; 7+ messages in thread
From: Paul_Koning @ 2014-03-31 13:56 UTC (permalink / raw)
  To: daniel.gutson; +Cc: gdb-patches

This certainly should be easily doable, just in gdb.  FWIW, if you start a program with gdbserver and then connect to it from gdb (“target remote” to gdbserver), the program is stopped at the first instruction, way before “main”.  At that point you should be able to set a breakpoint in a constructor and tell it “continue”.

If such a thing were desirable for gdb, the same logic could be used, I would assume.

	paul

On Mar 31, 2014, at 8:24 AM, Daniel Gutson <daniel.gutson@tallertechnologies.com> wrote:

> PING for a maintainer please?
> 
> Thanks!
> 
>   Daniel.
> 
> On Wed, Mar 26, 2014 at 3:22 PM, Daniel Gutson
> <daniel.gutson@tallertechnologies.com> wrote:
>> Hi,
>> 
>>    AFAIK, there is no command to break and debug the construction of
>> global objects in C++.
>> 
>> I'm looking for an equivalent command to "start" but instead of temp
>> breaking at the
>> beginning of main(), breaks at the beginning of every global ctor.
>> 
>> The way I'm currently doing this in GNU Linux/x86_64 is:
>>  br __static_initialization_and_destruction_0
>> which is a workaround, with the nice side effect that when asking info br, gdb
>> shows all the source locations of the global object instances.
>> 
>> I'm not sure whether this could supported by a native gdb feature or by a python
>> extension.
>> If there is consensus about the former, I might create some patch.
>> However, I suspect that this might require some support from collect2 too,
>> or some libc internals knowledge by gdb.
>> 
>>    Daniel.
> 
> 
> 
> -- 
> 
> Daniel F. Gutson
> Chief Engineering Officer, SPD
> 
> 
> San Lorenzo 47, 3rd Floor, Office 5
> 
> Córdoba, Argentina
> 
> 
> Phone: +54 351 4217888 / +54 351 4218211
> 
> Skype: dgutson

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: break on C++ global objects ctors
  2014-03-31 13:56   ` Paul_Koning
@ 2014-03-31 14:10     ` Daniel Gutson
  2014-03-31 14:16       ` Paul_Koning
  0 siblings, 1 reply; 7+ messages in thread
From: Daniel Gutson @ 2014-03-31 14:10 UTC (permalink / raw)
  To: Paul_Koning; +Cc: gdb-patches

On Mon, Mar 31, 2014 at 10:56 AM,  <Paul_Koning@dell.com> wrote:
> This certainly should be easily doable, just in gdb.  FWIW, if you start a program with gdbserver and then connect to it from gdb ("target remote" to gdbserver), the program is stopped at the first instruction, way before "main".

That doesn't solve how gdb detects the beginning of each ctor function.

  At that point you should be able to set a breakpoint in a
constructor and tell it "continue".
>
> If such a thing were desirable for gdb, the same logic could be used, I would assume.
>
>         paul
>
> On Mar 31, 2014, at 8:24 AM, Daniel Gutson <daniel.gutson@tallertechnologies.com> wrote:
>
>> PING for a maintainer please?
>>
>> Thanks!
>>
>>   Daniel.
>>
>> On Wed, Mar 26, 2014 at 3:22 PM, Daniel Gutson
>> <daniel.gutson@tallertechnologies.com> wrote:
>>> Hi,
>>>
>>>    AFAIK, there is no command to break and debug the construction of
>>> global objects in C++.
>>>
>>> I'm looking for an equivalent command to "start" but instead of temp
>>> breaking at the
>>> beginning of main(), breaks at the beginning of every global ctor.
>>>
>>> The way I'm currently doing this in GNU Linux/x86_64 is:
>>>  br __static_initialization_and_destruction_0
>>> which is a workaround, with the nice side effect that when asking info br, gdb
>>> shows all the source locations of the global object instances.
>>>
>>> I'm not sure whether this could supported by a native gdb feature or by a python
>>> extension.
>>> If there is consensus about the former, I might create some patch.
>>> However, I suspect that this might require some support from collect2 too,
>>> or some libc internals knowledge by gdb.
>>>
>>>    Daniel.
>>
>>
>>
>> --
>>
>> Daniel F. Gutson
>> Chief Engineering Officer, SPD
>>
>>
>> San Lorenzo 47, 3rd Floor, Office 5
>>
>> Córdoba, Argentina
>>
>>
>> Phone: +54 351 4217888 / +54 351 4218211
>>
>> Skype: dgutson



-- 

Daniel F. Gutson
Chief Engineering Officer, SPD


San Lorenzo 47, 3rd Floor, Office 5

Córdoba, Argentina


Phone: +54 351 4217888 / +54 351 4218211

Skype: dgutson

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: break on C++ global objects ctors
  2014-03-31 14:10     ` Daniel Gutson
@ 2014-03-31 14:16       ` Paul_Koning
  2014-03-31 14:41         ` Daniel Gutson
  0 siblings, 1 reply; 7+ messages in thread
From: Paul_Koning @ 2014-03-31 14:16 UTC (permalink / raw)
  To: daniel.gutson; +Cc: gdb-patches


On Mar 31, 2014, at 10:10 AM, Daniel Gutson <daniel.gutson@tallertechnologies.com> wrote:

> On Mon, Mar 31, 2014 at 10:56 AM,  <Paul_Koning@dell.com> wrote:
>> This certainly should be easily doable, just in gdb.  FWIW, if you start a program with gdbserver and then connect to it from gdb ("target remote" to gdbserver), the program is stopped at the first instruction, way before "main".
> 
> That doesn't solve how gdb detects the beginning of each ctor function.

I don’t know what problem you’re referring to.  A constructor is just a function, which has a name, and you can set a breakpoint on it.  

If for some reason that’s not working, that would be a bug, but I’ve used breakpoints on constructors for a long time and it seems to work when I try it.

	paul

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: break on C++ global objects ctors
  2014-03-31 14:16       ` Paul_Koning
@ 2014-03-31 14:41         ` Daniel Gutson
  2014-09-26 18:00           ` Daniel Gutson
  0 siblings, 1 reply; 7+ messages in thread
From: Daniel Gutson @ 2014-03-31 14:41 UTC (permalink / raw)
  To: Paul_Koning; +Cc: gdb-patches

On Mon, Mar 31, 2014 at 11:15 AM,  <Paul_Koning@dell.com> wrote:
>
> On Mar 31, 2014, at 10:10 AM, Daniel Gutson <daniel.gutson@tallertechnologies.com> wrote:
>
>> On Mon, Mar 31, 2014 at 10:56 AM,  <Paul_Koning@dell.com> wrote:
>>> This certainly should be easily doable, just in gdb.  FWIW, if you start a program with gdbserver and then connect to it from gdb ("target remote" to gdbserver), the program is stopped at the first instruction, way before "main".
>>
>> That doesn't solve how gdb detects the beginning of each ctor function.
>
> I don't know what problem you're referring to.  A constructor is just a function, which has a name, and you can set a breakpoint on it.
>
> If for some reason that's not working, that would be a bug, but I've used breakpoints on constructors for a long time and it seems to work when I try it.

The issue I need to add is to make gdb break at the beginning of the
construction of each (all)  global object of the program.
Breaking at the beginning of the program does not solve this. Please
see my original with this clarification, so maybe I can be clearer.

One possible solution is: add breaks in the ctors of ALL types, run,
and at main delete all those breakpoints.
Another solution is to do some handling of each
__static_initialization_and_destruction_0 which varies depending on
the context.


>
>         paul



-- 

Daniel F. Gutson
Chief Engineering Officer, SPD


San Lorenzo 47, 3rd Floor, Office 5

Córdoba, Argentina


Phone: +54 351 4217888 / +54 351 4218211

Skype: dgutson

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: break on C++ global objects ctors
  2014-03-31 14:41         ` Daniel Gutson
@ 2014-09-26 18:00           ` Daniel Gutson
  0 siblings, 0 replies; 7+ messages in thread
From: Daniel Gutson @ 2014-09-26 18:00 UTC (permalink / raw)
  To: Paul_Koning; +Cc: gdb-patches, Martin Galvan

[-- Attachment #1: Type: text/plain, Size: 3623 bytes --]

I resurrect this issue since there was no satisfying solution.

We went through the plugin solution, just to check the idea, and maybe
later discuss a native
(maybe gdb-gcc joint) solution.

There were three possible approaches:
  - a regex-based approach, library-implementation independent, so the
plugin does some magic looking for symbols and detecting which one
have, placing breakpoints there, breaking at main and add a command in
main to disable all the previous breakpoints. The attached file is a
plugin that follows this approach.
  - a library-implementation dependent approach, that breaks in all
the __static_initialization_and_destruction_0, then disassemblying
them finding each call to a ctor, placing a breakpoint there with a
"stepi" command. We are tempted to follow this approach but we ran out
of time so we're using the previous one. And we don't know how
portable this is (we checked x86 but need this tool for a number of
other platforms, such as ARM and SPARC). I believe that
__static_initialization_and_destruction_0 is generated for all
platforms and with the same name but I'm not sure.
  - a dwarf-inspection based approach which we didn't deeply explore.

Now, the plugin isn't perfect, has some corner cases, and required a
huge amount of regex magic (specially due to C++ templates).

Is there consensus that this could be done in a native command, such
as "break-global-ctors" (and "break-global-dtors", which the plugin
doesn't address either) ?

Thanks,

   Daniel.

ps: BTW, we found a lot of opportunities to improve of the python API
that would make this plugin much simpler, but that will go to a
separate thread.

On Mon, Mar 31, 2014 at 11:41 AM, Daniel Gutson
<daniel.gutson@tallertechnologies.com> wrote:
> On Mon, Mar 31, 2014 at 11:15 AM,  <Paul_Koning@dell.com> wrote:
>>
>> On Mar 31, 2014, at 10:10 AM, Daniel Gutson <daniel.gutson@tallertechnologies.com> wrote:
>>
>>> On Mon, Mar 31, 2014 at 10:56 AM,  <Paul_Koning@dell.com> wrote:
>>>> This certainly should be easily doable, just in gdb.  FWIW, if you start a program with gdbserver and then connect to it from gdb ("target remote" to gdbserver), the program is stopped at the first instruction, way before "main".
>>>
>>> That doesn't solve how gdb detects the beginning of each ctor function.
>>
>> I don't know what problem you're referring to.  A constructor is just a function, which has a name, and you can set a breakpoint on it.
>>
>> If for some reason that's not working, that would be a bug, but I've used breakpoints on constructors for a long time and it seems to work when I try it.
>
> The issue I need to add is to make gdb break at the beginning of the
> construction of each (all)  global object of the program.
> Breaking at the beginning of the program does not solve this. Please
> see my original with this clarification, so maybe I can be clearer.
>
> One possible solution is: add breaks in the ctors of ALL types, run,
> and at main delete all those breakpoints.
> Another solution is to do some handling of each
> __static_initialization_and_destruction_0 which varies depending on
> the context.
>
>
>>
>>         paul
>
>
>
> --
>
> Daniel F. Gutson
> Chief Engineering Officer, SPD
>
>
> San Lorenzo 47, 3rd Floor, Office 5
>
> Córdoba, Argentina
>
>
> Phone: +54 351 4217888 / +54 351 4218211
>
> Skype: dgutson



-- 

Daniel F. Gutson
Chief Engineering Officer, SPD


San Lorenzo 47, 3rd Floor, Office 5

Córdoba, Argentina


Phone: +54 351 4217888 / +54 351 4218211

Skype: dgutson

[-- Attachment #2: BreakAtGlobals.py --]
[-- Type: text/x-python, Size: 3085 bytes --]

# BreakAtGlobals.py: A GDB script for setting breakpoints at global constructors.
#
# Copyright (C) 2014 Martin Galvan, Daniel Gutson, Taller Technologies.
#
# BreakAtGlobals is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BreakAtGlobals is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BreakAtGlobals.  If not, see <http://www.gnu.org/licenses/>.

import re
import gdb

class MainBreakpoint(gdb.Breakpoint):
    def stop(self):

        for breakpointNumber in range(1, self.number):
            gdb.execute("delete " + str(breakpointNumber))

        return False

def breakAtGlobals():
    gdb.execute("set confirm off")
    gdb.execute("set pagination off")
    gdb.execute("set logging overwrite on")
    gdb.execute("set logging file breakAtGlobalsTmp.txt")
    gdb.execute("set logging redirect on")
    gdb.execute("set logging on")
    gdb.execute("info types")
    gdb.execute("set logging off")

    with open("breakAtGlobalsTmp.txt", "r") as outputLog:
        typeNames = getTypes(outputLog)

    constructors = getConstructors(typeNames)

    for constructor in constructors:
        gdb.execute("rbreak " + constructor + "*")

    MainBreakpoint("main")

def getTypes(outputLog):
    definedTypes = set()
    typeNames = []
    skipNextLine = True  # Skip the first line.

    for line in outputLog:
        if skipNextLine:
            skipNextLine = False
        elif line == "\n":  # An empty line is always followed by a useless line. Skip it.
            skipNextLine = True
        elif "typedef" not in line:  # This line contains a type name. Skip typedefs.
            definedTypes.add(line.rstrip(";\n"))

    for definedType in definedTypes:
        gdbType = gdb.types.get_basic_type(gdb.lookup_type(definedType))
        typeNames.append(gdbType.name)

    return typeNames

def getConstructors(typeNames):
    constructors = []
    finalConstructors = []

    # Append the class name to the type.
    for typeName in typeNames:
        if "::" in typeName:  # Our type is inside a namespace. Extract the class name from the full type name.
            className = typeName.rpartition("::")[2]
        else:
            className = typeName

        constructors.append(typeName + "::" + className)

    for constructor in constructors:
        finalConstructors.append(removeTemplateArguments(constructor))

    return finalConstructors

# Template classes have a <(some type)> at the end.
def removeTemplateArguments(constructor):
    match = None

    for match in re.finditer("(<.*?>)", constructor):
        pass

    if match:
        constructor = constructor[:match.start()]

    return constructor

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2014-09-26 18:00 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-26 18:22 break on C++ global objects ctors Daniel Gutson
2014-03-31 12:24 ` Daniel Gutson
2014-03-31 13:56   ` Paul_Koning
2014-03-31 14:10     ` Daniel Gutson
2014-03-31 14:16       ` Paul_Koning
2014-03-31 14:41         ` Daniel Gutson
2014-09-26 18:00           ` Daniel Gutson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).