GDB (API)
|
00001 # GDB 'explore' command. 00002 # Copyright (C) 2012-2013 Free Software Foundation, Inc. 00003 00004 # This program is free software; you can redistribute it and/or modify 00005 # it under the terms of the GNU General Public License as published by 00006 # the Free Software Foundation; either version 3 of the License, or 00007 # (at your option) any later version. 00008 # 00009 # This program is distributed in the hope that it will be useful, 00010 # but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 # GNU General Public License for more details. 00013 # 00014 # You should have received a copy of the GNU General Public License 00015 # along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 00017 """Implementation of the GDB 'explore' command using the GDB Python API.""" 00018 00019 import gdb 00020 import sys 00021 00022 if sys.version_info[0] > 2: 00023 # Python 3 renamed raw_input to input 00024 raw_input = input 00025 00026 class Explorer(object): 00027 """Internal class which invokes other explorers.""" 00028 00029 # This map is filled by the Explorer.init_env() function 00030 type_code_to_explorer_map = { } 00031 00032 _SCALAR_TYPE_LIST = ( 00033 gdb.TYPE_CODE_CHAR, 00034 gdb.TYPE_CODE_INT, 00035 gdb.TYPE_CODE_BOOL, 00036 gdb.TYPE_CODE_FLT, 00037 gdb.TYPE_CODE_VOID, 00038 gdb.TYPE_CODE_ENUM, 00039 ) 00040 00041 @staticmethod 00042 def guard_expr(expr): 00043 length = len(expr) 00044 guard = False 00045 00046 if expr[0] == '(' and expr[length-1] == ')': 00047 pass 00048 else: 00049 i = 0 00050 while i < length: 00051 c = expr[i] 00052 if (c == '_' or ('a' <= c and c <= 'z') or 00053 ('A' <= c and c <= 'Z') or ('0' <= c and c <= '9')): 00054 pass 00055 else: 00056 guard = True 00057 break 00058 i += 1 00059 00060 if guard: 00061 return "(" + expr + ")" 00062 else: 00063 return expr 00064 00065 @staticmethod 00066 def explore_expr(expr, value, is_child): 00067 """Main function to explore an expression value. 00068 00069 Arguments: 00070 expr: The expression string that is being explored. 00071 value: The gdb.Value value of the expression. 00072 is_child: Boolean value to indicate if the expression is a child. 00073 An expression is a child if it is derived from the main 00074 expression entered by the user. For example, if the user 00075 entered an expression which evaluates to a struct, then 00076 when exploring the fields of the struct, is_child is set 00077 to True internally. 00078 00079 Returns: 00080 No return value. 00081 """ 00082 type_code = value.type.code 00083 if type_code in Explorer.type_code_to_explorer_map: 00084 explorer_class = Explorer.type_code_to_explorer_map[type_code] 00085 while explorer_class.explore_expr(expr, value, is_child): 00086 pass 00087 else: 00088 print ("Explorer for type '%s' not yet available.\n" % 00089 str(value.type)) 00090 00091 @staticmethod 00092 def explore_type(name, datatype, is_child): 00093 """Main function to explore a data type. 00094 00095 Arguments: 00096 name: The string representing the path to the data type being 00097 explored. 00098 datatype: The gdb.Type value of the data type being explored. 00099 is_child: Boolean value to indicate if the name is a child. 00100 A name is a child if it is derived from the main name 00101 entered by the user. For example, if the user entered 00102 the name of struct type, then when exploring the fields 00103 of the struct, is_child is set to True internally. 00104 00105 Returns: 00106 No return value. 00107 """ 00108 type_code = datatype.code 00109 if type_code in Explorer.type_code_to_explorer_map: 00110 explorer_class = Explorer.type_code_to_explorer_map[type_code] 00111 while explorer_class.explore_type(name, datatype, is_child): 00112 pass 00113 else: 00114 print ("Explorer for type '%s' not yet available.\n" % 00115 str(datatype)) 00116 00117 @staticmethod 00118 def init_env(): 00119 """Initializes the Explorer environment. 00120 This function should be invoked before starting any exploration. If 00121 invoked before an exploration, it need not be invoked for subsequent 00122 explorations. 00123 """ 00124 Explorer.type_code_to_explorer_map = { 00125 gdb.TYPE_CODE_CHAR : ScalarExplorer, 00126 gdb.TYPE_CODE_INT : ScalarExplorer, 00127 gdb.TYPE_CODE_BOOL : ScalarExplorer, 00128 gdb.TYPE_CODE_FLT : ScalarExplorer, 00129 gdb.TYPE_CODE_VOID : ScalarExplorer, 00130 gdb.TYPE_CODE_ENUM : ScalarExplorer, 00131 gdb.TYPE_CODE_STRUCT : CompoundExplorer, 00132 gdb.TYPE_CODE_UNION : CompoundExplorer, 00133 gdb.TYPE_CODE_PTR : PointerExplorer, 00134 gdb.TYPE_CODE_REF : ReferenceExplorer, 00135 gdb.TYPE_CODE_TYPEDEF : TypedefExplorer, 00136 gdb.TYPE_CODE_ARRAY : ArrayExplorer 00137 } 00138 00139 @staticmethod 00140 def is_scalar_type(type): 00141 """Checks whether a type is a scalar type. 00142 A type is a scalar type of its type is 00143 gdb.TYPE_CODE_CHAR or 00144 gdb.TYPE_CODE_INT or 00145 gdb.TYPE_CODE_BOOL or 00146 gdb.TYPE_CODE_FLT or 00147 gdb.TYPE_CODE_VOID or 00148 gdb.TYPE_CODE_ENUM. 00149 00150 Arguments: 00151 type: The type to be checked. 00152 00153 Returns: 00154 'True' if 'type' is a scalar type. 'False' otherwise. 00155 """ 00156 return type.code in Explorer._SCALAR_TYPE_LIST 00157 00158 @staticmethod 00159 def return_to_parent_value(): 00160 """A utility function which prints that the current exploration session 00161 is returning to the parent value. Useful when exploring values. 00162 """ 00163 print ("\nReturning to parent value...\n") 00164 00165 @staticmethod 00166 def return_to_parent_value_prompt(): 00167 """A utility function which prompts the user to press the 'enter' key 00168 so that the exploration session can shift back to the parent value. 00169 Useful when exploring values. 00170 """ 00171 raw_input("\nPress enter to return to parent value: ") 00172 00173 @staticmethod 00174 def return_to_enclosing_type(): 00175 """A utility function which prints that the current exploration session 00176 is returning to the enclosing type. Useful when exploring types. 00177 """ 00178 print ("\nReturning to enclosing type...\n") 00179 00180 @staticmethod 00181 def return_to_enclosing_type_prompt(): 00182 """A utility function which prompts the user to press the 'enter' key 00183 so that the exploration session can shift back to the enclosing type. 00184 Useful when exploring types. 00185 """ 00186 raw_input("\nPress enter to return to enclosing type: ") 00187 00188 00189 class ScalarExplorer(object): 00190 """Internal class used to explore scalar values.""" 00191 00192 @staticmethod 00193 def explore_expr(expr, value, is_child): 00194 """Function to explore scalar values. 00195 See Explorer.explore_expr and Explorer.is_scalar_type for more 00196 information. 00197 """ 00198 print ("'%s' is a scalar value of type '%s'." % 00199 (expr, value.type)) 00200 print ("%s = %s" % (expr, str(value))) 00201 00202 if is_child: 00203 Explorer.return_to_parent_value_prompt() 00204 Explorer.return_to_parent_value() 00205 00206 return False 00207 00208 @staticmethod 00209 def explore_type(name, datatype, is_child): 00210 """Function to explore scalar types. 00211 See Explorer.explore_type and Explorer.is_scalar_type for more 00212 information. 00213 """ 00214 if datatype.code == gdb.TYPE_CODE_ENUM: 00215 if is_child: 00216 print ("%s is of an enumerated type '%s'." % 00217 (name, str(datatype))) 00218 else: 00219 print ("'%s' is an enumerated type." % name) 00220 else: 00221 if is_child: 00222 print ("%s is of a scalar type '%s'." % 00223 (name, str(datatype))) 00224 else: 00225 print ("'%s' is a scalar type." % name) 00226 00227 if is_child: 00228 Explorer.return_to_enclosing_type_prompt() 00229 Explorer.return_to_enclosing_type() 00230 00231 return False 00232 00233 00234 class PointerExplorer(object): 00235 """Internal class used to explore pointer values.""" 00236 00237 @staticmethod 00238 def explore_expr(expr, value, is_child): 00239 """Function to explore pointer values. 00240 See Explorer.explore_expr for more information. 00241 """ 00242 print ("'%s' is a pointer to a value of type '%s'" % 00243 (expr, str(value.type.target()))) 00244 option = raw_input("Continue exploring it as a pointer to a single " 00245 "value [y/n]: ") 00246 if option == "y": 00247 deref_value = None 00248 try: 00249 deref_value = value.dereference() 00250 str(deref_value) 00251 except gdb.MemoryError: 00252 print ("'%s' a pointer pointing to an invalid memory " 00253 "location." % expr) 00254 if is_child: 00255 Explorer.return_to_parent_value_prompt() 00256 return False 00257 Explorer.explore_expr("*%s" % Explorer.guard_expr(expr), 00258 deref_value, is_child) 00259 return False 00260 00261 option = raw_input("Continue exploring it as a pointer to an " 00262 "array [y/n]: ") 00263 if option == "y": 00264 while True: 00265 index = 0 00266 try: 00267 index = int(raw_input("Enter the index of the element you " 00268 "want to explore in '%s': " % expr)) 00269 except ValueError: 00270 break 00271 element_expr = "%s[%d]" % (Explorer.guard_expr(expr), index) 00272 element = value[index] 00273 try: 00274 str(element) 00275 except gdb.MemoryError: 00276 print ("Cannot read value at index %d." % index) 00277 continue 00278 Explorer.explore_expr(element_expr, element, True) 00279 return False 00280 00281 if is_child: 00282 Explorer.return_to_parent_value() 00283 return False 00284 00285 @staticmethod 00286 def explore_type(name, datatype, is_child): 00287 """Function to explore pointer types. 00288 See Explorer.explore_type for more information. 00289 """ 00290 target_type = datatype.target() 00291 print ("\n%s is a pointer to a value of type '%s'." % 00292 (name, str(target_type))) 00293 00294 Explorer.explore_type("the pointee type of %s" % name, 00295 target_type, 00296 is_child) 00297 return False 00298 00299 00300 class ReferenceExplorer(object): 00301 """Internal class used to explore reference (TYPE_CODE_REF) values.""" 00302 00303 @staticmethod 00304 def explore_expr(expr, value, is_child): 00305 """Function to explore array values. 00306 See Explorer.explore_expr for more information. 00307 """ 00308 referenced_value = value.referenced_value() 00309 Explorer.explore_expr(expr, referenced_value, is_child) 00310 return False 00311 00312 @staticmethod 00313 def explore_type(name, datatype, is_child): 00314 """Function to explore pointer types. 00315 See Explorer.explore_type for more information. 00316 """ 00317 target_type = datatype.target() 00318 Explorer.explore_type(name, target_type, is_child) 00319 return False 00320 00321 00322 class ArrayExplorer(object): 00323 """Internal class used to explore arrays.""" 00324 00325 @staticmethod 00326 def explore_expr(expr, value, is_child): 00327 """Function to explore array values. 00328 See Explorer.explore_expr for more information. 00329 """ 00330 target_type = value.type.target() 00331 print ("'%s' is an array of '%s'." % (expr, str(target_type))) 00332 index = 0 00333 try: 00334 index = int(raw_input("Enter the index of the element you want to " 00335 "explore in '%s': " % expr)) 00336 except ValueError: 00337 if is_child: 00338 Explorer.return_to_parent_value() 00339 return False 00340 00341 element = None 00342 try: 00343 element = value[index] 00344 str(element) 00345 except gdb.MemoryError: 00346 print ("Cannot read value at index %d." % index) 00347 raw_input("Press enter to continue... ") 00348 return True 00349 00350 Explorer.explore_expr("%s[%d]" % (Explorer.guard_expr(expr), index), 00351 element, True) 00352 return True 00353 00354 @staticmethod 00355 def explore_type(name, datatype, is_child): 00356 """Function to explore array types. 00357 See Explorer.explore_type for more information. 00358 """ 00359 target_type = datatype.target() 00360 print ("%s is an array of '%s'." % (name, str(target_type))) 00361 00362 Explorer.explore_type("the array element of %s" % name, target_type, 00363 is_child) 00364 return False 00365 00366 00367 class CompoundExplorer(object): 00368 """Internal class used to explore struct, classes and unions.""" 00369 00370 @staticmethod 00371 def _print_fields(print_list): 00372 """Internal function which prints the fields of a struct/class/union. 00373 """ 00374 max_field_name_length = 0 00375 for pair in print_list: 00376 if max_field_name_length < len(pair[0]): 00377 max_field_name_length = len(pair[0]) 00378 00379 for pair in print_list: 00380 print (" %*s = %s" % (max_field_name_length, pair[0], pair[1])) 00381 00382 @staticmethod 00383 def _get_real_field_count(fields): 00384 real_field_count = 0; 00385 for field in fields: 00386 if not field.artificial: 00387 real_field_count = real_field_count + 1 00388 00389 return real_field_count 00390 00391 @staticmethod 00392 def explore_expr(expr, value, is_child): 00393 """Function to explore structs/classes and union values. 00394 See Explorer.explore_expr for more information. 00395 """ 00396 datatype = value.type 00397 type_code = datatype.code 00398 fields = datatype.fields() 00399 00400 if type_code == gdb.TYPE_CODE_STRUCT: 00401 type_desc = "struct/class" 00402 else: 00403 type_desc = "union" 00404 00405 if CompoundExplorer._get_real_field_count(fields) == 0: 00406 print ("The value of '%s' is a %s of type '%s' with no fields." % 00407 (expr, type_desc, str(value.type))) 00408 if is_child: 00409 Explorer.return_to_parent_value_prompt() 00410 return False 00411 00412 print ("The value of '%s' is a %s of type '%s' with the following " 00413 "fields:\n" % (expr, type_desc, str(value.type))) 00414 00415 has_explorable_fields = False 00416 choice_to_compound_field_map = { } 00417 current_choice = 0 00418 print_list = [ ] 00419 for field in fields: 00420 if field.artificial: 00421 continue 00422 field_full_name = Explorer.guard_expr(expr) + "." + field.name 00423 if field.is_base_class: 00424 field_value = value.cast(field.type) 00425 else: 00426 field_value = value[field.name] 00427 literal_value = "" 00428 if type_code == gdb.TYPE_CODE_UNION: 00429 literal_value = ("<Enter %d to explore this field of type " 00430 "'%s'>" % (current_choice, str(field.type))) 00431 has_explorable_fields = True 00432 else: 00433 if Explorer.is_scalar_type(field.type): 00434 literal_value = ("%s .. (Value of type '%s')" % 00435 (str(field_value), str(field.type))) 00436 else: 00437 if field.is_base_class: 00438 field_desc = "base class" 00439 else: 00440 field_desc = "field" 00441 literal_value = ("<Enter %d to explore this %s of type " 00442 "'%s'>" % 00443 (current_choice, field_desc, 00444 str(field.type))) 00445 has_explorable_fields = True 00446 00447 choice_to_compound_field_map[str(current_choice)] = ( 00448 field_full_name, field_value) 00449 current_choice = current_choice + 1 00450 00451 print_list.append((field.name, literal_value)) 00452 00453 CompoundExplorer._print_fields(print_list) 00454 print ("") 00455 00456 if has_explorable_fields: 00457 choice = raw_input("Enter the field number of choice: ") 00458 if choice in choice_to_compound_field_map: 00459 Explorer.explore_expr(choice_to_compound_field_map[choice][0], 00460 choice_to_compound_field_map[choice][1], 00461 True) 00462 return True 00463 else: 00464 if is_child: 00465 Explorer.return_to_parent_value() 00466 else: 00467 if is_child: 00468 Explorer.return_to_parent_value_prompt() 00469 00470 return False 00471 00472 @staticmethod 00473 def explore_type(name, datatype, is_child): 00474 """Function to explore struct/class and union types. 00475 See Explorer.explore_type for more information. 00476 """ 00477 type_code = datatype.code 00478 type_desc = "" 00479 if type_code == gdb.TYPE_CODE_STRUCT: 00480 type_desc = "struct/class" 00481 else: 00482 type_desc = "union" 00483 00484 fields = datatype.fields() 00485 if CompoundExplorer._get_real_field_count(fields) == 0: 00486 if is_child: 00487 print ("%s is a %s of type '%s' with no fields." % 00488 (name, type_desc, str(datatype))) 00489 Explorer.return_to_enclosing_type_prompt() 00490 else: 00491 print ("'%s' is a %s with no fields." % (name, type_desc)) 00492 return False 00493 00494 if is_child: 00495 print ("%s is a %s of type '%s' " 00496 "with the following fields:\n" % 00497 (name, type_desc, str(datatype))) 00498 else: 00499 print ("'%s' is a %s with the following " 00500 "fields:\n" % 00501 (name, type_desc)) 00502 00503 has_explorable_fields = False 00504 current_choice = 0 00505 choice_to_compound_field_map = { } 00506 print_list = [ ] 00507 for field in fields: 00508 if field.artificial: 00509 continue 00510 if field.is_base_class: 00511 field_desc = "base class" 00512 else: 00513 field_desc = "field" 00514 rhs = ("<Enter %d to explore this %s of type '%s'>" % 00515 (current_choice, field_desc, str(field.type))) 00516 print_list.append((field.name, rhs)) 00517 choice_to_compound_field_map[str(current_choice)] = ( 00518 field.name, field.type, field_desc) 00519 current_choice = current_choice + 1 00520 00521 CompoundExplorer._print_fields(print_list) 00522 print ("") 00523 00524 if len(choice_to_compound_field_map) > 0: 00525 choice = raw_input("Enter the field number of choice: ") 00526 if choice in choice_to_compound_field_map: 00527 if is_child: 00528 new_name = ("%s '%s' of %s" % 00529 (choice_to_compound_field_map[choice][2], 00530 choice_to_compound_field_map[choice][0], 00531 name)) 00532 else: 00533 new_name = ("%s '%s' of '%s'" % 00534 (choice_to_compound_field_map[choice][2], 00535 choice_to_compound_field_map[choice][0], 00536 name)) 00537 Explorer.explore_type(new_name, 00538 choice_to_compound_field_map[choice][1], True) 00539 return True 00540 else: 00541 if is_child: 00542 Explorer.return_to_enclosing_type() 00543 else: 00544 if is_child: 00545 Explorer.return_to_enclosing_type_prompt() 00546 00547 return False 00548 00549 00550 class TypedefExplorer(object): 00551 """Internal class used to explore values whose type is a typedef.""" 00552 00553 @staticmethod 00554 def explore_expr(expr, value, is_child): 00555 """Function to explore typedef values. 00556 See Explorer.explore_expr for more information. 00557 """ 00558 actual_type = value.type.strip_typedefs() 00559 print ("The value of '%s' is of type '%s' " 00560 "which is a typedef of type '%s'" % 00561 (expr, str(value.type), str(actual_type))) 00562 00563 Explorer.explore_expr(expr, value.cast(actual_type), is_child) 00564 return False 00565 00566 @staticmethod 00567 def explore_type(name, datatype, is_child): 00568 """Function to explore typedef types. 00569 See Explorer.explore_type for more information. 00570 """ 00571 actual_type = datatype.strip_typedefs() 00572 if is_child: 00573 print ("The type of %s is a typedef of type '%s'." % 00574 (name, str(actual_type))) 00575 else: 00576 print ("The type '%s' is a typedef of type '%s'." % 00577 (name, str(actual_type))) 00578 00579 Explorer.explore_type(name, actual_type, is_child) 00580 return False 00581 00582 00583 class ExploreUtils(object): 00584 """Internal class which provides utilities for the main command classes.""" 00585 00586 @staticmethod 00587 def check_args(name, arg_str): 00588 """Utility to check if adequate number of arguments are passed to an 00589 explore command. 00590 00591 Arguments: 00592 name: The name of the explore command. 00593 arg_str: The argument string passed to the explore command. 00594 00595 Returns: 00596 True if adequate arguments are passed, false otherwise. 00597 00598 Raises: 00599 gdb.GdbError if adequate arguments are not passed. 00600 """ 00601 if len(arg_str) < 1: 00602 raise gdb.GdbError("ERROR: '%s' requires an argument." 00603 % name) 00604 return False 00605 else: 00606 return True 00607 00608 @staticmethod 00609 def get_type_from_str(type_str): 00610 """A utility function to deduce the gdb.Type value from a string 00611 representing the type. 00612 00613 Arguments: 00614 type_str: The type string from which the gdb.Type value should be 00615 deduced. 00616 00617 Returns: 00618 The deduced gdb.Type value if possible, None otherwise. 00619 """ 00620 try: 00621 # Assume the current language to be C/C++ and make a try. 00622 return gdb.parse_and_eval("(%s *)0" % type_str).type.target() 00623 except RuntimeError: 00624 # If assumption of current language to be C/C++ was wrong, then 00625 # lookup the type using the API. 00626 try: 00627 return gdb.lookup_type(type_str) 00628 except RuntimeError: 00629 return None 00630 00631 @staticmethod 00632 def get_value_from_str(value_str): 00633 """A utility function to deduce the gdb.Value value from a string 00634 representing the value. 00635 00636 Arguments: 00637 value_str: The value string from which the gdb.Value value should 00638 be deduced. 00639 00640 Returns: 00641 The deduced gdb.Value value if possible, None otherwise. 00642 """ 00643 try: 00644 return gdb.parse_and_eval(value_str) 00645 except RuntimeError: 00646 return None 00647 00648 00649 class ExploreCommand(gdb.Command): 00650 """Explore a value or a type valid in the current context. 00651 00652 Usage: 00653 00654 explore ARG 00655 00656 - ARG is either a valid expression or a type name. 00657 - At any stage of exploration, hit the return key (instead of a 00658 choice, if any) to return to the enclosing type or value. 00659 """ 00660 00661 def __init__(self): 00662 super(ExploreCommand, self).__init__(name = "explore", 00663 command_class = gdb.COMMAND_DATA, 00664 prefix = True) 00665 00666 def invoke(self, arg_str, from_tty): 00667 if ExploreUtils.check_args("explore", arg_str) == False: 00668 return 00669 00670 # Check if it is a value 00671 value = ExploreUtils.get_value_from_str(arg_str) 00672 if value is not None: 00673 Explorer.explore_expr(arg_str, value, False) 00674 return 00675 00676 # If it is not a value, check if it is a type 00677 datatype = ExploreUtils.get_type_from_str(arg_str) 00678 if datatype is not None: 00679 Explorer.explore_type(arg_str, datatype, False) 00680 return 00681 00682 # If it is neither a value nor a type, raise an error. 00683 raise gdb.GdbError( 00684 ("'%s' neither evaluates to a value nor is a type " 00685 "in the current context." % 00686 arg_str)) 00687 00688 00689 class ExploreValueCommand(gdb.Command): 00690 """Explore value of an expression valid in the current context. 00691 00692 Usage: 00693 00694 explore value ARG 00695 00696 - ARG is a valid expression. 00697 - At any stage of exploration, hit the return key (instead of a 00698 choice, if any) to return to the enclosing value. 00699 """ 00700 00701 def __init__(self): 00702 super(ExploreValueCommand, self).__init__( 00703 name = "explore value", command_class = gdb.COMMAND_DATA) 00704 00705 def invoke(self, arg_str, from_tty): 00706 if ExploreUtils.check_args("explore value", arg_str) == False: 00707 return 00708 00709 value = ExploreUtils.get_value_from_str(arg_str) 00710 if value is None: 00711 raise gdb.GdbError( 00712 (" '%s' does not evaluate to a value in the current " 00713 "context." % 00714 arg_str)) 00715 return 00716 00717 Explorer.explore_expr(arg_str, value, False) 00718 00719 00720 class ExploreTypeCommand(gdb.Command): 00721 """Explore a type or the type of an expression valid in the current 00722 context. 00723 00724 Usage: 00725 00726 explore type ARG 00727 00728 - ARG is a valid expression or a type name. 00729 - At any stage of exploration, hit the return key (instead of a 00730 choice, if any) to return to the enclosing type. 00731 """ 00732 00733 def __init__(self): 00734 super(ExploreTypeCommand, self).__init__( 00735 name = "explore type", command_class = gdb.COMMAND_DATA) 00736 00737 def invoke(self, arg_str, from_tty): 00738 if ExploreUtils.check_args("explore type", arg_str) == False: 00739 return 00740 00741 datatype = ExploreUtils.get_type_from_str(arg_str) 00742 if datatype is not None: 00743 Explorer.explore_type(arg_str, datatype, False) 00744 return 00745 00746 value = ExploreUtils.get_value_from_str(arg_str) 00747 if value is not None: 00748 print ("'%s' is of type '%s'." % (arg_str, str(value.type))) 00749 Explorer.explore_type(str(value.type), value.type, False) 00750 return 00751 00752 raise gdb.GdbError(("'%s' is not a type or value in the current " 00753 "context." % arg_str)) 00754 00755 00756 Explorer.init_env() 00757 00758 ExploreCommand() 00759 ExploreValueCommand() 00760 ExploreTypeCommand()