1 # GDB 'explore' command.
2 # Copyright (C) 2012-2022 Free Software Foundation, Inc.
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17 """Implementation of the GDB 'explore' command using the GDB Python API."""
22 if sys.version_info[0] > 2:
23 # Python 3 renamed raw_input to input
27 class Explorer(object):
28 """Internal class which invokes other explorers."""
30 # This map is filled by the Explorer.init_env() function
31 type_code_to_explorer_map = {}
47 if expr[0] == "(" and expr[length - 1] == ")":
55 or ("a" <= c and c <= "z")
56 or ("A" <= c and c <= "Z")
57 or ("0" <= c and c <= "9")
66 return "(" + expr + ")"
71 def explore_expr(expr, value, is_child):
72 """Main function to explore an expression value.
75 expr: The expression string that is being explored.
76 value: The gdb.Value value of the expression.
77 is_child: Boolean value to indicate if the expression is a child.
78 An expression is a child if it is derived from the main
79 expression entered by the user. For example, if the user
80 entered an expression which evaluates to a struct, then
81 when exploring the fields of the struct, is_child is set
87 type_code = value.type.code
88 if type_code in Explorer.type_code_to_explorer_map:
89 explorer_class = Explorer.type_code_to_explorer_map[type_code]
90 while explorer_class.explore_expr(expr, value, is_child):
93 print("Explorer for type '%s' not yet available.\n" % str(value.type))
96 def explore_type(name, datatype, is_child):
97 """Main function to explore a data type.
100 name: The string representing the path to the data type being
102 datatype: The gdb.Type value of the data type being explored.
103 is_child: Boolean value to indicate if the name is a child.
104 A name is a child if it is derived from the main name
105 entered by the user. For example, if the user entered
106 the name of struct type, then when exploring the fields
107 of the struct, is_child is set to True internally.
112 type_code = datatype.code
113 if type_code in Explorer.type_code_to_explorer_map:
114 explorer_class = Explorer.type_code_to_explorer_map[type_code]
115 while explorer_class.explore_type(name, datatype, is_child):
118 print("Explorer for type '%s' not yet available.\n" % str(datatype))
122 """Initializes the Explorer environment.
123 This function should be invoked before starting any exploration. If
124 invoked before an exploration, it need not be invoked for subsequent
127 Explorer.type_code_to_explorer_map = {
128 gdb.TYPE_CODE_CHAR: ScalarExplorer,
129 gdb.TYPE_CODE_INT: ScalarExplorer,
130 gdb.TYPE_CODE_BOOL: ScalarExplorer,
131 gdb.TYPE_CODE_FLT: ScalarExplorer,
132 gdb.TYPE_CODE_VOID: ScalarExplorer,
133 gdb.TYPE_CODE_ENUM: ScalarExplorer,
134 gdb.TYPE_CODE_STRUCT: CompoundExplorer,
135 gdb.TYPE_CODE_UNION: CompoundExplorer,
136 gdb.TYPE_CODE_PTR: PointerExplorer,
137 gdb.TYPE_CODE_REF: ReferenceExplorer,
138 gdb.TYPE_CODE_RVALUE_REF: ReferenceExplorer,
139 gdb.TYPE_CODE_TYPEDEF: TypedefExplorer,
140 gdb.TYPE_CODE_ARRAY: ArrayExplorer,
144 def is_scalar_type(type):
145 """Checks whether a type is a scalar type.
146 A type is a scalar type of its type is
147 gdb.TYPE_CODE_CHAR or
149 gdb.TYPE_CODE_BOOL or
151 gdb.TYPE_CODE_VOID or
155 type: The type to be checked.
158 'True' if 'type' is a scalar type. 'False' otherwise.
160 return type.code in Explorer._SCALAR_TYPE_LIST
163 def return_to_parent_value():
164 """A utility function which prints that the current exploration session
165 is returning to the parent value. Useful when exploring values.
167 print("\nReturning to parent value...\n")
170 def return_to_parent_value_prompt():
171 """A utility function which prompts the user to press the 'enter' key
172 so that the exploration session can shift back to the parent value.
173 Useful when exploring values.
175 raw_input("\nPress enter to return to parent value: ")
178 def return_to_enclosing_type():
179 """A utility function which prints that the current exploration session
180 is returning to the enclosing type. Useful when exploring types.
182 print("\nReturning to enclosing type...\n")
185 def return_to_enclosing_type_prompt():
186 """A utility function which prompts the user to press the 'enter' key
187 so that the exploration session can shift back to the enclosing type.
188 Useful when exploring types.
190 raw_input("\nPress enter to return to enclosing type: ")
193 class ScalarExplorer(object):
194 """Internal class used to explore scalar values."""
197 def explore_expr(expr, value, is_child):
198 """Function to explore scalar values.
199 See Explorer.explore_expr and Explorer.is_scalar_type for more
202 print("'%s' is a scalar value of type '%s'." % (expr, value.type))
203 print("%s = %s" % (expr, str(value)))
206 Explorer.return_to_parent_value_prompt()
207 Explorer.return_to_parent_value()
212 def explore_type(name, datatype, is_child):
213 """Function to explore scalar types.
214 See Explorer.explore_type and Explorer.is_scalar_type for more
217 if datatype.code == gdb.TYPE_CODE_ENUM:
219 print("%s is of an enumerated type '%s'." % (name, str(datatype)))
221 print("'%s' is an enumerated type." % name)
224 print("%s is of a scalar type '%s'." % (name, str(datatype)))
226 print("'%s' is a scalar type." % name)
229 Explorer.return_to_enclosing_type_prompt()
230 Explorer.return_to_enclosing_type()
235 class PointerExplorer(object):
236 """Internal class used to explore pointer values."""
239 def explore_expr(expr, value, is_child):
240 """Function to explore pointer values.
241 See Explorer.explore_expr for more information.
244 "'%s' is a pointer to a value of type '%s'"
245 % (expr, str(value.type.target()))
248 "Continue exploring it as a pointer to a single " "value [y/n]: "
253 deref_value = value.dereference()
255 except gdb.MemoryError:
257 "'%s' a pointer pointing to an invalid memory " "location." % expr
260 Explorer.return_to_parent_value_prompt()
262 Explorer.explore_expr(
263 "*%s" % Explorer.guard_expr(expr), deref_value, is_child
267 option = raw_input("Continue exploring it as a pointer to an " "array [y/n]: ")
274 "Enter the index of the element you "
275 "want to explore in '%s': " % expr
280 element_expr = "%s[%d]" % (Explorer.guard_expr(expr), index)
281 element = value[index]
284 except gdb.MemoryError:
285 print("Cannot read value at index %d." % index)
287 Explorer.explore_expr(element_expr, element, True)
291 Explorer.return_to_parent_value()
295 def explore_type(name, datatype, is_child):
296 """Function to explore pointer types.
297 See Explorer.explore_type for more information.
299 target_type = datatype.target()
300 print("\n%s is a pointer to a value of type '%s'." % (name, str(target_type)))
302 Explorer.explore_type("the pointee type of %s" % name, target_type, is_child)
306 class ReferenceExplorer(object):
307 """Internal class used to explore reference (TYPE_CODE_REF) values."""
310 def explore_expr(expr, value, is_child):
311 """Function to explore array values.
312 See Explorer.explore_expr for more information.
314 referenced_value = value.referenced_value()
315 Explorer.explore_expr(expr, referenced_value, is_child)
319 def explore_type(name, datatype, is_child):
320 """Function to explore pointer types.
321 See Explorer.explore_type for more information.
323 target_type = datatype.target()
324 Explorer.explore_type(name, target_type, is_child)
328 class ArrayExplorer(object):
329 """Internal class used to explore arrays."""
332 def explore_expr(expr, value, is_child):
333 """Function to explore array values.
334 See Explorer.explore_expr for more information.
336 target_type = value.type.target()
337 print("'%s' is an array of '%s'." % (expr, str(target_type)))
342 "Enter the index of the element you want to "
343 "explore in '%s': " % expr
348 Explorer.return_to_parent_value()
353 element = value[index]
355 except gdb.MemoryError:
356 print("Cannot read value at index %d." % index)
357 raw_input("Press enter to continue... ")
360 Explorer.explore_expr(
361 "%s[%d]" % (Explorer.guard_expr(expr), index), element, True
366 def explore_type(name, datatype, is_child):
367 """Function to explore array types.
368 See Explorer.explore_type for more information.
370 target_type = datatype.target()
371 print("%s is an array of '%s'." % (name, str(target_type)))
373 Explorer.explore_type("the array element of %s" % name, target_type, is_child)
377 class CompoundExplorer(object):
378 """Internal class used to explore struct, classes and unions."""
381 def _print_fields(print_list):
382 """Internal function which prints the fields of a struct/class/union."""
383 max_field_name_length = 0
384 for pair in print_list:
385 if max_field_name_length < len(pair[0]):
386 max_field_name_length = len(pair[0])
388 for pair in print_list:
389 print(" %*s = %s" % (max_field_name_length, pair[0], pair[1]))
392 def _get_real_field_count(fields):
395 if not field.artificial:
396 real_field_count = real_field_count + 1
398 return real_field_count
401 def explore_expr(expr, value, is_child):
402 """Function to explore structs/classes and union values.
403 See Explorer.explore_expr for more information.
405 datatype = value.type
406 type_code = datatype.code
407 fields = datatype.fields()
409 if type_code == gdb.TYPE_CODE_STRUCT:
410 type_desc = "struct/class"
414 if CompoundExplorer._get_real_field_count(fields) == 0:
416 "The value of '%s' is a %s of type '%s' with no fields."
417 % (expr, type_desc, str(value.type))
420 Explorer.return_to_parent_value_prompt()
424 "The value of '%s' is a %s of type '%s' with the following "
425 "fields:\n" % (expr, type_desc, str(value.type))
428 has_explorable_fields = False
429 choice_to_compound_field_map = {}
435 field_full_name = Explorer.guard_expr(expr) + "." + field.name
436 if field.is_base_class:
437 field_value = value.cast(field.type)
439 field_value = value[field.name]
441 if type_code == gdb.TYPE_CODE_UNION:
442 literal_value = "<Enter %d to explore this field of type " "'%s'>" % (
446 has_explorable_fields = True
448 if Explorer.is_scalar_type(field.type):
449 literal_value = "%s .. (Value of type '%s')" % (
454 if field.is_base_class:
455 field_desc = "base class"
458 literal_value = "<Enter %d to explore this %s of type " "'%s'>" % (
463 has_explorable_fields = True
465 choice_to_compound_field_map[str(current_choice)] = (
469 current_choice = current_choice + 1
471 print_list.append((field.name, literal_value))
473 CompoundExplorer._print_fields(print_list)
476 if has_explorable_fields:
477 choice = raw_input("Enter the field number of choice: ")
478 if choice in choice_to_compound_field_map:
479 Explorer.explore_expr(
480 choice_to_compound_field_map[choice][0],
481 choice_to_compound_field_map[choice][1],
487 Explorer.return_to_parent_value()
490 Explorer.return_to_parent_value_prompt()
495 def explore_type(name, datatype, is_child):
496 """Function to explore struct/class and union types.
497 See Explorer.explore_type for more information.
499 type_code = datatype.code
501 if type_code == gdb.TYPE_CODE_STRUCT:
502 type_desc = "struct/class"
506 fields = datatype.fields()
507 if CompoundExplorer._get_real_field_count(fields) == 0:
510 "%s is a %s of type '%s' with no fields."
511 % (name, type_desc, str(datatype))
513 Explorer.return_to_enclosing_type_prompt()
515 print("'%s' is a %s with no fields." % (name, type_desc))
520 "%s is a %s of type '%s' "
521 "with the following fields:\n" % (name, type_desc, str(datatype))
524 print("'%s' is a %s with the following " "fields:\n" % (name, type_desc))
527 choice_to_compound_field_map = {}
532 if field.is_base_class:
533 field_desc = "base class"
536 rhs = "<Enter %d to explore this %s of type '%s'>" % (
541 print_list.append((field.name, rhs))
542 choice_to_compound_field_map[str(current_choice)] = (
547 current_choice = current_choice + 1
549 CompoundExplorer._print_fields(print_list)
552 if len(choice_to_compound_field_map) > 0:
553 choice = raw_input("Enter the field number of choice: ")
554 if choice in choice_to_compound_field_map:
556 new_name = "%s '%s' of %s" % (
557 choice_to_compound_field_map[choice][2],
558 choice_to_compound_field_map[choice][0],
562 new_name = "%s '%s' of '%s'" % (
563 choice_to_compound_field_map[choice][2],
564 choice_to_compound_field_map[choice][0],
567 Explorer.explore_type(
568 new_name, choice_to_compound_field_map[choice][1], True
573 Explorer.return_to_enclosing_type()
576 Explorer.return_to_enclosing_type_prompt()
581 class TypedefExplorer(object):
582 """Internal class used to explore values whose type is a typedef."""
585 def explore_expr(expr, value, is_child):
586 """Function to explore typedef values.
587 See Explorer.explore_expr for more information.
589 actual_type = value.type.strip_typedefs()
591 "The value of '%s' is of type '%s' "
592 "which is a typedef of type '%s'"
593 % (expr, str(value.type), str(actual_type))
596 Explorer.explore_expr(expr, value.cast(actual_type), is_child)
600 def explore_type(name, datatype, is_child):
601 """Function to explore typedef types.
602 See Explorer.explore_type for more information.
604 actual_type = datatype.strip_typedefs()
607 "The type of %s is a typedef of type '%s'." % (name, str(actual_type))
610 print("The type '%s' is a typedef of type '%s'." % (name, str(actual_type)))
612 Explorer.explore_type(name, actual_type, is_child)
616 class ExploreUtils(object):
617 """Internal class which provides utilities for the main command classes."""
620 def check_args(name, arg_str):
621 """Utility to check if adequate number of arguments are passed to an
625 name: The name of the explore command.
626 arg_str: The argument string passed to the explore command.
629 True if adequate arguments are passed, false otherwise.
632 gdb.GdbError if adequate arguments are not passed.
635 raise gdb.GdbError("ERROR: '%s' requires an argument." % name)
641 def get_type_from_str(type_str):
642 """A utility function to deduce the gdb.Type value from a string
643 representing the type.
646 type_str: The type string from which the gdb.Type value should be
650 The deduced gdb.Type value if possible, None otherwise.
653 # Assume the current language to be C/C++ and make a try.
654 return gdb.parse_and_eval("(%s *)0" % type_str).type.target()
656 # If assumption of current language to be C/C++ was wrong, then
657 # lookup the type using the API.
659 return gdb.lookup_type(type_str)
664 def get_value_from_str(value_str):
665 """A utility function to deduce the gdb.Value value from a string
666 representing the value.
669 value_str: The value string from which the gdb.Value value should
673 The deduced gdb.Value value if possible, None otherwise.
676 return gdb.parse_and_eval(value_str)
681 class ExploreCommand(gdb.Command):
682 """Explore a value or a type valid in the current context.
686 - ARG is either a valid expression or a type name.
687 - At any stage of exploration, hit the return key (instead of a
688 choice, if any) to return to the enclosing type or value."""
691 super(ExploreCommand, self).__init__(
692 name="explore", command_class=gdb.COMMAND_DATA, prefix=True
695 def invoke(self, arg_str, from_tty):
696 if ExploreUtils.check_args("explore", arg_str) is False:
699 # Check if it is a value
700 value = ExploreUtils.get_value_from_str(arg_str)
701 if value is not None:
702 Explorer.explore_expr(arg_str, value, False)
705 # If it is not a value, check if it is a type
706 datatype = ExploreUtils.get_type_from_str(arg_str)
707 if datatype is not None:
708 Explorer.explore_type(arg_str, datatype, False)
711 # If it is neither a value nor a type, raise an error.
714 "'%s' neither evaluates to a value nor is a type "
715 "in the current context." % arg_str
720 class ExploreValueCommand(gdb.Command):
721 """Explore value of an expression valid in the current context.
723 Usage: explore value ARG
725 - ARG is a valid expression.
726 - At any stage of exploration, hit the return key (instead of a
727 choice, if any) to return to the enclosing value."""
730 super(ExploreValueCommand, self).__init__(
731 name="explore value", command_class=gdb.COMMAND_DATA
734 def invoke(self, arg_str, from_tty):
735 if ExploreUtils.check_args("explore value", arg_str) is False:
738 value = ExploreUtils.get_value_from_str(arg_str)
742 " '%s' does not evaluate to a value in the current "
748 Explorer.explore_expr(arg_str, value, False)
751 class ExploreTypeCommand(gdb.Command):
752 """Explore a type or the type of an expression.
754 Usage: explore type ARG
756 - ARG is a valid expression or a type name.
757 - At any stage of exploration, hit the return key (instead of a
758 choice, if any) to return to the enclosing type."""
761 super(ExploreTypeCommand, self).__init__(
762 name="explore type", command_class=gdb.COMMAND_DATA
765 def invoke(self, arg_str, from_tty):
766 if ExploreUtils.check_args("explore type", arg_str) is False:
769 datatype = ExploreUtils.get_type_from_str(arg_str)
770 if datatype is not None:
771 Explorer.explore_type(arg_str, datatype, False)
774 value = ExploreUtils.get_value_from_str(arg_str)
775 if value is not None:
776 print("'%s' is of type '%s'." % (arg_str, str(value.type)))
777 Explorer.explore_type(str(value.type), value.type, False)
781 ("'%s' is not a type or value in the current " "context." % arg_str)
788 ExploreValueCommand()