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