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