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