1*ef5ccd6cSJohn Marino# GDB 'explore' command. 2*ef5ccd6cSJohn Marino# Copyright (C) 2012-2013 Free Software Foundation, Inc. 3*ef5ccd6cSJohn Marino 4*ef5ccd6cSJohn Marino# This program is free software; you can redistribute it and/or modify 5*ef5ccd6cSJohn Marino# it under the terms of the GNU General Public License as published by 6*ef5ccd6cSJohn Marino# the Free Software Foundation; either version 3 of the License, or 7*ef5ccd6cSJohn Marino# (at your option) any later version. 8*ef5ccd6cSJohn Marino# 9*ef5ccd6cSJohn Marino# This program is distributed in the hope that it will be useful, 10*ef5ccd6cSJohn Marino# but WITHOUT ANY WARRANTY; without even the implied warranty of 11*ef5ccd6cSJohn Marino# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12*ef5ccd6cSJohn Marino# GNU General Public License for more details. 13*ef5ccd6cSJohn Marino# 14*ef5ccd6cSJohn Marino# You should have received a copy of the GNU General Public License 15*ef5ccd6cSJohn Marino# along with this program. If not, see <http://www.gnu.org/licenses/>. 16*ef5ccd6cSJohn Marino 17*ef5ccd6cSJohn Marino"""Implementation of the GDB 'explore' command using the GDB Python API.""" 18*ef5ccd6cSJohn Marino 19*ef5ccd6cSJohn Marinoimport gdb 20*ef5ccd6cSJohn Marinoimport sys 21*ef5ccd6cSJohn Marino 22*ef5ccd6cSJohn Marinoif sys.version_info[0] > 2: 23*ef5ccd6cSJohn Marino # Python 3 renamed raw_input to input 24*ef5ccd6cSJohn Marino raw_input = input 25*ef5ccd6cSJohn Marino 26*ef5ccd6cSJohn Marinoclass Explorer(object): 27*ef5ccd6cSJohn Marino """Internal class which invokes other explorers.""" 28*ef5ccd6cSJohn Marino 29*ef5ccd6cSJohn Marino # This map is filled by the Explorer.init_env() function 30*ef5ccd6cSJohn Marino type_code_to_explorer_map = { } 31*ef5ccd6cSJohn Marino 32*ef5ccd6cSJohn Marino _SCALAR_TYPE_LIST = ( 33*ef5ccd6cSJohn Marino gdb.TYPE_CODE_CHAR, 34*ef5ccd6cSJohn Marino gdb.TYPE_CODE_INT, 35*ef5ccd6cSJohn Marino gdb.TYPE_CODE_BOOL, 36*ef5ccd6cSJohn Marino gdb.TYPE_CODE_FLT, 37*ef5ccd6cSJohn Marino gdb.TYPE_CODE_VOID, 38*ef5ccd6cSJohn Marino gdb.TYPE_CODE_ENUM, 39*ef5ccd6cSJohn Marino ) 40*ef5ccd6cSJohn Marino 41*ef5ccd6cSJohn Marino @staticmethod 42*ef5ccd6cSJohn Marino def guard_expr(expr): 43*ef5ccd6cSJohn Marino length = len(expr) 44*ef5ccd6cSJohn Marino guard = False 45*ef5ccd6cSJohn Marino 46*ef5ccd6cSJohn Marino if expr[0] == '(' and expr[length-1] == ')': 47*ef5ccd6cSJohn Marino pass 48*ef5ccd6cSJohn Marino else: 49*ef5ccd6cSJohn Marino i = 0 50*ef5ccd6cSJohn Marino while i < length: 51*ef5ccd6cSJohn Marino c = expr[i] 52*ef5ccd6cSJohn Marino if (c == '_' or ('a' <= c and c <= 'z') or 53*ef5ccd6cSJohn Marino ('A' <= c and c <= 'Z') or ('0' <= c and c <= '9')): 54*ef5ccd6cSJohn Marino pass 55*ef5ccd6cSJohn Marino else: 56*ef5ccd6cSJohn Marino guard = True 57*ef5ccd6cSJohn Marino break 58*ef5ccd6cSJohn Marino i += 1 59*ef5ccd6cSJohn Marino 60*ef5ccd6cSJohn Marino if guard: 61*ef5ccd6cSJohn Marino return "(" + expr + ")" 62*ef5ccd6cSJohn Marino else: 63*ef5ccd6cSJohn Marino return expr 64*ef5ccd6cSJohn Marino 65*ef5ccd6cSJohn Marino @staticmethod 66*ef5ccd6cSJohn Marino def explore_expr(expr, value, is_child): 67*ef5ccd6cSJohn Marino """Main function to explore an expression value. 68*ef5ccd6cSJohn Marino 69*ef5ccd6cSJohn Marino Arguments: 70*ef5ccd6cSJohn Marino expr: The expression string that is being explored. 71*ef5ccd6cSJohn Marino value: The gdb.Value value of the expression. 72*ef5ccd6cSJohn Marino is_child: Boolean value to indicate if the expression is a child. 73*ef5ccd6cSJohn Marino An expression is a child if it is derived from the main 74*ef5ccd6cSJohn Marino expression entered by the user. For example, if the user 75*ef5ccd6cSJohn Marino entered an expression which evaluates to a struct, then 76*ef5ccd6cSJohn Marino when exploring the fields of the struct, is_child is set 77*ef5ccd6cSJohn Marino to True internally. 78*ef5ccd6cSJohn Marino 79*ef5ccd6cSJohn Marino Returns: 80*ef5ccd6cSJohn Marino No return value. 81*ef5ccd6cSJohn Marino """ 82*ef5ccd6cSJohn Marino type_code = value.type.code 83*ef5ccd6cSJohn Marino if type_code in Explorer.type_code_to_explorer_map: 84*ef5ccd6cSJohn Marino explorer_class = Explorer.type_code_to_explorer_map[type_code] 85*ef5ccd6cSJohn Marino while explorer_class.explore_expr(expr, value, is_child): 86*ef5ccd6cSJohn Marino pass 87*ef5ccd6cSJohn Marino else: 88*ef5ccd6cSJohn Marino print ("Explorer for type '%s' not yet available.\n" % 89*ef5ccd6cSJohn Marino str(value.type)) 90*ef5ccd6cSJohn Marino 91*ef5ccd6cSJohn Marino @staticmethod 92*ef5ccd6cSJohn Marino def explore_type(name, datatype, is_child): 93*ef5ccd6cSJohn Marino """Main function to explore a data type. 94*ef5ccd6cSJohn Marino 95*ef5ccd6cSJohn Marino Arguments: 96*ef5ccd6cSJohn Marino name: The string representing the path to the data type being 97*ef5ccd6cSJohn Marino explored. 98*ef5ccd6cSJohn Marino datatype: The gdb.Type value of the data type being explored. 99*ef5ccd6cSJohn Marino is_child: Boolean value to indicate if the name is a child. 100*ef5ccd6cSJohn Marino A name is a child if it is derived from the main name 101*ef5ccd6cSJohn Marino entered by the user. For example, if the user entered 102*ef5ccd6cSJohn Marino the name of struct type, then when exploring the fields 103*ef5ccd6cSJohn Marino of the struct, is_child is set to True internally. 104*ef5ccd6cSJohn Marino 105*ef5ccd6cSJohn Marino Returns: 106*ef5ccd6cSJohn Marino No return value. 107*ef5ccd6cSJohn Marino """ 108*ef5ccd6cSJohn Marino type_code = datatype.code 109*ef5ccd6cSJohn Marino if type_code in Explorer.type_code_to_explorer_map: 110*ef5ccd6cSJohn Marino explorer_class = Explorer.type_code_to_explorer_map[type_code] 111*ef5ccd6cSJohn Marino while explorer_class.explore_type(name, datatype, is_child): 112*ef5ccd6cSJohn Marino pass 113*ef5ccd6cSJohn Marino else: 114*ef5ccd6cSJohn Marino print ("Explorer for type '%s' not yet available.\n" % 115*ef5ccd6cSJohn Marino str(datatype)) 116*ef5ccd6cSJohn Marino 117*ef5ccd6cSJohn Marino @staticmethod 118*ef5ccd6cSJohn Marino def init_env(): 119*ef5ccd6cSJohn Marino """Initializes the Explorer environment. 120*ef5ccd6cSJohn Marino This function should be invoked before starting any exploration. If 121*ef5ccd6cSJohn Marino invoked before an exploration, it need not be invoked for subsequent 122*ef5ccd6cSJohn Marino explorations. 123*ef5ccd6cSJohn Marino """ 124*ef5ccd6cSJohn Marino Explorer.type_code_to_explorer_map = { 125*ef5ccd6cSJohn Marino gdb.TYPE_CODE_CHAR : ScalarExplorer, 126*ef5ccd6cSJohn Marino gdb.TYPE_CODE_INT : ScalarExplorer, 127*ef5ccd6cSJohn Marino gdb.TYPE_CODE_BOOL : ScalarExplorer, 128*ef5ccd6cSJohn Marino gdb.TYPE_CODE_FLT : ScalarExplorer, 129*ef5ccd6cSJohn Marino gdb.TYPE_CODE_VOID : ScalarExplorer, 130*ef5ccd6cSJohn Marino gdb.TYPE_CODE_ENUM : ScalarExplorer, 131*ef5ccd6cSJohn Marino gdb.TYPE_CODE_STRUCT : CompoundExplorer, 132*ef5ccd6cSJohn Marino gdb.TYPE_CODE_UNION : CompoundExplorer, 133*ef5ccd6cSJohn Marino gdb.TYPE_CODE_PTR : PointerExplorer, 134*ef5ccd6cSJohn Marino gdb.TYPE_CODE_REF : ReferenceExplorer, 135*ef5ccd6cSJohn Marino gdb.TYPE_CODE_TYPEDEF : TypedefExplorer, 136*ef5ccd6cSJohn Marino gdb.TYPE_CODE_ARRAY : ArrayExplorer 137*ef5ccd6cSJohn Marino } 138*ef5ccd6cSJohn Marino 139*ef5ccd6cSJohn Marino @staticmethod 140*ef5ccd6cSJohn Marino def is_scalar_type(type): 141*ef5ccd6cSJohn Marino """Checks whether a type is a scalar type. 142*ef5ccd6cSJohn Marino A type is a scalar type of its type is 143*ef5ccd6cSJohn Marino gdb.TYPE_CODE_CHAR or 144*ef5ccd6cSJohn Marino gdb.TYPE_CODE_INT or 145*ef5ccd6cSJohn Marino gdb.TYPE_CODE_BOOL or 146*ef5ccd6cSJohn Marino gdb.TYPE_CODE_FLT or 147*ef5ccd6cSJohn Marino gdb.TYPE_CODE_VOID or 148*ef5ccd6cSJohn Marino gdb.TYPE_CODE_ENUM. 149*ef5ccd6cSJohn Marino 150*ef5ccd6cSJohn Marino Arguments: 151*ef5ccd6cSJohn Marino type: The type to be checked. 152*ef5ccd6cSJohn Marino 153*ef5ccd6cSJohn Marino Returns: 154*ef5ccd6cSJohn Marino 'True' if 'type' is a scalar type. 'False' otherwise. 155*ef5ccd6cSJohn Marino """ 156*ef5ccd6cSJohn Marino return type.code in Explorer._SCALAR_TYPE_LIST 157*ef5ccd6cSJohn Marino 158*ef5ccd6cSJohn Marino @staticmethod 159*ef5ccd6cSJohn Marino def return_to_parent_value(): 160*ef5ccd6cSJohn Marino """A utility function which prints that the current exploration session 161*ef5ccd6cSJohn Marino is returning to the parent value. Useful when exploring values. 162*ef5ccd6cSJohn Marino """ 163*ef5ccd6cSJohn Marino print ("\nReturning to parent value...\n") 164*ef5ccd6cSJohn Marino 165*ef5ccd6cSJohn Marino @staticmethod 166*ef5ccd6cSJohn Marino def return_to_parent_value_prompt(): 167*ef5ccd6cSJohn Marino """A utility function which prompts the user to press the 'enter' key 168*ef5ccd6cSJohn Marino so that the exploration session can shift back to the parent value. 169*ef5ccd6cSJohn Marino Useful when exploring values. 170*ef5ccd6cSJohn Marino """ 171*ef5ccd6cSJohn Marino raw_input("\nPress enter to return to parent value: ") 172*ef5ccd6cSJohn Marino 173*ef5ccd6cSJohn Marino @staticmethod 174*ef5ccd6cSJohn Marino def return_to_enclosing_type(): 175*ef5ccd6cSJohn Marino """A utility function which prints that the current exploration session 176*ef5ccd6cSJohn Marino is returning to the enclosing type. Useful when exploring types. 177*ef5ccd6cSJohn Marino """ 178*ef5ccd6cSJohn Marino print ("\nReturning to enclosing type...\n") 179*ef5ccd6cSJohn Marino 180*ef5ccd6cSJohn Marino @staticmethod 181*ef5ccd6cSJohn Marino def return_to_enclosing_type_prompt(): 182*ef5ccd6cSJohn Marino """A utility function which prompts the user to press the 'enter' key 183*ef5ccd6cSJohn Marino so that the exploration session can shift back to the enclosing type. 184*ef5ccd6cSJohn Marino Useful when exploring types. 185*ef5ccd6cSJohn Marino """ 186*ef5ccd6cSJohn Marino raw_input("\nPress enter to return to enclosing type: ") 187*ef5ccd6cSJohn Marino 188*ef5ccd6cSJohn Marino 189*ef5ccd6cSJohn Marinoclass ScalarExplorer(object): 190*ef5ccd6cSJohn Marino """Internal class used to explore scalar values.""" 191*ef5ccd6cSJohn Marino 192*ef5ccd6cSJohn Marino @staticmethod 193*ef5ccd6cSJohn Marino def explore_expr(expr, value, is_child): 194*ef5ccd6cSJohn Marino """Function to explore scalar values. 195*ef5ccd6cSJohn Marino See Explorer.explore_expr and Explorer.is_scalar_type for more 196*ef5ccd6cSJohn Marino information. 197*ef5ccd6cSJohn Marino """ 198*ef5ccd6cSJohn Marino print ("'%s' is a scalar value of type '%s'." % 199*ef5ccd6cSJohn Marino (expr, value.type)) 200*ef5ccd6cSJohn Marino print ("%s = %s" % (expr, str(value))) 201*ef5ccd6cSJohn Marino 202*ef5ccd6cSJohn Marino if is_child: 203*ef5ccd6cSJohn Marino Explorer.return_to_parent_value_prompt() 204*ef5ccd6cSJohn Marino Explorer.return_to_parent_value() 205*ef5ccd6cSJohn Marino 206*ef5ccd6cSJohn Marino return False 207*ef5ccd6cSJohn Marino 208*ef5ccd6cSJohn Marino @staticmethod 209*ef5ccd6cSJohn Marino def explore_type(name, datatype, is_child): 210*ef5ccd6cSJohn Marino """Function to explore scalar types. 211*ef5ccd6cSJohn Marino See Explorer.explore_type and Explorer.is_scalar_type for more 212*ef5ccd6cSJohn Marino information. 213*ef5ccd6cSJohn Marino """ 214*ef5ccd6cSJohn Marino if datatype.code == gdb.TYPE_CODE_ENUM: 215*ef5ccd6cSJohn Marino if is_child: 216*ef5ccd6cSJohn Marino print ("%s is of an enumerated type '%s'." % 217*ef5ccd6cSJohn Marino (name, str(datatype))) 218*ef5ccd6cSJohn Marino else: 219*ef5ccd6cSJohn Marino print ("'%s' is an enumerated type." % name) 220*ef5ccd6cSJohn Marino else: 221*ef5ccd6cSJohn Marino if is_child: 222*ef5ccd6cSJohn Marino print ("%s is of a scalar type '%s'." % 223*ef5ccd6cSJohn Marino (name, str(datatype))) 224*ef5ccd6cSJohn Marino else: 225*ef5ccd6cSJohn Marino print ("'%s' is a scalar type." % name) 226*ef5ccd6cSJohn Marino 227*ef5ccd6cSJohn Marino if is_child: 228*ef5ccd6cSJohn Marino Explorer.return_to_enclosing_type_prompt() 229*ef5ccd6cSJohn Marino Explorer.return_to_enclosing_type() 230*ef5ccd6cSJohn Marino 231*ef5ccd6cSJohn Marino return False 232*ef5ccd6cSJohn Marino 233*ef5ccd6cSJohn Marino 234*ef5ccd6cSJohn Marinoclass PointerExplorer(object): 235*ef5ccd6cSJohn Marino """Internal class used to explore pointer values.""" 236*ef5ccd6cSJohn Marino 237*ef5ccd6cSJohn Marino @staticmethod 238*ef5ccd6cSJohn Marino def explore_expr(expr, value, is_child): 239*ef5ccd6cSJohn Marino """Function to explore pointer values. 240*ef5ccd6cSJohn Marino See Explorer.explore_expr for more information. 241*ef5ccd6cSJohn Marino """ 242*ef5ccd6cSJohn Marino print ("'%s' is a pointer to a value of type '%s'" % 243*ef5ccd6cSJohn Marino (expr, str(value.type.target()))) 244*ef5ccd6cSJohn Marino option = raw_input("Continue exploring it as a pointer to a single " 245*ef5ccd6cSJohn Marino "value [y/n]: ") 246*ef5ccd6cSJohn Marino if option == "y": 247*ef5ccd6cSJohn Marino deref_value = None 248*ef5ccd6cSJohn Marino try: 249*ef5ccd6cSJohn Marino deref_value = value.dereference() 250*ef5ccd6cSJohn Marino str(deref_value) 251*ef5ccd6cSJohn Marino except gdb.MemoryError: 252*ef5ccd6cSJohn Marino print ("'%s' a pointer pointing to an invalid memory " 253*ef5ccd6cSJohn Marino "location." % expr) 254*ef5ccd6cSJohn Marino if is_child: 255*ef5ccd6cSJohn Marino Explorer.return_to_parent_value_prompt() 256*ef5ccd6cSJohn Marino return False 257*ef5ccd6cSJohn Marino Explorer.explore_expr("*%s" % Explorer.guard_expr(expr), 258*ef5ccd6cSJohn Marino deref_value, is_child) 259*ef5ccd6cSJohn Marino return False 260*ef5ccd6cSJohn Marino 261*ef5ccd6cSJohn Marino option = raw_input("Continue exploring it as a pointer to an " 262*ef5ccd6cSJohn Marino "array [y/n]: ") 263*ef5ccd6cSJohn Marino if option == "y": 264*ef5ccd6cSJohn Marino while True: 265*ef5ccd6cSJohn Marino index = 0 266*ef5ccd6cSJohn Marino try: 267*ef5ccd6cSJohn Marino index = int(raw_input("Enter the index of the element you " 268*ef5ccd6cSJohn Marino "want to explore in '%s': " % expr)) 269*ef5ccd6cSJohn Marino except ValueError: 270*ef5ccd6cSJohn Marino break 271*ef5ccd6cSJohn Marino element_expr = "%s[%d]" % (Explorer.guard_expr(expr), index) 272*ef5ccd6cSJohn Marino element = value[index] 273*ef5ccd6cSJohn Marino try: 274*ef5ccd6cSJohn Marino str(element) 275*ef5ccd6cSJohn Marino except gdb.MemoryError: 276*ef5ccd6cSJohn Marino print ("Cannot read value at index %d." % index) 277*ef5ccd6cSJohn Marino continue 278*ef5ccd6cSJohn Marino Explorer.explore_expr(element_expr, element, True) 279*ef5ccd6cSJohn Marino return False 280*ef5ccd6cSJohn Marino 281*ef5ccd6cSJohn Marino if is_child: 282*ef5ccd6cSJohn Marino Explorer.return_to_parent_value() 283*ef5ccd6cSJohn Marino return False 284*ef5ccd6cSJohn Marino 285*ef5ccd6cSJohn Marino @staticmethod 286*ef5ccd6cSJohn Marino def explore_type(name, datatype, is_child): 287*ef5ccd6cSJohn Marino """Function to explore pointer types. 288*ef5ccd6cSJohn Marino See Explorer.explore_type for more information. 289*ef5ccd6cSJohn Marino """ 290*ef5ccd6cSJohn Marino target_type = datatype.target() 291*ef5ccd6cSJohn Marino print ("\n%s is a pointer to a value of type '%s'." % 292*ef5ccd6cSJohn Marino (name, str(target_type))) 293*ef5ccd6cSJohn Marino 294*ef5ccd6cSJohn Marino Explorer.explore_type("the pointee type of %s" % name, 295*ef5ccd6cSJohn Marino target_type, 296*ef5ccd6cSJohn Marino is_child) 297*ef5ccd6cSJohn Marino return False 298*ef5ccd6cSJohn Marino 299*ef5ccd6cSJohn Marino 300*ef5ccd6cSJohn Marinoclass ReferenceExplorer(object): 301*ef5ccd6cSJohn Marino """Internal class used to explore reference (TYPE_CODE_REF) values.""" 302*ef5ccd6cSJohn Marino 303*ef5ccd6cSJohn Marino @staticmethod 304*ef5ccd6cSJohn Marino def explore_expr(expr, value, is_child): 305*ef5ccd6cSJohn Marino """Function to explore array values. 306*ef5ccd6cSJohn Marino See Explorer.explore_expr for more information. 307*ef5ccd6cSJohn Marino """ 308*ef5ccd6cSJohn Marino referenced_value = value.referenced_value() 309*ef5ccd6cSJohn Marino Explorer.explore_expr(expr, referenced_value, is_child) 310*ef5ccd6cSJohn Marino return False 311*ef5ccd6cSJohn Marino 312*ef5ccd6cSJohn Marino @staticmethod 313*ef5ccd6cSJohn Marino def explore_type(name, datatype, is_child): 314*ef5ccd6cSJohn Marino """Function to explore pointer types. 315*ef5ccd6cSJohn Marino See Explorer.explore_type for more information. 316*ef5ccd6cSJohn Marino """ 317*ef5ccd6cSJohn Marino target_type = datatype.target() 318*ef5ccd6cSJohn Marino Explorer.explore_type(name, target_type, is_child) 319*ef5ccd6cSJohn Marino return False 320*ef5ccd6cSJohn Marino 321*ef5ccd6cSJohn Marino 322*ef5ccd6cSJohn Marinoclass ArrayExplorer(object): 323*ef5ccd6cSJohn Marino """Internal class used to explore arrays.""" 324*ef5ccd6cSJohn Marino 325*ef5ccd6cSJohn Marino @staticmethod 326*ef5ccd6cSJohn Marino def explore_expr(expr, value, is_child): 327*ef5ccd6cSJohn Marino """Function to explore array values. 328*ef5ccd6cSJohn Marino See Explorer.explore_expr for more information. 329*ef5ccd6cSJohn Marino """ 330*ef5ccd6cSJohn Marino target_type = value.type.target() 331*ef5ccd6cSJohn Marino print ("'%s' is an array of '%s'." % (expr, str(target_type))) 332*ef5ccd6cSJohn Marino index = 0 333*ef5ccd6cSJohn Marino try: 334*ef5ccd6cSJohn Marino index = int(raw_input("Enter the index of the element you want to " 335*ef5ccd6cSJohn Marino "explore in '%s': " % expr)) 336*ef5ccd6cSJohn Marino except ValueError: 337*ef5ccd6cSJohn Marino if is_child: 338*ef5ccd6cSJohn Marino Explorer.return_to_parent_value() 339*ef5ccd6cSJohn Marino return False 340*ef5ccd6cSJohn Marino 341*ef5ccd6cSJohn Marino element = None 342*ef5ccd6cSJohn Marino try: 343*ef5ccd6cSJohn Marino element = value[index] 344*ef5ccd6cSJohn Marino str(element) 345*ef5ccd6cSJohn Marino except gdb.MemoryError: 346*ef5ccd6cSJohn Marino print ("Cannot read value at index %d." % index) 347*ef5ccd6cSJohn Marino raw_input("Press enter to continue... ") 348*ef5ccd6cSJohn Marino return True 349*ef5ccd6cSJohn Marino 350*ef5ccd6cSJohn Marino Explorer.explore_expr("%s[%d]" % (Explorer.guard_expr(expr), index), 351*ef5ccd6cSJohn Marino element, True) 352*ef5ccd6cSJohn Marino return True 353*ef5ccd6cSJohn Marino 354*ef5ccd6cSJohn Marino @staticmethod 355*ef5ccd6cSJohn Marino def explore_type(name, datatype, is_child): 356*ef5ccd6cSJohn Marino """Function to explore array types. 357*ef5ccd6cSJohn Marino See Explorer.explore_type for more information. 358*ef5ccd6cSJohn Marino """ 359*ef5ccd6cSJohn Marino target_type = datatype.target() 360*ef5ccd6cSJohn Marino print ("%s is an array of '%s'." % (name, str(target_type))) 361*ef5ccd6cSJohn Marino 362*ef5ccd6cSJohn Marino Explorer.explore_type("the array element of %s" % name, target_type, 363*ef5ccd6cSJohn Marino is_child) 364*ef5ccd6cSJohn Marino return False 365*ef5ccd6cSJohn Marino 366*ef5ccd6cSJohn Marino 367*ef5ccd6cSJohn Marinoclass CompoundExplorer(object): 368*ef5ccd6cSJohn Marino """Internal class used to explore struct, classes and unions.""" 369*ef5ccd6cSJohn Marino 370*ef5ccd6cSJohn Marino @staticmethod 371*ef5ccd6cSJohn Marino def _print_fields(print_list): 372*ef5ccd6cSJohn Marino """Internal function which prints the fields of a struct/class/union. 373*ef5ccd6cSJohn Marino """ 374*ef5ccd6cSJohn Marino max_field_name_length = 0 375*ef5ccd6cSJohn Marino for pair in print_list: 376*ef5ccd6cSJohn Marino if max_field_name_length < len(pair[0]): 377*ef5ccd6cSJohn Marino max_field_name_length = len(pair[0]) 378*ef5ccd6cSJohn Marino 379*ef5ccd6cSJohn Marino for pair in print_list: 380*ef5ccd6cSJohn Marino print (" %*s = %s" % (max_field_name_length, pair[0], pair[1])) 381*ef5ccd6cSJohn Marino 382*ef5ccd6cSJohn Marino @staticmethod 383*ef5ccd6cSJohn Marino def _get_real_field_count(fields): 384*ef5ccd6cSJohn Marino real_field_count = 0; 385*ef5ccd6cSJohn Marino for field in fields: 386*ef5ccd6cSJohn Marino if not field.artificial: 387*ef5ccd6cSJohn Marino real_field_count = real_field_count + 1 388*ef5ccd6cSJohn Marino 389*ef5ccd6cSJohn Marino return real_field_count 390*ef5ccd6cSJohn Marino 391*ef5ccd6cSJohn Marino @staticmethod 392*ef5ccd6cSJohn Marino def explore_expr(expr, value, is_child): 393*ef5ccd6cSJohn Marino """Function to explore structs/classes and union values. 394*ef5ccd6cSJohn Marino See Explorer.explore_expr for more information. 395*ef5ccd6cSJohn Marino """ 396*ef5ccd6cSJohn Marino datatype = value.type 397*ef5ccd6cSJohn Marino type_code = datatype.code 398*ef5ccd6cSJohn Marino fields = datatype.fields() 399*ef5ccd6cSJohn Marino 400*ef5ccd6cSJohn Marino if type_code == gdb.TYPE_CODE_STRUCT: 401*ef5ccd6cSJohn Marino type_desc = "struct/class" 402*ef5ccd6cSJohn Marino else: 403*ef5ccd6cSJohn Marino type_desc = "union" 404*ef5ccd6cSJohn Marino 405*ef5ccd6cSJohn Marino if CompoundExplorer._get_real_field_count(fields) == 0: 406*ef5ccd6cSJohn Marino print ("The value of '%s' is a %s of type '%s' with no fields." % 407*ef5ccd6cSJohn Marino (expr, type_desc, str(value.type))) 408*ef5ccd6cSJohn Marino if is_child: 409*ef5ccd6cSJohn Marino Explorer.return_to_parent_value_prompt() 410*ef5ccd6cSJohn Marino return False 411*ef5ccd6cSJohn Marino 412*ef5ccd6cSJohn Marino print ("The value of '%s' is a %s of type '%s' with the following " 413*ef5ccd6cSJohn Marino "fields:\n" % (expr, type_desc, str(value.type))) 414*ef5ccd6cSJohn Marino 415*ef5ccd6cSJohn Marino has_explorable_fields = False 416*ef5ccd6cSJohn Marino choice_to_compound_field_map = { } 417*ef5ccd6cSJohn Marino current_choice = 0 418*ef5ccd6cSJohn Marino print_list = [ ] 419*ef5ccd6cSJohn Marino for field in fields: 420*ef5ccd6cSJohn Marino if field.artificial: 421*ef5ccd6cSJohn Marino continue 422*ef5ccd6cSJohn Marino field_full_name = Explorer.guard_expr(expr) + "." + field.name 423*ef5ccd6cSJohn Marino if field.is_base_class: 424*ef5ccd6cSJohn Marino field_value = value.cast(field.type) 425*ef5ccd6cSJohn Marino else: 426*ef5ccd6cSJohn Marino field_value = value[field.name] 427*ef5ccd6cSJohn Marino literal_value = "" 428*ef5ccd6cSJohn Marino if type_code == gdb.TYPE_CODE_UNION: 429*ef5ccd6cSJohn Marino literal_value = ("<Enter %d to explore this field of type " 430*ef5ccd6cSJohn Marino "'%s'>" % (current_choice, str(field.type))) 431*ef5ccd6cSJohn Marino has_explorable_fields = True 432*ef5ccd6cSJohn Marino else: 433*ef5ccd6cSJohn Marino if Explorer.is_scalar_type(field.type): 434*ef5ccd6cSJohn Marino literal_value = ("%s .. (Value of type '%s')" % 435*ef5ccd6cSJohn Marino (str(field_value), str(field.type))) 436*ef5ccd6cSJohn Marino else: 437*ef5ccd6cSJohn Marino if field.is_base_class: 438*ef5ccd6cSJohn Marino field_desc = "base class" 439*ef5ccd6cSJohn Marino else: 440*ef5ccd6cSJohn Marino field_desc = "field" 441*ef5ccd6cSJohn Marino literal_value = ("<Enter %d to explore this %s of type " 442*ef5ccd6cSJohn Marino "'%s'>" % 443*ef5ccd6cSJohn Marino (current_choice, field_desc, 444*ef5ccd6cSJohn Marino str(field.type))) 445*ef5ccd6cSJohn Marino has_explorable_fields = True 446*ef5ccd6cSJohn Marino 447*ef5ccd6cSJohn Marino choice_to_compound_field_map[str(current_choice)] = ( 448*ef5ccd6cSJohn Marino field_full_name, field_value) 449*ef5ccd6cSJohn Marino current_choice = current_choice + 1 450*ef5ccd6cSJohn Marino 451*ef5ccd6cSJohn Marino print_list.append((field.name, literal_value)) 452*ef5ccd6cSJohn Marino 453*ef5ccd6cSJohn Marino CompoundExplorer._print_fields(print_list) 454*ef5ccd6cSJohn Marino print ("") 455*ef5ccd6cSJohn Marino 456*ef5ccd6cSJohn Marino if has_explorable_fields: 457*ef5ccd6cSJohn Marino choice = raw_input("Enter the field number of choice: ") 458*ef5ccd6cSJohn Marino if choice in choice_to_compound_field_map: 459*ef5ccd6cSJohn Marino Explorer.explore_expr(choice_to_compound_field_map[choice][0], 460*ef5ccd6cSJohn Marino choice_to_compound_field_map[choice][1], 461*ef5ccd6cSJohn Marino True) 462*ef5ccd6cSJohn Marino return True 463*ef5ccd6cSJohn Marino else: 464*ef5ccd6cSJohn Marino if is_child: 465*ef5ccd6cSJohn Marino Explorer.return_to_parent_value() 466*ef5ccd6cSJohn Marino else: 467*ef5ccd6cSJohn Marino if is_child: 468*ef5ccd6cSJohn Marino Explorer.return_to_parent_value_prompt() 469*ef5ccd6cSJohn Marino 470*ef5ccd6cSJohn Marino return False 471*ef5ccd6cSJohn Marino 472*ef5ccd6cSJohn Marino @staticmethod 473*ef5ccd6cSJohn Marino def explore_type(name, datatype, is_child): 474*ef5ccd6cSJohn Marino """Function to explore struct/class and union types. 475*ef5ccd6cSJohn Marino See Explorer.explore_type for more information. 476*ef5ccd6cSJohn Marino """ 477*ef5ccd6cSJohn Marino type_code = datatype.code 478*ef5ccd6cSJohn Marino type_desc = "" 479*ef5ccd6cSJohn Marino if type_code == gdb.TYPE_CODE_STRUCT: 480*ef5ccd6cSJohn Marino type_desc = "struct/class" 481*ef5ccd6cSJohn Marino else: 482*ef5ccd6cSJohn Marino type_desc = "union" 483*ef5ccd6cSJohn Marino 484*ef5ccd6cSJohn Marino fields = datatype.fields() 485*ef5ccd6cSJohn Marino if CompoundExplorer._get_real_field_count(fields) == 0: 486*ef5ccd6cSJohn Marino if is_child: 487*ef5ccd6cSJohn Marino print ("%s is a %s of type '%s' with no fields." % 488*ef5ccd6cSJohn Marino (name, type_desc, str(datatype))) 489*ef5ccd6cSJohn Marino Explorer.return_to_enclosing_type_prompt() 490*ef5ccd6cSJohn Marino else: 491*ef5ccd6cSJohn Marino print ("'%s' is a %s with no fields." % (name, type_desc)) 492*ef5ccd6cSJohn Marino return False 493*ef5ccd6cSJohn Marino 494*ef5ccd6cSJohn Marino if is_child: 495*ef5ccd6cSJohn Marino print ("%s is a %s of type '%s' " 496*ef5ccd6cSJohn Marino "with the following fields:\n" % 497*ef5ccd6cSJohn Marino (name, type_desc, str(datatype))) 498*ef5ccd6cSJohn Marino else: 499*ef5ccd6cSJohn Marino print ("'%s' is a %s with the following " 500*ef5ccd6cSJohn Marino "fields:\n" % 501*ef5ccd6cSJohn Marino (name, type_desc)) 502*ef5ccd6cSJohn Marino 503*ef5ccd6cSJohn Marino has_explorable_fields = False 504*ef5ccd6cSJohn Marino current_choice = 0 505*ef5ccd6cSJohn Marino choice_to_compound_field_map = { } 506*ef5ccd6cSJohn Marino print_list = [ ] 507*ef5ccd6cSJohn Marino for field in fields: 508*ef5ccd6cSJohn Marino if field.artificial: 509*ef5ccd6cSJohn Marino continue 510*ef5ccd6cSJohn Marino if field.is_base_class: 511*ef5ccd6cSJohn Marino field_desc = "base class" 512*ef5ccd6cSJohn Marino else: 513*ef5ccd6cSJohn Marino field_desc = "field" 514*ef5ccd6cSJohn Marino rhs = ("<Enter %d to explore this %s of type '%s'>" % 515*ef5ccd6cSJohn Marino (current_choice, field_desc, str(field.type))) 516*ef5ccd6cSJohn Marino print_list.append((field.name, rhs)) 517*ef5ccd6cSJohn Marino choice_to_compound_field_map[str(current_choice)] = ( 518*ef5ccd6cSJohn Marino field.name, field.type, field_desc) 519*ef5ccd6cSJohn Marino current_choice = current_choice + 1 520*ef5ccd6cSJohn Marino 521*ef5ccd6cSJohn Marino CompoundExplorer._print_fields(print_list) 522*ef5ccd6cSJohn Marino print ("") 523*ef5ccd6cSJohn Marino 524*ef5ccd6cSJohn Marino if len(choice_to_compound_field_map) > 0: 525*ef5ccd6cSJohn Marino choice = raw_input("Enter the field number of choice: ") 526*ef5ccd6cSJohn Marino if choice in choice_to_compound_field_map: 527*ef5ccd6cSJohn Marino if is_child: 528*ef5ccd6cSJohn Marino new_name = ("%s '%s' of %s" % 529*ef5ccd6cSJohn Marino (choice_to_compound_field_map[choice][2], 530*ef5ccd6cSJohn Marino choice_to_compound_field_map[choice][0], 531*ef5ccd6cSJohn Marino name)) 532*ef5ccd6cSJohn Marino else: 533*ef5ccd6cSJohn Marino new_name = ("%s '%s' of '%s'" % 534*ef5ccd6cSJohn Marino (choice_to_compound_field_map[choice][2], 535*ef5ccd6cSJohn Marino choice_to_compound_field_map[choice][0], 536*ef5ccd6cSJohn Marino name)) 537*ef5ccd6cSJohn Marino Explorer.explore_type(new_name, 538*ef5ccd6cSJohn Marino choice_to_compound_field_map[choice][1], True) 539*ef5ccd6cSJohn Marino return True 540*ef5ccd6cSJohn Marino else: 541*ef5ccd6cSJohn Marino if is_child: 542*ef5ccd6cSJohn Marino Explorer.return_to_enclosing_type() 543*ef5ccd6cSJohn Marino else: 544*ef5ccd6cSJohn Marino if is_child: 545*ef5ccd6cSJohn Marino Explorer.return_to_enclosing_type_prompt() 546*ef5ccd6cSJohn Marino 547*ef5ccd6cSJohn Marino return False 548*ef5ccd6cSJohn Marino 549*ef5ccd6cSJohn Marino 550*ef5ccd6cSJohn Marinoclass TypedefExplorer(object): 551*ef5ccd6cSJohn Marino """Internal class used to explore values whose type is a typedef.""" 552*ef5ccd6cSJohn Marino 553*ef5ccd6cSJohn Marino @staticmethod 554*ef5ccd6cSJohn Marino def explore_expr(expr, value, is_child): 555*ef5ccd6cSJohn Marino """Function to explore typedef values. 556*ef5ccd6cSJohn Marino See Explorer.explore_expr for more information. 557*ef5ccd6cSJohn Marino """ 558*ef5ccd6cSJohn Marino actual_type = value.type.strip_typedefs() 559*ef5ccd6cSJohn Marino print ("The value of '%s' is of type '%s' " 560*ef5ccd6cSJohn Marino "which is a typedef of type '%s'" % 561*ef5ccd6cSJohn Marino (expr, str(value.type), str(actual_type))) 562*ef5ccd6cSJohn Marino 563*ef5ccd6cSJohn Marino Explorer.explore_expr(expr, value.cast(actual_type), is_child) 564*ef5ccd6cSJohn Marino return False 565*ef5ccd6cSJohn Marino 566*ef5ccd6cSJohn Marino @staticmethod 567*ef5ccd6cSJohn Marino def explore_type(name, datatype, is_child): 568*ef5ccd6cSJohn Marino """Function to explore typedef types. 569*ef5ccd6cSJohn Marino See Explorer.explore_type for more information. 570*ef5ccd6cSJohn Marino """ 571*ef5ccd6cSJohn Marino actual_type = datatype.strip_typedefs() 572*ef5ccd6cSJohn Marino if is_child: 573*ef5ccd6cSJohn Marino print ("The type of %s is a typedef of type '%s'." % 574*ef5ccd6cSJohn Marino (name, str(actual_type))) 575*ef5ccd6cSJohn Marino else: 576*ef5ccd6cSJohn Marino print ("The type '%s' is a typedef of type '%s'." % 577*ef5ccd6cSJohn Marino (name, str(actual_type))) 578*ef5ccd6cSJohn Marino 579*ef5ccd6cSJohn Marino Explorer.explore_type(name, actual_type, is_child) 580*ef5ccd6cSJohn Marino return False 581*ef5ccd6cSJohn Marino 582*ef5ccd6cSJohn Marino 583*ef5ccd6cSJohn Marinoclass ExploreUtils(object): 584*ef5ccd6cSJohn Marino """Internal class which provides utilities for the main command classes.""" 585*ef5ccd6cSJohn Marino 586*ef5ccd6cSJohn Marino @staticmethod 587*ef5ccd6cSJohn Marino def check_args(name, arg_str): 588*ef5ccd6cSJohn Marino """Utility to check if adequate number of arguments are passed to an 589*ef5ccd6cSJohn Marino explore command. 590*ef5ccd6cSJohn Marino 591*ef5ccd6cSJohn Marino Arguments: 592*ef5ccd6cSJohn Marino name: The name of the explore command. 593*ef5ccd6cSJohn Marino arg_str: The argument string passed to the explore command. 594*ef5ccd6cSJohn Marino 595*ef5ccd6cSJohn Marino Returns: 596*ef5ccd6cSJohn Marino True if adequate arguments are passed, false otherwise. 597*ef5ccd6cSJohn Marino 598*ef5ccd6cSJohn Marino Raises: 599*ef5ccd6cSJohn Marino gdb.GdbError if adequate arguments are not passed. 600*ef5ccd6cSJohn Marino """ 601*ef5ccd6cSJohn Marino if len(arg_str) < 1: 602*ef5ccd6cSJohn Marino raise gdb.GdbError("ERROR: '%s' requires an argument." 603*ef5ccd6cSJohn Marino % name) 604*ef5ccd6cSJohn Marino return False 605*ef5ccd6cSJohn Marino else: 606*ef5ccd6cSJohn Marino return True 607*ef5ccd6cSJohn Marino 608*ef5ccd6cSJohn Marino @staticmethod 609*ef5ccd6cSJohn Marino def get_type_from_str(type_str): 610*ef5ccd6cSJohn Marino """A utility function to deduce the gdb.Type value from a string 611*ef5ccd6cSJohn Marino representing the type. 612*ef5ccd6cSJohn Marino 613*ef5ccd6cSJohn Marino Arguments: 614*ef5ccd6cSJohn Marino type_str: The type string from which the gdb.Type value should be 615*ef5ccd6cSJohn Marino deduced. 616*ef5ccd6cSJohn Marino 617*ef5ccd6cSJohn Marino Returns: 618*ef5ccd6cSJohn Marino The deduced gdb.Type value if possible, None otherwise. 619*ef5ccd6cSJohn Marino """ 620*ef5ccd6cSJohn Marino try: 621*ef5ccd6cSJohn Marino # Assume the current language to be C/C++ and make a try. 622*ef5ccd6cSJohn Marino return gdb.parse_and_eval("(%s *)0" % type_str).type.target() 623*ef5ccd6cSJohn Marino except RuntimeError: 624*ef5ccd6cSJohn Marino # If assumption of current language to be C/C++ was wrong, then 625*ef5ccd6cSJohn Marino # lookup the type using the API. 626*ef5ccd6cSJohn Marino try: 627*ef5ccd6cSJohn Marino return gdb.lookup_type(type_str) 628*ef5ccd6cSJohn Marino except RuntimeError: 629*ef5ccd6cSJohn Marino return None 630*ef5ccd6cSJohn Marino 631*ef5ccd6cSJohn Marino @staticmethod 632*ef5ccd6cSJohn Marino def get_value_from_str(value_str): 633*ef5ccd6cSJohn Marino """A utility function to deduce the gdb.Value value from a string 634*ef5ccd6cSJohn Marino representing the value. 635*ef5ccd6cSJohn Marino 636*ef5ccd6cSJohn Marino Arguments: 637*ef5ccd6cSJohn Marino value_str: The value string from which the gdb.Value value should 638*ef5ccd6cSJohn Marino be deduced. 639*ef5ccd6cSJohn Marino 640*ef5ccd6cSJohn Marino Returns: 641*ef5ccd6cSJohn Marino The deduced gdb.Value value if possible, None otherwise. 642*ef5ccd6cSJohn Marino """ 643*ef5ccd6cSJohn Marino try: 644*ef5ccd6cSJohn Marino return gdb.parse_and_eval(value_str) 645*ef5ccd6cSJohn Marino except RuntimeError: 646*ef5ccd6cSJohn Marino return None 647*ef5ccd6cSJohn Marino 648*ef5ccd6cSJohn Marino 649*ef5ccd6cSJohn Marinoclass ExploreCommand(gdb.Command): 650*ef5ccd6cSJohn Marino """Explore a value or a type valid in the current context. 651*ef5ccd6cSJohn Marino 652*ef5ccd6cSJohn Marino Usage: 653*ef5ccd6cSJohn Marino 654*ef5ccd6cSJohn Marino explore ARG 655*ef5ccd6cSJohn Marino 656*ef5ccd6cSJohn Marino - ARG is either a valid expression or a type name. 657*ef5ccd6cSJohn Marino - At any stage of exploration, hit the return key (instead of a 658*ef5ccd6cSJohn Marino choice, if any) to return to the enclosing type or value. 659*ef5ccd6cSJohn Marino """ 660*ef5ccd6cSJohn Marino 661*ef5ccd6cSJohn Marino def __init__(self): 662*ef5ccd6cSJohn Marino super(ExploreCommand, self).__init__(name = "explore", 663*ef5ccd6cSJohn Marino command_class = gdb.COMMAND_DATA, 664*ef5ccd6cSJohn Marino prefix = True) 665*ef5ccd6cSJohn Marino 666*ef5ccd6cSJohn Marino def invoke(self, arg_str, from_tty): 667*ef5ccd6cSJohn Marino if ExploreUtils.check_args("explore", arg_str) == False: 668*ef5ccd6cSJohn Marino return 669*ef5ccd6cSJohn Marino 670*ef5ccd6cSJohn Marino # Check if it is a value 671*ef5ccd6cSJohn Marino value = ExploreUtils.get_value_from_str(arg_str) 672*ef5ccd6cSJohn Marino if value is not None: 673*ef5ccd6cSJohn Marino Explorer.explore_expr(arg_str, value, False) 674*ef5ccd6cSJohn Marino return 675*ef5ccd6cSJohn Marino 676*ef5ccd6cSJohn Marino # If it is not a value, check if it is a type 677*ef5ccd6cSJohn Marino datatype = ExploreUtils.get_type_from_str(arg_str) 678*ef5ccd6cSJohn Marino if datatype is not None: 679*ef5ccd6cSJohn Marino Explorer.explore_type(arg_str, datatype, False) 680*ef5ccd6cSJohn Marino return 681*ef5ccd6cSJohn Marino 682*ef5ccd6cSJohn Marino # If it is neither a value nor a type, raise an error. 683*ef5ccd6cSJohn Marino raise gdb.GdbError( 684*ef5ccd6cSJohn Marino ("'%s' neither evaluates to a value nor is a type " 685*ef5ccd6cSJohn Marino "in the current context." % 686*ef5ccd6cSJohn Marino arg_str)) 687*ef5ccd6cSJohn Marino 688*ef5ccd6cSJohn Marino 689*ef5ccd6cSJohn Marinoclass ExploreValueCommand(gdb.Command): 690*ef5ccd6cSJohn Marino """Explore value of an expression valid in the current context. 691*ef5ccd6cSJohn Marino 692*ef5ccd6cSJohn Marino Usage: 693*ef5ccd6cSJohn Marino 694*ef5ccd6cSJohn Marino explore value ARG 695*ef5ccd6cSJohn Marino 696*ef5ccd6cSJohn Marino - ARG is a valid expression. 697*ef5ccd6cSJohn Marino - At any stage of exploration, hit the return key (instead of a 698*ef5ccd6cSJohn Marino choice, if any) to return to the enclosing value. 699*ef5ccd6cSJohn Marino """ 700*ef5ccd6cSJohn Marino 701*ef5ccd6cSJohn Marino def __init__(self): 702*ef5ccd6cSJohn Marino super(ExploreValueCommand, self).__init__( 703*ef5ccd6cSJohn Marino name = "explore value", command_class = gdb.COMMAND_DATA) 704*ef5ccd6cSJohn Marino 705*ef5ccd6cSJohn Marino def invoke(self, arg_str, from_tty): 706*ef5ccd6cSJohn Marino if ExploreUtils.check_args("explore value", arg_str) == False: 707*ef5ccd6cSJohn Marino return 708*ef5ccd6cSJohn Marino 709*ef5ccd6cSJohn Marino value = ExploreUtils.get_value_from_str(arg_str) 710*ef5ccd6cSJohn Marino if value is None: 711*ef5ccd6cSJohn Marino raise gdb.GdbError( 712*ef5ccd6cSJohn Marino (" '%s' does not evaluate to a value in the current " 713*ef5ccd6cSJohn Marino "context." % 714*ef5ccd6cSJohn Marino arg_str)) 715*ef5ccd6cSJohn Marino return 716*ef5ccd6cSJohn Marino 717*ef5ccd6cSJohn Marino Explorer.explore_expr(arg_str, value, False) 718*ef5ccd6cSJohn Marino 719*ef5ccd6cSJohn Marino 720*ef5ccd6cSJohn Marinoclass ExploreTypeCommand(gdb.Command): 721*ef5ccd6cSJohn Marino """Explore a type or the type of an expression valid in the current 722*ef5ccd6cSJohn Marino context. 723*ef5ccd6cSJohn Marino 724*ef5ccd6cSJohn Marino Usage: 725*ef5ccd6cSJohn Marino 726*ef5ccd6cSJohn Marino explore type ARG 727*ef5ccd6cSJohn Marino 728*ef5ccd6cSJohn Marino - ARG is a valid expression or a type name. 729*ef5ccd6cSJohn Marino - At any stage of exploration, hit the return key (instead of a 730*ef5ccd6cSJohn Marino choice, if any) to return to the enclosing type. 731*ef5ccd6cSJohn Marino """ 732*ef5ccd6cSJohn Marino 733*ef5ccd6cSJohn Marino def __init__(self): 734*ef5ccd6cSJohn Marino super(ExploreTypeCommand, self).__init__( 735*ef5ccd6cSJohn Marino name = "explore type", command_class = gdb.COMMAND_DATA) 736*ef5ccd6cSJohn Marino 737*ef5ccd6cSJohn Marino def invoke(self, arg_str, from_tty): 738*ef5ccd6cSJohn Marino if ExploreUtils.check_args("explore type", arg_str) == False: 739*ef5ccd6cSJohn Marino return 740*ef5ccd6cSJohn Marino 741*ef5ccd6cSJohn Marino datatype = ExploreUtils.get_type_from_str(arg_str) 742*ef5ccd6cSJohn Marino if datatype is not None: 743*ef5ccd6cSJohn Marino Explorer.explore_type(arg_str, datatype, False) 744*ef5ccd6cSJohn Marino return 745*ef5ccd6cSJohn Marino 746*ef5ccd6cSJohn Marino value = ExploreUtils.get_value_from_str(arg_str) 747*ef5ccd6cSJohn Marino if value is not None: 748*ef5ccd6cSJohn Marino print ("'%s' is of type '%s'." % (arg_str, str(value.type))) 749*ef5ccd6cSJohn Marino Explorer.explore_type(str(value.type), value.type, False) 750*ef5ccd6cSJohn Marino return 751*ef5ccd6cSJohn Marino 752*ef5ccd6cSJohn Marino raise gdb.GdbError(("'%s' is not a type or value in the current " 753*ef5ccd6cSJohn Marino "context." % arg_str)) 754*ef5ccd6cSJohn Marino 755*ef5ccd6cSJohn Marino 756*ef5ccd6cSJohn MarinoExplorer.init_env() 757*ef5ccd6cSJohn Marino 758*ef5ccd6cSJohn MarinoExploreCommand() 759*ef5ccd6cSJohn MarinoExploreValueCommand() 760*ef5ccd6cSJohn MarinoExploreTypeCommand() 761