17"""Implementation of the GDB 'explore' command using the GDB Python API."""
23 """Internal class which invokes other explorers."""
26 type_code_to_explorer_map = {}
42 if expr[0] ==
"(" and expr[length - 1] ==
")":
50 or (
"a" <= c
and c <=
"z")
51 or (
"A" <= c
and c <=
"Z")
52 or (
"0" <= c
and c <=
"9")
61 return "(" + expr +
")"
67 """Main function to explore an expression value.
70 expr: The expression string that is being explored.
71 value: The gdb.Value value of the expression.
72 is_child: Boolean value to indicate if the expression is a child.
73 An expression is a child if it is derived from the main
74 expression entered by the user. For example, if the user
75 entered an expression which evaluates to a struct, then
76 when exploring the fields of the struct, is_child is set
82 type_code = value.type.code
83 if type_code
in Explorer.type_code_to_explorer_map:
84 explorer_class = Explorer.type_code_to_explorer_map[type_code]
85 while explorer_class.explore_expr(expr, value, is_child):
88 print(
"Explorer for type '%s' not yet available.\n" % str(value.type))
92 """Main function to explore a data type.
95 name: The string representing the path to the data type being
97 datatype: The gdb.Type value of the data type being explored.
98 is_child: Boolean value to indicate if the name is a child.
99 A name is a child if it is derived from the main name
100 entered by the user. For example, if the user entered
101 the name of struct type, then when exploring the fields
102 of the struct, is_child is set to True internally.
107 type_code = datatype.code
108 if type_code
in Explorer.type_code_to_explorer_map:
109 explorer_class = Explorer.type_code_to_explorer_map[type_code]
110 while explorer_class.explore_type(name, datatype, is_child):
113 print(
"Explorer for type '%s' not yet available.\n" % str(datatype))
117 """Initializes the Explorer environment.
118 This function should be invoked before starting any exploration. If
119 invoked before an exploration, it need not be invoked for subsequent
122 Explorer.type_code_to_explorer_map = {
123 gdb.TYPE_CODE_CHAR: ScalarExplorer,
124 gdb.TYPE_CODE_INT: ScalarExplorer,
125 gdb.TYPE_CODE_BOOL: ScalarExplorer,
126 gdb.TYPE_CODE_FLT: ScalarExplorer,
127 gdb.TYPE_CODE_VOID: ScalarExplorer,
128 gdb.TYPE_CODE_ENUM: ScalarExplorer,
129 gdb.TYPE_CODE_STRUCT: CompoundExplorer,
130 gdb.TYPE_CODE_UNION: CompoundExplorer,
131 gdb.TYPE_CODE_PTR: PointerExplorer,
132 gdb.TYPE_CODE_REF: ReferenceExplorer,
133 gdb.TYPE_CODE_RVALUE_REF: ReferenceExplorer,
134 gdb.TYPE_CODE_TYPEDEF: TypedefExplorer,
135 gdb.TYPE_CODE_ARRAY: ArrayExplorer,
140 """Checks whether a type is a scalar type.
141 A type is a scalar type of its type is
142 gdb.TYPE_CODE_CHAR or
144 gdb.TYPE_CODE_BOOL or
146 gdb.TYPE_CODE_VOID or
150 type: The type to be checked.
153 'True' if 'type' is a scalar type. 'False' otherwise.
155 return type.code
in Explorer._SCALAR_TYPE_LIST
159 """A utility function which prints that the current exploration session
160 is returning to the parent value. Useful when exploring values.
162 print(
"\nReturning to parent value...\n")
166 """A utility function which prompts the user to press the 'enter' key
167 so that the exploration session can shift back to the parent value.
168 Useful when exploring values.
170 input(
"\nPress enter to return to parent value: ")
174 """A utility function which prints that the current exploration session
175 is returning to the enclosing type. Useful when exploring types.
177 print(
"\nReturning to enclosing type...\n")
181 """A utility function which prompts the user to press the 'enter' key
182 so that the exploration session can shift back to the enclosing type.
183 Useful when exploring types.
185 input(
"\nPress enter to return to enclosing type: ")
189 """Internal class used to explore scalar values."""
193 """Function to explore scalar values.
194 See Explorer.explore_expr and Explorer.is_scalar_type for more
197 print(
"'%s' is a scalar value of type '%s'." % (expr, value.type))
198 print(
"%s = %s" % (expr, str(value)))
201 Explorer.return_to_parent_value_prompt()
202 Explorer.return_to_parent_value()
208 """Function to explore scalar types.
209 See Explorer.explore_type and Explorer.is_scalar_type for more
212 if datatype.code == gdb.TYPE_CODE_ENUM:
214 print(
"%s is of an enumerated type '%s'." % (name, str(datatype)))
216 print(
"'%s' is an enumerated type." % name)
219 print(
"%s is of a scalar type '%s'." % (name, str(datatype)))
221 print(
"'%s' is a scalar type." % name)
224 Explorer.return_to_enclosing_type_prompt()
225 Explorer.return_to_enclosing_type()
231 """Internal class used to explore pointer values."""
235 """Function to explore pointer values.
236 See Explorer.explore_expr for more information.
239 "'%s' is a pointer to a value of type '%s'"
240 % (expr, str(value.type.target()))
243 "Continue exploring it as a pointer to a single " "value [y/n]: "
248 deref_value = value.dereference()
250 except gdb.MemoryError:
252 "'%s' a pointer pointing to an invalid memory " "location." % expr
255 Explorer.return_to_parent_value_prompt()
257 Explorer.explore_expr(
258 "*%s" % Explorer.guard_expr(expr), deref_value, is_child
262 option = input(
"Continue exploring it as a pointer to an " "array [y/n]: ")
269 "Enter the index of the element you "
270 "want to explore in '%s': " % expr
275 element_expr =
"%s[%d]" % (Explorer.guard_expr(expr), index)
276 element = value[index]
279 except gdb.MemoryError:
280 print(
"Cannot read value at index %d." % index)
282 Explorer.explore_expr(element_expr, element,
True)
286 Explorer.return_to_parent_value()
291 """Function to explore pointer types.
292 See Explorer.explore_type for more information.
294 target_type = datatype.target()
295 print(
"\n%s is a pointer to a value of type '%s'." % (name, str(target_type)))
297 Explorer.explore_type(
"the pointee type of %s" % name, target_type, is_child)
302 """Internal class used to explore reference (TYPE_CODE_REF) values."""
306 """Function to explore array values.
307 See Explorer.explore_expr for more information.
309 referenced_value = value.referenced_value()
310 Explorer.explore_expr(expr, referenced_value, is_child)
315 """Function to explore pointer types.
316 See Explorer.explore_type for more information.
318 target_type = datatype.target()
319 Explorer.explore_type(name, target_type, is_child)
324 """Internal class used to explore arrays."""
328 """Function to explore array values.
329 See Explorer.explore_expr for more information.
331 target_type = value.type.target()
332 print(
"'%s' is an array of '%s'." % (expr, str(target_type)))
337 "Enter the index of the element you want to "
338 "explore in '%s': " % expr
343 Explorer.return_to_parent_value()
348 element = value[index]
350 except gdb.MemoryError:
351 print(
"Cannot read value at index %d." % index)
352 input(
"Press enter to continue... ")
355 Explorer.explore_expr(
356 "%s[%d]" % (Explorer.guard_expr(expr), index), element,
True
362 """Function to explore array types.
363 See Explorer.explore_type for more information.
365 target_type = datatype.target()
366 print(
"%s is an array of '%s'." % (name, str(target_type)))
368 Explorer.explore_type(
"the array element of %s" % name, target_type, is_child)
373 """Internal class used to explore struct, classes and unions."""
377 """Internal function which prints the fields of a struct/class/union."""
378 max_field_name_length = 0
379 for pair
in print_list:
380 if max_field_name_length < len(pair[0]):
381 max_field_name_length = len(pair[0])
383 for pair
in print_list:
384 print(
" %*s = %s" % (max_field_name_length, pair[0], pair[1]))
390 if not field.artificial:
391 real_field_count = real_field_count + 1
393 return real_field_count
397 """Function to explore structs/classes and union values.
398 See Explorer.explore_expr for more information.
400 datatype = value.type
401 type_code = datatype.code
402 fields = datatype.fields()
404 if type_code == gdb.TYPE_CODE_STRUCT:
405 type_desc =
"struct/class"
409 if CompoundExplorer._get_real_field_count(fields) == 0:
411 "The value of '%s' is a %s of type '%s' with no fields."
412 % (expr, type_desc, str(value.type))
415 Explorer.return_to_parent_value_prompt()
419 "The value of '%s' is a %s of type '%s' with the following "
420 "fields:\n" % (expr, type_desc, str(value.type))
423 has_explorable_fields =
False
424 choice_to_compound_field_map = {}
430 field_full_name = Explorer.guard_expr(expr) +
"." + field.name
431 if field.is_base_class:
432 field_value = value.cast(field.type)
434 field_value = value[field.name]
436 if type_code == gdb.TYPE_CODE_UNION:
437 literal_value =
"<Enter %d to explore this field of type " "'%s'>" % (
441 has_explorable_fields =
True
443 if Explorer.is_scalar_type(field.type):
444 literal_value =
"%s .. (Value of type '%s')" % (
449 if field.is_base_class:
450 field_desc =
"base class"
453 literal_value =
"<Enter %d to explore this %s of type " "'%s'>" % (
458 has_explorable_fields =
True
460 choice_to_compound_field_map[str(current_choice)] = (
464 current_choice = current_choice + 1
466 print_list.append((field.name, literal_value))
468 CompoundExplorer._print_fields(print_list)
471 if has_explorable_fields:
472 choice = input(
"Enter the field number of choice: ")
473 if choice
in choice_to_compound_field_map:
474 Explorer.explore_expr(
475 choice_to_compound_field_map[choice][0],
476 choice_to_compound_field_map[choice][1],
482 Explorer.return_to_parent_value()
485 Explorer.return_to_parent_value_prompt()
491 """Function to explore struct/class and union types.
492 See Explorer.explore_type for more information.
494 type_code = datatype.code
496 if type_code == gdb.TYPE_CODE_STRUCT:
497 type_desc =
"struct/class"
501 fields = datatype.fields()
502 if CompoundExplorer._get_real_field_count(fields) == 0:
505 "%s is a %s of type '%s' with no fields."
506 % (name, type_desc, str(datatype))
508 Explorer.return_to_enclosing_type_prompt()
510 print(
"'%s' is a %s with no fields." % (name, type_desc))
515 "%s is a %s of type '%s' "
516 "with the following fields:\n" % (name, type_desc, str(datatype))
519 print(
"'%s' is a %s with the following " "fields:\n" % (name, type_desc))
522 choice_to_compound_field_map = {}
527 if field.is_base_class:
528 field_desc =
"base class"
531 rhs =
"<Enter %d to explore this %s of type '%s'>" % (
536 print_list.append((field.name, rhs))
537 choice_to_compound_field_map[str(current_choice)] = (
542 current_choice = current_choice + 1
544 CompoundExplorer._print_fields(print_list)
547 if len(choice_to_compound_field_map) > 0:
548 choice = input(
"Enter the field number of choice: ")
549 if choice
in choice_to_compound_field_map:
551 new_name =
"%s '%s' of %s" % (
552 choice_to_compound_field_map[choice][2],
553 choice_to_compound_field_map[choice][0],
557 new_name =
"%s '%s' of '%s'" % (
558 choice_to_compound_field_map[choice][2],
559 choice_to_compound_field_map[choice][0],
562 Explorer.explore_type(
563 new_name, choice_to_compound_field_map[choice][1],
True
568 Explorer.return_to_enclosing_type()
571 Explorer.return_to_enclosing_type_prompt()
577 """Internal class used to explore values whose type is a typedef."""
581 """Function to explore typedef values.
582 See Explorer.explore_expr for more information.
584 actual_type = value.type.strip_typedefs()
586 "The value of '%s' is of type '%s' "
587 "which is a typedef of type '%s'"
588 % (expr, str(value.type), str(actual_type))
591 Explorer.explore_expr(expr, value.cast(actual_type), is_child)
596 """Function to explore typedef types.
597 See Explorer.explore_type for more information.
599 actual_type = datatype.strip_typedefs()
602 "The type of %s is a typedef of type '%s'." % (name, str(actual_type))
605 print(
"The type '%s' is a typedef of type '%s'." % (name, str(actual_type)))
607 Explorer.explore_type(name, actual_type, is_child)
612 """Internal class which provides utilities for the main command classes."""
616 """Utility to check if adequate number of arguments are passed to an
620 name: The name of the explore command.
621 arg_str: The argument string passed to the explore command.
624 True if adequate arguments are passed, false otherwise.
627 gdb.GdbError if adequate arguments are not passed.
630 raise gdb.GdbError(
"ERROR: '%s' requires an argument." % name)
637 """A utility function to deduce the gdb.Type value from a string
638 representing the type.
641 type_str: The type string from which the gdb.Type value should be
645 The deduced gdb.Type value if possible, None otherwise.
649 return gdb.parse_and_eval(
"(%s *)0" % type_str).type.target()
654 return gdb.lookup_type(type_str)
660 """A utility function to deduce the gdb.Value value from a string
661 representing the value.
664 value_str: The value string from which the gdb.Value value should
668 The deduced gdb.Value value if possible, None otherwise.
671 return gdb.parse_and_eval(value_str)
677 """Explore a value or a type valid in the current context.
681 - ARG is either a valid expression or a type name.
682 - At any stage of exploration, hit the return key (instead of a
683 choice, if any) to return to the enclosing type or value."""
686 super(ExploreCommand, self).
__init__(
687 name=
"explore", command_class=gdb.COMMAND_DATA, prefix=
True
691 if ExploreUtils.check_args(
"explore", arg_str)
is False:
695 value = ExploreUtils.get_value_from_str(arg_str)
696 if value
is not None:
697 Explorer.explore_expr(arg_str, value,
False)
701 datatype = ExploreUtils.get_type_from_str(arg_str)
702 if datatype
is not None:
703 Explorer.explore_type(arg_str, datatype,
False)
709 "'%s' neither evaluates to a value nor is a type "
710 "in the current context." % arg_str
716 """Explore value of an expression valid in the current context.
718 Usage: explore value ARG
720 - ARG is a valid expression.
721 - At any stage of exploration, hit the return key (instead of a
722 choice, if any) to return to the enclosing value."""
725 super(ExploreValueCommand, self).
__init__(
726 name=
"explore value", command_class=gdb.COMMAND_DATA
730 if ExploreUtils.check_args(
"explore value", arg_str)
is False:
733 value = ExploreUtils.get_value_from_str(arg_str)
737 " '%s' does not evaluate to a value in the current "
743 Explorer.explore_expr(arg_str, value,
False)
747 """Explore a type or the type of an expression.
749 Usage: explore type ARG
751 - ARG is a valid expression or a type name.
752 - At any stage of exploration, hit the return key (instead of a
753 choice, if any) to return to the enclosing type."""
756 super(ExploreTypeCommand, self).
__init__(
757 name=
"explore type", command_class=gdb.COMMAND_DATA
761 if ExploreUtils.check_args(
"explore type", arg_str)
is False:
764 datatype = ExploreUtils.get_type_from_str(arg_str)
765 if datatype
is not None:
766 Explorer.explore_type(arg_str, datatype,
False)
769 value = ExploreUtils.get_value_from_str(arg_str)
770 if value
is not None:
771 print(
"'%s' is of type '%s'." % (arg_str, str(value.type)))
772 Explorer.explore_type(str(value.type), value.type,
False)
776 (
"'%s' is not a type or value in the current " "context." % arg_str)
explore_expr(expr, value, is_child)
explore_type(name, datatype, is_child)
explore_type(name, datatype, is_child)
_get_real_field_count(fields)
explore_expr(expr, value, is_child)
_print_fields(print_list)
invoke(self, arg_str, from_tty)
invoke(self, arg_str, from_tty)
get_value_from_str(value_str)
get_type_from_str(type_str)
check_args(name, arg_str)
invoke(self, arg_str, from_tty)
explore_expr(expr, value, is_child)
return_to_enclosing_type_prompt()
return_to_parent_value_prompt()
return_to_enclosing_type()
explore_type(name, datatype, is_child)
explore_expr(expr, value, is_child)
explore_type(name, datatype, is_child)
explore_expr(expr, value, is_child)
explore_type(name, datatype, is_child)
explore_type(name, datatype, is_child)
explore_expr(expr, value, is_child)
explore_type(name, datatype, is_child)
explore_expr(expr, value, is_child)