Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2011 the V8 project authors. All rights reserved. | 3 # Copyright 2011 the V8 project authors. All rights reserved. |
| 4 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
| 5 # modification, are permitted provided that the following conditions are | 5 # modification, are permitted provided that the following conditions are |
| 6 # met: | 6 # met: |
| 7 # | 7 # |
| 8 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
| 9 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
| 10 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 516 # }; | 516 # }; |
| 517 # static P p; | 517 # static P p; |
| 518 INSTANCE_TYPES = { | 518 INSTANCE_TYPES = { |
| 519 64: "SYMBOL_TYPE", | 519 64: "SYMBOL_TYPE", |
| 520 68: "ASCII_SYMBOL_TYPE", | 520 68: "ASCII_SYMBOL_TYPE", |
| 521 65: "CONS_SYMBOL_TYPE", | 521 65: "CONS_SYMBOL_TYPE", |
| 522 69: "CONS_ASCII_SYMBOL_TYPE", | 522 69: "CONS_ASCII_SYMBOL_TYPE", |
| 523 66: "EXTERNAL_SYMBOL_TYPE", | 523 66: "EXTERNAL_SYMBOL_TYPE", |
| 524 74: "EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE", | 524 74: "EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE", |
| 525 70: "EXTERNAL_ASCII_SYMBOL_TYPE", | 525 70: "EXTERNAL_ASCII_SYMBOL_TYPE", |
| 526 82: "SHORT_EXTERNAL_SYMBOL_TYPE", | |
| 527 90: "SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE", | |
| 528 86: "SHORT_EXTERNAL_ASCII_SYMBOL_TYPE", | |
| 526 0: "STRING_TYPE", | 529 0: "STRING_TYPE", |
| 527 4: "ASCII_STRING_TYPE", | 530 4: "ASCII_STRING_TYPE", |
| 528 1: "CONS_STRING_TYPE", | 531 1: "CONS_STRING_TYPE", |
| 529 5: "CONS_ASCII_STRING_TYPE", | 532 5: "CONS_ASCII_STRING_TYPE", |
| 533 3: "SLICED_STRING_TYPE", | |
| 530 2: "EXTERNAL_STRING_TYPE", | 534 2: "EXTERNAL_STRING_TYPE", |
| 531 10: "EXTERNAL_STRING_WITH_ASCII_DATA_TYPE", | 535 10: "EXTERNAL_STRING_WITH_ASCII_DATA_TYPE", |
| 532 6: "EXTERNAL_ASCII_STRING_TYPE", | 536 6: "EXTERNAL_ASCII_STRING_TYPE", |
| 537 18: "SHORT_EXTERNAL_STRING_TYPE", | |
| 538 26: "SHORT_EXTERNAL_STRING_WITH_ASCII_DATA_TYPE", | |
| 539 22: "SHORT_EXTERNAL_ASCII_STRING_TYPE", | |
| 533 6: "PRIVATE_EXTERNAL_ASCII_STRING_TYPE", | 540 6: "PRIVATE_EXTERNAL_ASCII_STRING_TYPE", |
| 534 128: "MAP_TYPE", | 541 128: "MAP_TYPE", |
| 535 129: "CODE_TYPE", | 542 129: "CODE_TYPE", |
| 536 130: "ODDBALL_TYPE", | 543 130: "ODDBALL_TYPE", |
| 537 131: "JS_GLOBAL_PROPERTY_CELL_TYPE", | 544 131: "JS_GLOBAL_PROPERTY_CELL_TYPE", |
| 538 132: "HEAP_NUMBER_TYPE", | 545 132: "HEAP_NUMBER_TYPE", |
| 539 133: "FOREIGN_TYPE", | 546 133: "FOREIGN_TYPE", |
| 540 134: "BYTE_ARRAY_TYPE", | 547 134: "BYTE_ARRAY_TYPE", |
| 541 135: "EXTERNAL_BYTE_ARRAY_TYPE", | 548 135: "FREE_SPACE_TYPE", |
| 542 136: "EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE", | 549 136: "EXTERNAL_BYTE_ARRAY_TYPE", |
| 543 137: "EXTERNAL_SHORT_ARRAY_TYPE", | 550 137: "EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE", |
| 544 138: "EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE", | 551 138: "EXTERNAL_SHORT_ARRAY_TYPE", |
| 545 139: "EXTERNAL_INT_ARRAY_TYPE", | 552 139: "EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE", |
| 546 140: "EXTERNAL_UNSIGNED_INT_ARRAY_TYPE", | 553 140: "EXTERNAL_INT_ARRAY_TYPE", |
| 547 141: "EXTERNAL_FLOAT_ARRAY_TYPE", | 554 141: "EXTERNAL_UNSIGNED_INT_ARRAY_TYPE", |
| 548 143: "EXTERNAL_PIXEL_ARRAY_TYPE", | 555 142: "EXTERNAL_FLOAT_ARRAY_TYPE", |
| 549 145: "FILLER_TYPE", | 556 144: "EXTERNAL_PIXEL_ARRAY_TYPE", |
| 550 146: "ACCESSOR_INFO_TYPE", | 557 146: "FILLER_TYPE", |
| 551 147: "ACCESS_CHECK_INFO_TYPE", | 558 147: "ACCESSOR_INFO_TYPE", |
| 552 148: "INTERCEPTOR_INFO_TYPE", | 559 148: "ACCESS_CHECK_INFO_TYPE", |
| 553 149: "CALL_HANDLER_INFO_TYPE", | 560 149: "INTERCEPTOR_INFO_TYPE", |
| 554 150: "FUNCTION_TEMPLATE_INFO_TYPE", | 561 150: "CALL_HANDLER_INFO_TYPE", |
| 555 151: "OBJECT_TEMPLATE_INFO_TYPE", | 562 151: "FUNCTION_TEMPLATE_INFO_TYPE", |
| 556 152: "SIGNATURE_INFO_TYPE", | 563 152: "OBJECT_TEMPLATE_INFO_TYPE", |
| 557 153: "TYPE_SWITCH_INFO_TYPE", | 564 153: "SIGNATURE_INFO_TYPE", |
| 558 154: "SCRIPT_TYPE", | 565 154: "TYPE_SWITCH_INFO_TYPE", |
| 559 155: "CODE_CACHE_TYPE", | 566 155: "SCRIPT_TYPE", |
| 560 156: "POLYMORPHIC_CODE_CACHE_TYPE", | 567 156: "CODE_CACHE_TYPE", |
| 561 159: "FIXED_ARRAY_TYPE", | 568 157: "POLYMORPHIC_CODE_CACHE_TYPE", |
| 562 160: "SHARED_FUNCTION_INFO_TYPE", | 569 160: "FIXED_ARRAY_TYPE", |
| 563 161: "JS_MESSAGE_OBJECT_TYPE", | 570 145: "FIXED_DOUBLE_ARRAY_TYPE", |
| 564 162: "JS_VALUE_TYPE", | 571 161: "SHARED_FUNCTION_INFO_TYPE", |
| 565 163: "JS_OBJECT_TYPE", | 572 162: "JS_MESSAGE_OBJECT_TYPE", |
| 566 164: "JS_CONTEXT_EXTENSION_OBJECT_TYPE", | 573 165: "JS_VALUE_TYPE", |
| 567 165: "JS_GLOBAL_OBJECT_TYPE", | 574 166: "JS_OBJECT_TYPE", |
| 568 166: "JS_BUILTINS_OBJECT_TYPE", | 575 167: "JS_CONTEXT_EXTENSION_OBJECT_TYPE", |
| 569 167: "JS_GLOBAL_PROXY_TYPE", | 576 168: "JS_GLOBAL_OBJECT_TYPE", |
| 570 168: "JS_ARRAY_TYPE", | 577 169: "JS_BUILTINS_OBJECT_TYPE", |
| 571 169: "JS_PROXY_TYPE", | 578 170: "JS_GLOBAL_PROXY_TYPE", |
| 572 170: "JS_WEAK_MAP_TYPE", | 579 171: "JS_ARRAY_TYPE", |
| 573 171: "JS_REGEXP_TYPE", | 580 164: "JS_PROXY_TYPE", |
| 574 172: "JS_FUNCTION_TYPE", | 581 174: "JS_WEAK_MAP_TYPE", |
| 575 173: "JS_FUNCTION_PROXY_TYPE", | 582 175: "JS_REGEXP_TYPE", |
| 576 157: "DEBUG_INFO_TYPE", | 583 176: "JS_FUNCTION_TYPE", |
| 577 158: "BREAK_POINT_INFO_TYPE", | 584 163: "JS_FUNCTION_PROXY_TYPE", |
| 585 158: "DEBUG_INFO_TYPE", | |
| 586 159: "BREAK_POINT_INFO_TYPE", | |
| 578 } | 587 } |
| 579 | 588 |
| 580 | 589 |
| 581 class Printer(object): | 590 class Printer(object): |
| 582 """Printer with indentation support.""" | 591 """Printer with indentation support.""" |
| 583 | 592 |
| 584 def __init__(self): | 593 def __init__(self): |
| 585 self.indent = 0 | 594 self.indent = 0 |
| 586 | 595 |
| 587 def Indent(self): | 596 def Indent(self): |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 645 field_value = self.heap.reader.ReadUIntPtr(self.address + offset) | 654 field_value = self.heap.reader.ReadUIntPtr(self.address + offset) |
| 646 return self.heap.FindObjectOrSmi(field_value) | 655 return self.heap.FindObjectOrSmi(field_value) |
| 647 | 656 |
| 648 def SmiField(self, offset): | 657 def SmiField(self, offset): |
| 649 field_value = self.heap.reader.ReadUIntPtr(self.address + offset) | 658 field_value = self.heap.reader.ReadUIntPtr(self.address + offset) |
| 650 assert (field_value & 1) == 0 | 659 assert (field_value & 1) == 0 |
| 651 return field_value / 2 | 660 return field_value / 2 |
| 652 | 661 |
| 653 | 662 |
| 654 class Map(HeapObject): | 663 class Map(HeapObject): |
| 655 def InstanceTypeOffset(): | 664 def InstanceTypeOffset(self): |
| 656 return self.heap.PointerSize() + self.heap.IntSize() | 665 return self.heap.PointerSize() + self.heap.IntSize() |
| 657 | 666 |
| 658 def __init__(self, heap, map, address): | 667 def __init__(self, heap, map, address): |
| 659 HeapObject.__init__(self, heap, map, address) | 668 HeapObject.__init__(self, heap, map, address) |
| 660 self.instance_type = \ | 669 self.instance_type = \ |
| 661 heap.reader.ReadU8(self.address + self.InstanceTypeOffset()) | 670 heap.reader.ReadU8(self.address + self.InstanceTypeOffset()) |
| 662 | 671 |
| 663 | 672 |
| 664 class String(HeapObject): | 673 class String(HeapObject): |
| 665 def LengthOffset(self): | 674 def LengthOffset(self): |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 879 class Code(HeapObject): | 888 class Code(HeapObject): |
| 880 CODE_ALIGNMENT_MASK = (1 << 5) - 1 | 889 CODE_ALIGNMENT_MASK = (1 << 5) - 1 |
| 881 | 890 |
| 882 def InstructionSizeOffset(self): | 891 def InstructionSizeOffset(self): |
| 883 return self.heap.PointerSize() | 892 return self.heap.PointerSize() |
| 884 | 893 |
| 885 @staticmethod | 894 @staticmethod |
| 886 def HeaderSize(heap): | 895 def HeaderSize(heap): |
| 887 return (heap.PointerSize() + heap.IntSize() + \ | 896 return (heap.PointerSize() + heap.IntSize() + \ |
| 888 4 * heap.PointerSize() + 3 * heap.IntSize() + \ | 897 4 * heap.PointerSize() + 3 * heap.IntSize() + \ |
| 889 CODE_ALIGNMENT_MASK) & ~CODE_ALIGNMENT_MASK | 898 Code.CODE_ALIGNMENT_MASK) & ~Code.CODE_ALIGNMENT_MASK |
| 890 | 899 |
| 891 def __init__(self, heap, map, address): | 900 def __init__(self, heap, map, address): |
| 892 HeapObject.__init__(self, heap, map, address) | 901 HeapObject.__init__(self, heap, map, address) |
| 893 self.entry = self.address + Code.HeaderSize(heap) | 902 self.entry = self.address + Code.HeaderSize(heap) |
| 894 self.instruction_size = \ | 903 self.instruction_size = \ |
| 895 heap.reader.ReadU32(self.address + self.InstructionSizeOffset()) | 904 heap.reader.ReadU32(self.address + self.InstructionSizeOffset()) |
| 896 | 905 |
| 897 def Print(self, p): | 906 def Print(self, p): |
| 898 lines = self.heap.reader.GetDisasmLines(self.entry, self.instruction_size) | 907 lines = self.heap.reader.GetDisasmLines(self.entry, self.instruction_size) |
| 899 p.Print("Code(%s) {" % self.heap.reader.FormatIntPtr(self.address)) | 908 p.Print("Code(%s) {" % self.heap.reader.FormatIntPtr(self.address)) |
| 900 p.Indent() | 909 p.Indent() |
| 901 p.Print("instruction_size: %d" % self.instruction_size) | 910 p.Print("instruction_size: %d" % self.instruction_size) |
| 902 p.PrintLines(self._FormatLine(line) for line in lines) | 911 p.PrintLines(self._FormatLine(line) for line in lines) |
| 903 p.Dedent() | 912 p.Dedent() |
| 904 p.Print("}") | 913 p.Print("}") |
| 905 | 914 |
| 906 def _FormatLine(self, line): | 915 def _FormatLine(self, line): |
| 907 return FormatDisasmLine(self.entry, self.heap, line) | 916 return FormatDisasmLine(self.entry, self.heap, line) |
| 908 | 917 |
| 909 | 918 |
| 910 class V8Heap(object): | 919 class V8Heap(object): |
| 911 CLASS_MAP = { | 920 CLASS_MAP = { |
| 912 "SYMBOL_TYPE": SeqString, | 921 "SYMBOL_TYPE": SeqString, |
| 913 "ASCII_SYMBOL_TYPE": SeqString, | 922 "ASCII_SYMBOL_TYPE": SeqString, |
| 914 "CONS_SYMBOL_TYPE": ConsString, | 923 "CONS_SYMBOL_TYPE": ConsString, |
| 915 "CONS_ASCII_SYMBOL_TYPE": ConsString, | 924 "CONS_ASCII_SYMBOL_TYPE": ConsString, |
| 916 "EXTERNAL_SYMBOL_TYPE": ExternalString, | 925 "EXTERNAL_SYMBOL_TYPE": ExternalString, |
| 917 "EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE": ExternalString, | 926 "EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE": ExternalString, |
| 918 "EXTERNAL_ASCII_SYMBOL_TYPE": ExternalString, | 927 "EXTERNAL_ASCII_SYMBOL_TYPE": ExternalString, |
| 928 "SHORT_EXTERNAL_SYMBOL_TYPE": ExternalString, | |
| 929 "SHORT_EXTERNAL_SYMBOL_WITH_ASCII_DATA_TYPE": ExternalString, | |
| 930 "SHORT_EXTERNAL_ASCII_SYMBOL_TYPE": ExternalString, | |
| 919 "STRING_TYPE": SeqString, | 931 "STRING_TYPE": SeqString, |
| 920 "ASCII_STRING_TYPE": SeqString, | 932 "ASCII_STRING_TYPE": SeqString, |
| 921 "CONS_STRING_TYPE": ConsString, | 933 "CONS_STRING_TYPE": ConsString, |
| 922 "CONS_ASCII_STRING_TYPE": ConsString, | 934 "CONS_ASCII_STRING_TYPE": ConsString, |
| 923 "EXTERNAL_STRING_TYPE": ExternalString, | 935 "EXTERNAL_STRING_TYPE": ExternalString, |
| 924 "EXTERNAL_STRING_WITH_ASCII_DATA_TYPE": ExternalString, | 936 "EXTERNAL_STRING_WITH_ASCII_DATA_TYPE": ExternalString, |
| 925 "EXTERNAL_ASCII_STRING_TYPE": ExternalString, | 937 "EXTERNAL_ASCII_STRING_TYPE": ExternalString, |
| 926 | 938 |
| 927 "MAP_TYPE": Map, | 939 "MAP_TYPE": Map, |
| 928 "ODDBALL_TYPE": Oddball, | 940 "ODDBALL_TYPE": Oddball, |
| 929 "FIXED_ARRAY_TYPE": FixedArray, | 941 "FIXED_ARRAY_TYPE": FixedArray, |
| 930 "JS_FUNCTION_TYPE": JSFunction, | 942 "JS_FUNCTION_TYPE": JSFunction, |
| 931 "SHARED_FUNCTION_INFO_TYPE": SharedFunctionInfo, | 943 "SHARED_FUNCTION_INFO_TYPE": SharedFunctionInfo, |
| 932 "SCRIPT_TYPE": Script, | 944 "SCRIPT_TYPE": Script, |
| 933 "CODE_TYPE": Code | 945 "CODE_TYPE": Code |
| 934 } | 946 } |
| 935 | 947 |
| 936 def __init__(self, reader, stack_map): | 948 def __init__(self, reader, stack_map): |
| 937 self.reader = reader | 949 self.reader = reader |
| 938 self.stack_map = stack_map | 950 self.stack_map = stack_map |
| 939 self.objects = {} | 951 self.objects = {} |
| 940 | 952 |
| 941 def FindObjectOrSmi(self, tagged_address): | 953 def FindObjectOrSmi(self, tagged_address): |
| 942 if (tagged_address & 1) == 0: return tagged_address / 2 | 954 if (tagged_address & 1) == 0: return tagged_address / 2 |
| 943 return self.FindObject(tagged_address) | 955 return self.FindObject(tagged_address) |
| 944 | 956 |
| 957 def FindMap(self, tagged_address): | |
|
Vyacheslav Egorov (Chromium)
2012/01/04 08:45:35
One trick that might help to guess whether smth is
Michael Starzinger
2012/01/05 14:26:30
Done. I also added the alignment check for other h
| |
| 958 if (tagged_address & 1) != 1: return None | |
| 959 address = tagged_address - 1 | |
| 960 if not self.reader.IsValidAddress(address): return None | |
| 961 object = Map(self, None, address) | |
| 962 return object | |
| 963 | |
| 945 def FindObject(self, tagged_address): | 964 def FindObject(self, tagged_address): |
| 946 if tagged_address in self.objects: | 965 if tagged_address in self.objects: |
| 947 return self.objects[tagged_address] | 966 return self.objects[tagged_address] |
| 948 if (tagged_address & 1) != 1: return None | 967 if (tagged_address & 1) != 1: return None |
| 949 address = tagged_address - 1 | 968 address = tagged_address - 1 |
| 950 if not self.reader.IsValidAddress(address): return None | 969 if not self.reader.IsValidAddress(address): return None |
| 951 map_tagged_address = self.reader.ReadUIntPtr(address) | 970 map_tagged_address = self.reader.ReadUIntPtr(address) |
| 952 if tagged_address == map_tagged_address: | 971 if tagged_address == map_tagged_address: |
| 953 # Meta map? | 972 # Meta map? |
| 954 meta_map = Map(self, None, address) | 973 meta_map = Map(self, None, address) |
| 955 instance_type_name = INSTANCE_TYPES.get(meta_map.instance_type) | 974 instance_type_name = INSTANCE_TYPES.get(meta_map.instance_type) |
| 956 if instance_type_name != "MAP_TYPE": return None | 975 if instance_type_name != "MAP_TYPE": return None |
| 957 meta_map.map = meta_map | 976 meta_map.map = meta_map |
| 958 object = meta_map | 977 object = meta_map |
| 959 else: | 978 else: |
| 960 map = self.FindObject(map_tagged_address) | 979 map = self.FindMap(map_tagged_address) |
| 961 if map is None: return None | 980 if map is None: return None |
| 962 instance_type_name = INSTANCE_TYPES.get(map.instance_type) | 981 instance_type_name = INSTANCE_TYPES.get(map.instance_type) |
| 963 if instance_type_name is None: return None | 982 if instance_type_name is None: return None |
| 964 cls = V8Heap.CLASS_MAP.get(instance_type_name, HeapObject) | 983 cls = V8Heap.CLASS_MAP.get(instance_type_name, HeapObject) |
| 965 object = cls(self, map, address) | 984 object = cls(self, map, address) |
| 966 self.objects[tagged_address] = object | 985 self.objects[tagged_address] = object |
| 967 return object | 986 return object |
| 968 | 987 |
| 988 def IntSize(self): | |
| 989 return 4 | |
| 990 | |
| 969 def PointerSize(self): | 991 def PointerSize(self): |
| 970 return self.reader.PointerSize() | 992 return self.reader.PointerSize() |
| 971 | 993 |
| 972 | 994 |
| 973 | 995 |
| 974 EIP_PROXIMITY = 64 | 996 EIP_PROXIMITY = 64 |
| 975 | 997 |
| 976 CONTEXT_FOR_ARCH = { | 998 CONTEXT_FOR_ARCH = { |
| 977 MD_CPU_ARCHITECTURE_AMD64: | 999 MD_CPU_ARCHITECTURE_AMD64: |
| 978 ['rax', 'rbx', 'rcx', 'rdx', 'rdi', 'rsi', 'rbp', 'rsp', 'rip'], | 1000 ['rax', 'rbx', 'rcx', 'rdx', 'rdi', 'rsi', 'rbp', 'rsp', 'rip'], |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1027 reader.Dispose() | 1049 reader.Dispose() |
| 1028 | 1050 |
| 1029 | 1051 |
| 1030 if __name__ == "__main__": | 1052 if __name__ == "__main__": |
| 1031 parser = optparse.OptionParser(USAGE) | 1053 parser = optparse.OptionParser(USAGE) |
| 1032 options, args = parser.parse_args() | 1054 options, args = parser.parse_args() |
| 1033 if len(args) != 1: | 1055 if len(args) != 1: |
| 1034 parser.print_help() | 1056 parser.print_help() |
| 1035 sys.exit(1) | 1057 sys.exit(1) |
| 1036 AnalyzeMinidump(options, args[0]) | 1058 AnalyzeMinidump(options, args[0]) |
| OLD | NEW |