├── .gitignore ├── ChangeLog ├── LICENSE ├── README.md ├── dumpanalyze ├── __init__.py ├── __main__.py ├── abortreason.py ├── dumpparser.py ├── trace.py ├── tracebush.py ├── traceforest.py └── view │ ├── __init__.py │ ├── abortreasonsdetails.py │ ├── abortreasonslist.py │ ├── tracebush.py │ └── traces.py ├── requirements-install.txt ├── requirements-setup.txt ├── requirements-tests.txt ├── run-tests.py ├── setup.cfg ├── setup.py └── tests ├── dump-files ├── test_cli.txt └── test_objects.txt ├── test_cli.py └── test_objects.py /.gitignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | 3 | README.html 4 | build 5 | dist 6 | dumpanalyze.egg-info 7 | venv 8 | .eggs 9 | .tox 10 | .idea 11 | *.pyc 12 | .DS_Store 13 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | version 0.9.1 2 | * Remove dependency on minor version of Python 3 | * Fixed regular expression literals 4 | * Fixed parsing of trace flushes 5 | * Bumped copyright year 6 | 7 | version 0.9.0 8 | * First public release 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2017-2019 IPONWEB Ltd. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | dumpanalyze 2 | =========== 3 | 4 | Introduction 5 | ------------ 6 | 7 | `dumpanalyze` is a mini-framework equipped with a CLI for processing LuaJIT's 8 | plain text JIT compiler dumps. `dumpanalyze` can be used with any other software 9 | as well, as long the dump format remains the same. 10 | 11 | To get a grasp of what a *dump* is, run following command in your terminal 12 | (assuming you already have LuaJIT installed): 13 | 14 | ``` 15 | luajit -jdump=T -e 'local s = 0; for i = 1, 100 do s = s + i end; print(s)' 16 | ``` 17 | 18 | You will see some plain text output which is generated in run-time as long as 19 | the JIT compiler records a trace, assembles its machine code, etc. This info 20 | can now be used for analysing/improving/troubleshooting the compiler. 21 | 22 | However, if you try to run the dump with a large application under heavy load, 23 | you may face certain difficulties trying to interpret the output. First, 24 | it may be really **huge**. Second, it may contain various artefacts (compiled 25 | traces, aborted traces, exit state records) melted into a single data stream. 26 | Third, if your application is large enough, the dump will contain information 27 | about thousands of traces connected with non-trivial parent/child relations. 28 | 29 | `dumpanalyze` was created to (at least partly) address these challenges. 30 | 31 | Architecture 32 | ------------ 33 | 34 | The core of the `dumpanalyze` is a *parser of dumps* which reads its input 35 | line by line converting it into a simple object model (compiled traces, 36 | trace bushes, abort reasons, etc.). 37 | 38 | After parsing is done, resulting objects can be grouped and rendered 39 | with a help of various *views*. 40 | 41 | Everything is glued together with a CLI although can be used a Python module. 42 | 43 | Available Views 44 | --------------- 45 | 46 | * Aggregated list of compiled traces (`csv`) 47 | * List of trace bushes (`txt`, `png`) 48 | * Aggregated list of abort reasons (`csv`) 49 | * List of abort reasons grouped by file:line (`txt`) 50 | 51 | Installation 52 | ------------ 53 | 54 | For local installation, simply clone this repository. 55 | 56 | If you need a system-wide installation, please run following command from 57 | the repository root after cloning it: 58 | 59 | ``` 60 | sudo pip install . 61 | ``` 62 | 63 | This will install all modules and create a CLI wrapper named `dumpanalyze`. 64 | 65 | Usage 66 | ----- 67 | 68 | In case of local installation: 69 | 70 | ``` 71 | python3 -m dumpanalyze --dump /path/to/dump.txt --out-dir /tmp/dump-parsed 72 | ``` 73 | 74 | ...or... 75 | 76 | ``` 77 | PYTHONPATH=. python3 dumpanalyze --dump /path/to/dump.txt --out-dir /tmp/dump-parsed 78 | ``` 79 | 80 | In case of system-wide installation: 81 | 82 | ``` 83 | dumpanalyze --dump /path/to/dump.txt --out-dir /tmp/dump-parsed 84 | ``` 85 | 86 | Running tests 87 | ------------- 88 | 89 | Run the following from the repository root: 90 | 91 | ``` 92 | python3 run-tests.py 93 | ``` 94 | 95 | Benchmarks 96 | ---------- 97 | 98 | * Data: a dump obtained from a production system (~800Mb of plain text data) 99 | * Machine: Intel(R) Core(TM) i5-4570 CPU @ 3.20GHz with 8Gb RAM 100 | * Time (in user mode): 122 seconds 101 | * Peak RAM usage: 900Mb 102 | 103 | Links 104 | ----- 105 | 106 | * [LuaJIT dump module](https://github.com/LuaJIT/LuaJIT/blob/master/src/jit/dump.lua) 107 | * [Loom: replacement / enhancement of the -jdump option](https://github.com/cloudflare/loom) 108 | * [luajit-web-inspector](https://github.com/mejedi/luajit-web-inspector) 109 | * [Studio: Yet another debugging environment from RaptorJIT developers](https://github.com/studio/studio) 110 | 111 | Caveats 112 | ------- 113 | 114 | * This software was tested with Python 3.5 and 3.6. 115 | * The parser supports **only plain text dumps** at the moment. 116 | 117 | Copyright and License 118 | --------------------- 119 | 120 | Copyright 2017-2019 IPONWEB Ltd. 121 | 122 | This software is licensed under the terms of the MIT license. 123 | -------------------------------------------------------------------------------- /dumpanalyze/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = '0.9.1' 2 | -------------------------------------------------------------------------------- /dumpanalyze/__main__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Command-line interface for parsing dumps and producing views. 4 | # This module is a part of the toolkit for processing LuaJIT plain text dumps. 5 | # 6 | # Copyright 2017-2019 IPONWEB Ltd. 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | # IN THE SOFTWARE. 25 | # 26 | 27 | import sys 28 | import os 29 | import errno 30 | import argparse 31 | 32 | from dumpanalyze.dumpparser import DumpParser 33 | from dumpanalyze.traceforest import TraceForest 34 | 35 | from dumpanalyze.view.traces import ViewTraces 36 | from dumpanalyze.view.tracebush import ViewTraceBush 37 | from dumpanalyze.view.abortreasonslist import ViewAbortReasonsList 38 | from dumpanalyze.view.abortreasonsdetails import ViewAbortReasonsDetails 39 | 40 | if sys.version_info[0] < 3: 41 | sys.exit("This toolkit requires Python 3.0+") 42 | 43 | 44 | def parse_command_line(argv): 45 | argparser = argparse.ArgumentParser() 46 | argparser.add_argument( 47 | "--dump", 48 | type=str, 49 | help="Path to the dump file", 50 | ) 51 | argparser.add_argument( 52 | "--out-dir", 53 | type=str, 54 | help="Path to output directory", 55 | ) 56 | args = argparser.parse_args(argv[1:]) 57 | return args 58 | 59 | 60 | def get_output_directory(args): 61 | out_dir = args.out_dir 62 | 63 | if out_dir is None: 64 | out_dir = os.path.join( 65 | os.path.dirname(args.dump), 66 | "{}-parsed".format(os.path.basename(args.dump)), 67 | ) 68 | 69 | if os.path.isdir(out_dir): 70 | if not os.access(out_dir, os.W_OK): 71 | sys.exit("Bad output directory '{}'".format(out_dir)) 72 | else: 73 | return out_dir 74 | 75 | try: 76 | os.makedirs(out_dir, exist_ok=True) 77 | except OSError as e: 78 | if e.errno == errno.EACCES: 79 | sys.exit( 80 | "Permission denied to create output directory '{}'" 81 | .format(out_dir) 82 | ) 83 | else: 84 | raise 85 | 86 | return out_dir 87 | 88 | 89 | def main(argv=None): 90 | argv = argv or sys.argv 91 | args = parse_command_line(argv) 92 | 93 | if args.dump is None: 94 | sys.exit("Dump file name is not specified") 95 | elif not(os.path.isfile(args.dump) and os.access(args.dump, os.R_OK)): 96 | sys.exit("Bad dump file name '{}'".format(args.dump)) 97 | 98 | out_dir = get_output_directory(args) 99 | 100 | print("Initializing") 101 | 102 | # Setup parser: 103 | parser = DumpParser(args.dump) 104 | 105 | # Setup all available views: 106 | v_traces = ViewTraces("csv") 107 | v_ar_list = ViewAbortReasonsList("csv") 108 | v_ar_details = ViewAbortReasonsDetails("txt") 109 | v_bush_txt = ViewTraceBush("txt") 110 | v_bush_png = ViewTraceBush("png") 111 | 112 | generation = 1 113 | while True: 114 | print("Generation {}: parsing dump".format(generation)) 115 | 116 | status = parser.parse() 117 | traces = parser.traces 118 | abort_reasons = parser.abort_reasons 119 | 120 | print("Read {} compiled traces".format(len(traces))) 121 | 122 | forest = TraceForest(traces) 123 | bushes = forest.bushes 124 | 125 | print("Read {} trace bushes".format(len(bushes))) 126 | 127 | print("Rendering aggregated list of compiled traces") 128 | v_traces.render(os.path.join( 129 | out_dir, "gen-{}-traces.csv".format(generation) 130 | ), traces) 131 | 132 | print("Rendering aggregated list of abort reasons") 133 | v_ar_list.render(os.path.join( 134 | out_dir, "gen-{}-abort-reasons.csv".format(generation) 135 | ), abort_reasons) 136 | 137 | print("Rendering detailed list of abort reasons") 138 | v_ar_details.render(os.path.join( 139 | out_dir, "gen-{}-abort-reasons.txt".format(generation) 140 | ), abort_reasons) 141 | 142 | print("Rendering views of bushes") 143 | for root_id, bush in bushes.items(): 144 | fname = "gen-{}-bush-{}".format(generation, str(root_id)) 145 | v_bush_txt.render(os.path.join(out_dir, fname + ".txt"), bush) 146 | v_bush_png.render(os.path.join(out_dir, fname), bush) 147 | 148 | if status == parser.PARSED_DUMP: 149 | break 150 | 151 | generation += 1 152 | 153 | print("Done") 154 | 155 | 156 | if __name__ == "__main__": 157 | main() 158 | -------------------------------------------------------------------------------- /dumpanalyze/abortreason.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Compilation abort reason. 4 | # This module is a part of the toolkit for processing LuaJIT plain text dumps. 5 | # 6 | # Copyright 2017-2019 IPONWEB Ltd. 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | # IN THE SOFTWARE. 25 | # 26 | 27 | import re 28 | 29 | 30 | class AbortReason: 31 | re_abort_reason = re.compile(r" abort (.+?):(\d+) -- (.+)$") 32 | 33 | def __init__(self, line): 34 | match = self.re_abort_reason.search(line) 35 | 36 | self._file = match.group(1) 37 | self._line = int(match.group(2)) 38 | self._reason = match.group(3) 39 | 40 | @property 41 | def file(self): 42 | return self._file 43 | 44 | @property 45 | def line(self): 46 | return self._line 47 | 48 | @property 49 | def reason(self): 50 | return self._reason 51 | -------------------------------------------------------------------------------- /dumpanalyze/dumpparser.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Line-by-line parser of a LuaJIT plain text dump. 4 | # This module is a part of the toolkit for processing LuaJIT plain text dumps. 5 | # 6 | # Copyright 2017-2019 IPONWEB Ltd. 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | # IN THE SOFTWARE. 25 | # 26 | 27 | import sys 28 | import re 29 | 30 | from dumpanalyze.trace import Trace 31 | from dumpanalyze.abortreason import AbortReason 32 | 33 | 34 | class DumpParser: 35 | # Internal parser states while parsing multiple states 36 | # within a single trace generation: 37 | PARSER_INIT = "" 38 | PARSER_START = "start" 39 | PARSER_IR = "IR" 40 | PARSER_MCODE = "mcode" 41 | PARSER_STOP = "stop" 42 | PARSER_EXIT = "exit" 43 | PARSER_ABORT = "abort" 44 | PARSER_FLUSH = "flush" 45 | 46 | # External parser states: 47 | PARSED_GENERATION = 1 # Parsed generation, but there are more in the dump 48 | PARSED_DUMP = 2 # Parsed generation and reached the end of the dump 49 | 50 | ASSERTABLE_STATES = [ 51 | PARSER_IR, PARSER_MCODE, PARSER_STOP, PARSER_ABORT 52 | ] 53 | 54 | # Regular expression to detect a new logical portion of 55 | # trace-related data or a global trace flush: 56 | re_trace_header = re.compile(r"^---- TRACE (?:(\d+ )?(\S+))") 57 | 58 | def __init__(self, dump): 59 | # Errors are ignored because non-UTF-8 string values 60 | # may appear in the dumps. 61 | self._dump_f = open(dump, "r", errors="ignore") 62 | 63 | self._init_parser() 64 | 65 | def __del__(self): 66 | self._dump_f.close() 67 | 68 | @property 69 | def traces(self): 70 | return self._traces 71 | 72 | @property 73 | def abort_reasons(self): 74 | return self._abort_reasons 75 | 76 | def parse(self): 77 | self._init_parser() 78 | 79 | for line in self._dump_f: 80 | self._line += 1 81 | self._parse_line(line) 82 | if self._state == self.PARSER_FLUSH: 83 | return self.PARSED_GENERATION 84 | 85 | return self.PARSED_DUMP 86 | 87 | def _init_parser(self): 88 | self._line = 0 89 | self._state = self.PARSER_INIT 90 | self._trace = None 91 | self._traces = [] 92 | self._abort_reasons = [] 93 | 94 | def _parse_line(self, line): 95 | if line == "\n": 96 | return 97 | 98 | match = self.re_trace_header.match(line) 99 | if match: 100 | trace_id = int(match.group(1) or 0) 101 | self._parse_header_line(line, match.group(2), trace_id) 102 | else: 103 | self._trace.process_data(self._state, line) 104 | 105 | def _parse_header_line(self, line, state, trace_id): 106 | self._state = state 107 | 108 | if state in self.ASSERTABLE_STATES and trace_id != self._trace.id: 109 | sys.exit( 110 | "Line {}, in state={}: Expected trace ID {}, got {}" 111 | .format(self._line, self._state, self._trace.id, trace_id) 112 | ) 113 | 114 | if state == self.PARSER_ABORT: 115 | self._abort_reasons.append(AbortReason(line)) 116 | return 117 | 118 | if state == self.PARSER_START: 119 | self._trace = Trace(trace_id) 120 | 121 | self._trace.process_header(state, line) 122 | 123 | if state == self.PARSER_STOP: 124 | self._traces.append(self._trace) 125 | -------------------------------------------------------------------------------- /dumpanalyze/trace.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # A compiled trace. 4 | # This module is a part of the toolkit for processing LuaJIT plain text dumps. 5 | # 6 | # Copyright 2017-2019 IPONWEB Ltd. 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | # IN THE SOFTWARE. 25 | # 26 | 27 | import collections 28 | import re 29 | 30 | 31 | class Trace: 32 | # Regular expressions to extract data from trace header lines: 33 | re_header_start = re.compile(r" start (?:((\d+)/(\d+)) )?([^:]+):(\d+)$") 34 | re_header_mcode = re.compile(r" mcode (\d+)$") 35 | re_header_stop = re.compile(r" stop -> (.+)$") 36 | 37 | # Regular expressions to extract data from trace data lines: 38 | re_data_mcode = re.compile(r"->(\d+)") 39 | 40 | def __init__(self, trace_id): 41 | self._id = trace_id 42 | self._parent_id = 0 43 | self._parent_side = 0 44 | self._parent = "" 45 | self._file = "" 46 | self._line = 0 47 | self._link_type = "" 48 | self._side_exits = collections.defaultdict(lambda: 0) 49 | self._num_ir = 0 50 | self._num_sn = 0 51 | self._size_mcode = 0 52 | self._bc = [] # List of bytecode dump 53 | self._ir = [] # List of IR dump 54 | self._mc = [] # List of machine code dump 55 | 56 | @property 57 | def id(self): 58 | return self._id 59 | 60 | @property 61 | def parent_id(self): 62 | return self._parent_id 63 | 64 | @property 65 | def parent_side(self): 66 | return self._parent_side 67 | 68 | @property 69 | def parent(self): 70 | return self._parent 71 | 72 | @property 73 | def is_root(self): 74 | return self._parent_id == 0 75 | 76 | @property 77 | def file(self): 78 | return self._file 79 | 80 | @property 81 | def line(self): 82 | return self._line 83 | 84 | @property 85 | def link_type(self): 86 | return self._link_type 87 | 88 | @property 89 | def side_exits(self): 90 | return self._side_exits 91 | 92 | @property 93 | def num_bc(self): 94 | return len(self._bc) 95 | 96 | @property 97 | def num_ir(self): 98 | return self._num_ir 99 | 100 | @property 101 | def num_sn(self): 102 | return self._num_sn 103 | 104 | @property 105 | def size_mcode(self): 106 | return self._size_mcode 107 | 108 | @property 109 | def bc(self): 110 | return self._bc 111 | 112 | @property 113 | def ir(self): 114 | return self._ir 115 | 116 | @property 117 | def mc(self): 118 | return self._mc 119 | 120 | # Process `line` which is logically a header signalling about entering 121 | # a new `state` while reading the stream of data. 122 | def process_header(self, state, line): 123 | action = "_process_header_" + state 124 | return getattr(self, action)(line) 125 | 126 | # Process a `line` of data while the parser is in the given `state`. 127 | def process_data(self, state, line): 128 | action = "_process_data_" + state 129 | return getattr(self, action)(line) 130 | 131 | # 132 | # Per-state terminal handlers for header lines 133 | # 134 | 135 | def _process_header_start(self, line): 136 | match = self.re_header_start.search(line) 137 | 138 | if match.group(1) is not None: 139 | self._parent = match.group(1) 140 | 141 | if match.group(2) is not None: 142 | self._parent_id = int(match.group(2)) 143 | 144 | if match.group(3) is not None: 145 | self._parent_side = int(match.group(3)) 146 | 147 | self._file = match.group(4) 148 | self._line = int(match.group(5)) 149 | 150 | def _process_header_IR(self, line): 151 | pass 152 | 153 | def _process_header_mcode(self, line): 154 | match = self.re_header_mcode.search(line) 155 | self._size_mcode = int(match.group(1)) 156 | 157 | def _process_header_stop(self, line): 158 | match = self.re_header_stop.search(line) 159 | self._link_type = match.group(1) 160 | 161 | def _process_header_exit(self, line): 162 | pass 163 | 164 | def _process_header_abort(self, line): 165 | pass 166 | 167 | def _process_header_flush(self, line): 168 | pass 169 | 170 | # 171 | # Per-state terminal handlers for data lines 172 | # 173 | 174 | def _process_data_start(self, line): 175 | self._bc.append(line) 176 | 177 | def _process_data_IR(self, line): 178 | self._ir.append(line) 179 | if "SNAP" in line: 180 | self._num_sn += 1 181 | else: 182 | self._num_ir += 1 183 | 184 | def _process_data_mcode(self, line): 185 | self._mc.append(line) 186 | match = self.re_data_mcode.search(line) 187 | 188 | if not match or match.group(1) is None: 189 | return 190 | 191 | # We record only side exits actually preserved in mcode 192 | self._side_exits[int(match.group(1))] += 1 193 | 194 | def _process_data_stop(self, line): 195 | pass 196 | 197 | def _process_data_exit(self, line): 198 | pass 199 | 200 | def _process_data_abort(self, line): 201 | pass 202 | 203 | def _process_data_flush(self, line): 204 | pass 205 | -------------------------------------------------------------------------------- /dumpanalyze/tracebush.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # A bush of compiled traces. 4 | # This module is a part of the toolkit for processing LuaJIT plain text dumps. 5 | # 6 | # Copyright 2017-2019 IPONWEB Ltd. 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | # IN THE SOFTWARE. 25 | # 26 | 27 | 28 | class TraceBush: 29 | 30 | def __init__(self, root_trace): 31 | self._root_id = root_trace.id 32 | self._traces = [root_trace] 33 | 34 | @property 35 | def root_id(self): 36 | return self._root_id 37 | 38 | @property 39 | def size(self): 40 | return len(self._traces) 41 | 42 | @property 43 | def traces(self): 44 | return self._traces 45 | 46 | def append(self, trace): 47 | self._traces.append(trace) 48 | -------------------------------------------------------------------------------- /dumpanalyze/traceforest.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # A forest of trace bushes. 4 | # This module is a part of the toolkit for processing LuaJIT plain text dumps. 5 | # 6 | # Copyright 2017-2019 IPONWEB Ltd. 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | # IN THE SOFTWARE. 25 | # 26 | 27 | from dumpanalyze.tracebush import TraceBush 28 | 29 | 30 | class TraceForest: 31 | 32 | def __init__(self, traces): 33 | forest = {} 34 | roots = {} 35 | 36 | for trace in traces: 37 | root_id = None 38 | if trace.is_root: 39 | root_id = trace.id 40 | forest[root_id] = TraceBush(trace) 41 | else: 42 | root_id = roots[trace.parent_id] 43 | forest[root_id].append(trace) 44 | roots[trace.id] = root_id 45 | 46 | self._bushes = forest 47 | 48 | @property 49 | def bushes(self): 50 | return self._bushes 51 | -------------------------------------------------------------------------------- /dumpanalyze/view/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luavela/dumpanalyze/eb09386c59fc8263d583bf53d31f811e7b8171ea/dumpanalyze/view/__init__.py -------------------------------------------------------------------------------- /dumpanalyze/view/abortreasonsdetails.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Abort reasons detailed view. 4 | # This module is a part of the toolkit for processing LuaJIT plain text dumps. 5 | # 6 | # Copyright 2017-2019 IPONWEB Ltd. 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | # IN THE SOFTWARE. 25 | # 26 | 27 | import collections 28 | 29 | 30 | class ViewAbortReasonsDetails: 31 | 32 | def __init__(self, fmt): 33 | self._fmt = fmt 34 | 35 | def render(self, fname, abort_reasons): 36 | if self._fmt == "txt": 37 | self._render_txt(fname, abort_reasons) 38 | else: 39 | raise Exception("Unknown format") 40 | 41 | def _render_txt(self, fname, abort_reasons): 42 | files = collections.defaultdict( 43 | lambda: collections.defaultdict( 44 | lambda: collections.defaultdict( 45 | lambda: 0 46 | ) 47 | ) 48 | ) 49 | 50 | for ar in abort_reasons: 51 | files[ar.file][ar.line][ar.reason] += 1 52 | 53 | with open(fname, 'w', newline='') as out: 54 | names = sorted(files.keys()) 55 | for name in names: 56 | out.write("{}:\n".format(name)) 57 | lines = sorted(files[name].keys()) 58 | for line in lines: 59 | out.write("\tline {}:\n".format(line)) 60 | reasons = sorted(files[name][line].keys()) 61 | for reason in reasons: 62 | out.write("\t\t{}: {}\n".format( 63 | reason, files[name][line][reason] 64 | )) 65 | -------------------------------------------------------------------------------- /dumpanalyze/view/abortreasonslist.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Abort reasons aggregated view. 4 | # This module is a part of the toolkit for processing LuaJIT plain text dumps. 5 | # 6 | # Copyright 2017-2019 IPONWEB Ltd. 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | # IN THE SOFTWARE. 25 | # 26 | 27 | import collections 28 | import csv 29 | 30 | 31 | class ViewAbortReasonsList: 32 | 33 | CSV_HEADER = ["REASON", "COUNT"] 34 | 35 | def __init__(self, fmt): 36 | self._fmt = fmt 37 | 38 | def render(self, fname, abort_reasons): 39 | if self._fmt == "csv": 40 | self._render_csv(fname, abort_reasons) 41 | else: 42 | raise Exception("Unknown format") 43 | 44 | def _render_csv(self, fname, abort_reasons): 45 | reasons_map = collections.defaultdict(lambda: 0) 46 | 47 | for ar in abort_reasons: 48 | reasons_map[ar.reason] += 1 49 | 50 | reasons_sorted = sorted( 51 | reasons_map.items(), key=lambda x: x[1], reverse=True 52 | ) 53 | 54 | with open(fname, "w", newline="") as out: 55 | writer = csv.writer(out, delimiter=",", quoting=csv.QUOTE_MINIMAL) 56 | writer.writerow(self.CSV_HEADER) 57 | for reason, count in reasons_sorted: 58 | writer.writerow([reason, count]) 59 | -------------------------------------------------------------------------------- /dumpanalyze/view/tracebush.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Trace bush view. 4 | # This module is a part of the toolkit for processing LuaJIT plain text dumps. 5 | # 6 | # Copyright 2017-2019 IPONWEB Ltd. 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | # IN THE SOFTWARE. 25 | # 26 | 27 | import graphviz 28 | 29 | 30 | class ViewTraceBush: 31 | 32 | MARKED_TRACE_COLOR = "crimson" 33 | 34 | def __init__(self, fmt): 35 | self._fmt = fmt 36 | 37 | def render(self, fname, bush): 38 | if self._fmt == "txt": 39 | self._render_txt(fname, bush) 40 | elif self._fmt == "png": 41 | self._render_png(fname, bush) 42 | else: 43 | raise Exception("Unknown format") 44 | 45 | def _render_txt(self, fname, bush): 46 | with open(fname, "w") as out: 47 | for trace in bush.traces: 48 | self._print_trace(out, trace) 49 | 50 | def _render_png(self, fname, bush): 51 | graph = graphviz.Digraph(format="png") 52 | for trace in bush.traces: 53 | self._add_to_graph(graph, bush, trace) 54 | graph.render(filename=fname, cleanup=True) 55 | 56 | def _print_trace(self, out, trace): 57 | padding = " " if trace.parent else "" 58 | out.write("---- TRACE {} start {}{}{}:{}\n".format( 59 | trace.id, 60 | trace.parent, 61 | padding, 62 | trace.file, 63 | trace.line 64 | )) 65 | out.write("".join(trace.bc)) 66 | out.write("---- TRACE {} IR\n".format(trace.id)) 67 | out.write("".join(trace.ir)) 68 | out.write("---- TRACE {} mcode {}\n".format( 69 | trace.id, 70 | trace.size_mcode 71 | )) 72 | out.write("".join(trace.mc)) 73 | out.write("---- TRACE {} stop -> {}\n".format( 74 | trace.id, 75 | trace.link_type 76 | )) 77 | out.write("\n") 78 | 79 | # Add a trace (either a root one or a side-trace) to the graph. 80 | def _add_to_graph(self, graph, bush, trace): 81 | 82 | # 83 | # Add the "trace entry node" (along with a link to the parent for 84 | # side traces) 85 | # 86 | 87 | node_start = "START " + str(trace.id) 88 | self._add_boundary_node(graph, node_start, trace.is_root) 89 | 90 | # In case of side traces, highlight parent's compiled side-exit: 91 | if not trace.is_root: 92 | graph.edge(trace.parent, node_start, style="bold") 93 | 94 | node_last = self._add_trace_body(graph, trace, node_start) 95 | 96 | # 97 | # Add the "trace exit node" with link information 98 | # 99 | 100 | link_type = trace.link_type 101 | node_end = "END " + str(trace.id) + " " 102 | if link_type == "interpreter": 103 | # A stub trace: The only thing it does 104 | # is an immediate switch to interpreter 105 | node_end += "enforce VM" 106 | elif link_type == "return": 107 | # Normal return to interpreter 108 | node_end += "return to VM" 109 | elif link_type == "loop": 110 | # Looping trace 111 | node_end += "loop" 112 | elif link_type.isnumeric(): 113 | # Link to another root trace 114 | node_end += "goto " + link_type 115 | else: 116 | # Don't know how to render the rest properly 117 | # will be fixed on demand 118 | node_end += link_type 119 | 120 | self._add_boundary_node(graph, node_end, trace.is_root) 121 | self._add_implicit_cf_edge(graph, node_last, node_end, trace.is_root) 122 | 123 | node_loop = None 124 | if link_type == "loop": 125 | node_loop = node_start 126 | elif link_type.isnumeric() and int(link_type) == bush.root_id: 127 | # If current trace links to current *root* trace, add a 128 | # corresponding 129 | # edge. Otherwise the link will point to some other bush 130 | # outside the graph. 131 | node_loop = "START " + str(bush.root_id) 132 | 133 | if node_loop is not None: 134 | graph.edge(node_end, node_loop, style="bold") 135 | 136 | # Add the body of the trace (exit 0 --> exit 1 --> ... --> exit N). 137 | def _add_trace_body(self, graph, trace, node_start): 138 | side_exits = sorted(trace.side_exits.keys()) 139 | node_prev = node_start 140 | 141 | for side_exit in side_exits: 142 | node_side = str(trace.id) + "/" + str(side_exit) 143 | self._add_implicit_cf_edge( 144 | graph, node_prev, node_side, trace.is_root 145 | ) 146 | if trace.is_root: 147 | graph.node( 148 | node_side, 149 | style="bold", 150 | color=self.MARKED_TRACE_COLOR 151 | ) 152 | node_prev = node_side 153 | 154 | return node_prev 155 | 156 | # Add initial/final node for a trace 157 | def _add_boundary_node(self, graph, node, is_root): 158 | graph.node(node, style="bold", shape="box") 159 | if is_root: 160 | graph.node(node, color=self.MARKED_TRACE_COLOR) 161 | 162 | # Add an edge denoting an implicit control flow within the trace 163 | def _add_implicit_cf_edge(self, graph, node1, node2, is_root): 164 | if is_root: 165 | graph.edge( 166 | node1, node2, 167 | color=self.MARKED_TRACE_COLOR, 168 | penwidth="1.5" 169 | ) 170 | else: 171 | graph.edge(node1, node2, style="dashed") 172 | -------------------------------------------------------------------------------- /dumpanalyze/view/traces.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Trace list view. 4 | # This module is a part of the toolkit for processing LuaJIT plain text dumps. 5 | # 6 | # Copyright 2017-2019 IPONWEB Ltd. 7 | # 8 | # Permission is hereby granted, free of charge, to any person obtaining a copy 9 | # of this software and associated documentation files (the "Software"), to deal 10 | # in the Software without restriction, including without limitation the rights 11 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | # copies of the Software, and to permit persons to whom the Software is 13 | # furnished to do so, subject to the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be included in 16 | # all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 | # IN THE SOFTWARE. 25 | # 26 | 27 | import csv 28 | 29 | 30 | class ViewTraces: 31 | 32 | CSV_HEADER = [ 33 | "ID", "PARENT", "LINK_TYPE", "NUM_BC", "NUM_IR", "NUM_SN", "SIZE_MC", 34 | ] 35 | 36 | def __init__(self, fmt): 37 | self._fmt = fmt 38 | 39 | def render(self, fname, traces): 40 | if self._fmt == "csv": 41 | self._render_csv(fname, traces) 42 | else: 43 | raise Exception("Unknown format") 44 | 45 | def _render_csv(self, fname, traces): 46 | with open(fname, "w", newline="") as out: 47 | writer = csv.writer( 48 | out, delimiter=",", quoting=csv.QUOTE_MINIMAL 49 | ) 50 | writer.writerow(self.CSV_HEADER) 51 | for trace in traces: 52 | writer.writerow([ 53 | trace.id, 54 | trace.parent_id, 55 | trace.link_type, 56 | trace.num_bc, 57 | trace.num_ir, 58 | trace.num_sn, 59 | trace.size_mcode, 60 | ]) 61 | -------------------------------------------------------------------------------- /requirements-install.txt: -------------------------------------------------------------------------------- 1 | graphviz 2 | -------------------------------------------------------------------------------- /requirements-setup.txt: -------------------------------------------------------------------------------- 1 | pytest-runner 2 | -------------------------------------------------------------------------------- /requirements-tests.txt: -------------------------------------------------------------------------------- 1 | flake8 2 | pytest 3 | -------------------------------------------------------------------------------- /run-tests.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Test suite runner for dumpanalyze 4 | # Copyright 2017-2019 IPONWEB Ltd. See License Notice in LICENSE 5 | # 6 | 7 | from setuptools import sandbox 8 | sandbox.run_setup('setup.py', ['flake8', 'pytest']) 9 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [aliases] 2 | test=pytest 3 | 4 | [tool:pytest] 5 | addopts = --verbose 6 | 7 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # setup.py for dumpanalyze 4 | # Copyright 2017-2019 IPONWEB Ltd. See License Notice in LICENSE 5 | # 6 | 7 | import re 8 | from setuptools import setup 9 | 10 | with open('requirements-setup.txt') as fh: 11 | setup_requires = fh.read().splitlines() 12 | 13 | with open('requirements-install.txt') as fh: 14 | install_requires = fh.read().splitlines() 15 | 16 | with open('requirements-tests.txt') as fh: 17 | tests_require = fh.read().splitlines() 18 | 19 | 20 | def version(): 21 | pyfile = 'dumpanalyze/__init__.py' 22 | with open(pyfile) as fp: 23 | data = fp.read() 24 | 25 | match = re.search('__version__ = [\'\"](.+)[\'\"]', data) 26 | assert match, 'cannot find version in {}'.format(pyfile) 27 | return match.group(1) 28 | 29 | 30 | setup( 31 | name='dumpanalyze', 32 | version=version(), 33 | description='Toolkit for processing LuaJIT plain text dumps', 34 | long_description=open('README.md').read(), 35 | author='Anton Soldatov', 36 | author_email='asoldatov@iponweb.net', 37 | license='MIT', 38 | url='https://github.com/iponweb/dumpanalyze', 39 | packages=['dumpanalyze', 'dumpanalyze.view'], 40 | zip_safe=False, 41 | entry_points={ 42 | 'console_scripts': [ 43 | 'dumpanalyze=dumpanalyze.__main__:main', 44 | ], 45 | }, 46 | classifiers=[ 47 | 'Development Status :: 4 - Beta', 48 | 'Environment :: Console', 49 | 'Intended Audience :: Developers', 50 | 'License :: OSI Approved :: MIT License', 51 | 'Programming Language :: Python :: 3', 52 | 'Programming Language :: Python :: 3.4', 53 | 'Programming Language :: Python :: 3.5', 54 | 'Programming Language :: Python :: 3.6', 55 | 'Topic :: Utilities', 56 | ], 57 | keywords='luajit dump', 58 | setup_requires=setup_requires, 59 | install_requires=install_requires, 60 | tests_require=tests_require, 61 | ) 62 | -------------------------------------------------------------------------------- /tests/dump-files/test_cli.txt: -------------------------------------------------------------------------------- 1 | ---- TRACE 1 start =(command line):1 2 | 0002 UGET 1 0 ; st 3 | 0003 ISF 1 4 | 0011 RET0 0 1 5 | ---- TRACE 1 IR 6 | .... SNAP #0 [ ---- ---- ] 7 | 0001 rax fun SLOAD #0 R 8 | 0002 rax > p32 UREFC 0001 #0 9 | 0003 rax > nil ULOAD 0002 10 | .... SNAP #1 [ ---- ] 11 | ---- TRACE 1 abort =(command line):1 -- failed to allocate mcode memory 12 | 13 | ---- TRACE flush 14 | 15 | ---- TRACE 1 start =(command line):1 16 | 0006 KSHORT 5 60 17 | 0007 ISGE 4 5 18 | 0009 ADD 0 0 4 19 | 0010 JMP 5 => 0019 20 | 0019 FORL 1 => 0006 21 | ---- TRACE 1 IR 22 | .... SNAP #0 [ ---- ] 23 | 0001 rbp int SLOAD #2 CI 24 | .... SNAP #1 [ ---- ---- 0001 ---- ---- 0001 ] 25 | 0002 > int LT 0001 +60 26 | .... SNAP #2 [ ---- ---- 0001 ---- ---- 0001 ] 27 | 0003 xmm0 > flt SLOAD #1 T 28 | 0004 xmm7 flt CONV 0001 flt.int 29 | 0005 xmm7 + flt ADD 0004 0003 30 | 0006 rbp + int ADD 0001 +1 31 | .... SNAP #3 [ ---- 0005 ] 32 | 0007 > int LE 0006 +300 33 | .... SNAP #4 [ ---- 0005 0006 ---- ---- 0006 ] 34 | 0008 ------------ LOOP ------------ 35 | .... SNAP #5 [ ---- 0005 0006 ---- ---- 0006 ] 36 | 0009 > int LT 0006 +60 37 | 0010 xmm6 flt CONV 0006 flt.int 38 | 0011 xmm7 + flt ADD 0010 0005 39 | 0012 rbp + int ADD 0006 +1 40 | .... SNAP #6 [ ---- 0011 ] 41 | 0013 > int LE 0012 +300 42 | 0014 rbp int PHI 0006 0012 43 | 0015 xmm7 flt PHI 0005 0011 44 | ---- TRACE 1 mcode 113 45 | 0bccff83 mov r11, 0x7f5c3bfde608 46 | 0bccff8d mov dword [r11], 0x1 47 | 0bccff94 cvtsd2si ebp, qword [r10+0x10] 48 | 0bccff9a cmp ebp, 0x3c 49 | 0bccff9d jge 0xbcc0014 ->1 50 | 0bccffa3 cmp dword [r10+0x8], 0xfffffff2 51 | 0bccffab jnz 0xbcc0018 ->2 52 | 0bccffb1 movsd xmm0, qword [r10] 53 | 0bccffb6 xorps xmm7, xmm7 54 | 0bccffb9 cvtsi2sd xmm7, ebp 55 | 0bccffbd addsd xmm7, xmm0 56 | 0bccffc1 add ebp, 0x1 57 | 0bccffc4 cmp ebp, 0x12c 58 | 0bccffca jg 0xbcc001c ->3 59 | -> LOOP: 60 | 0bccffd0 cmp ebp, 0x3c 61 | 0bccffd3 jge 0xbcc0024 ->5 62 | 0bccffd9 xorps xmm6, xmm6 63 | 0bccffdc cvtsi2sd xmm6, ebp 64 | 0bccffe0 addsd xmm7, xmm6 65 | 0bccffe4 add ebp, 0x1 66 | 0bccffe7 cmp ebp, 0x12c 67 | 0bccffed jle 0xbccffd0 ->LOOP 68 | 0bccffef jmp 0xbcc0028 ->6 69 | ---- TRACE 1 stop -> loop 70 | 71 | ---- TRACE 1 exit 5 72 | General-purpose registers 73 | rax = 0x000000000bccff83 74 | rcx = 0x00007f5c3bfe1620 75 | rdx = 000000000000000000 76 | rbx = 0x00007f5c3bfec138 77 | rsp = 0x00007fffc278c790 78 | rbp = 0x000000000000003c 79 | rsi = 0x00007f5c3bfe0870 80 | rdi = 0x00007f5c3bfe03d8 81 | r8 = 0x0000000000000026 82 | r9 = 0x0000000000000026 83 | r10 = 0x00007f5c3bfe0c38 84 | r11 = 0x0000000000439ccf 85 | r12 = 0x0000000000405560 86 | r13 = 0x00007fffc278cb70 87 | r14 = 0x00007f5c3bfe03d8 88 | r15 = 0x00007f5c3bfec150 89 | Floating-point registers 90 | xmm0 = +1653 91 | xmm1 = +300 92 | xmm2 = +0 93 | xmm3 = +0 94 | xmm4 = -5.4874582225771e+303 95 | xmm5 = +0 96 | xmm6 = +59 97 | xmm7 = +1770 98 | xmm8 = +2.1840409025922e-317 99 | xmm9 = +0 100 | xmm10 = +0 101 | xmm11 = +0 102 | xmm12 = +5.4110892669614e-312 103 | xmm13 = +0 104 | xmm14 = +0 105 | xmm15 = +0 106 | 107 | ---- TRACE 1 exit 1 108 | General-purpose registers 109 | rax = 0x000000000bccff83 110 | rcx = 0x00007f5c3bfe1620 111 | rdx = 000000000000000000 112 | rbx = 0x00007f5c3bfec138 113 | rsp = 0x00007fffc278c790 114 | rbp = 0x000000000000003d 115 | rsi = 0x00007f5c3bfec114 116 | rdi = 0x00007f5c3bfde790 117 | r8 = 0x00007f5c3bffe780 118 | r9 = 0x00007f5c3bffe780 119 | r10 = 0x00007f5c3bfe0c38 120 | r11 = 0x0000000000439ccf 121 | r12 = 0x0000000000405560 122 | r13 = 0x00007fffc278cb70 123 | r14 = 0x00007f5c3bfe03d8 124 | r15 = 0x00007f5c3bfec150 125 | Floating-point registers 126 | xmm0 = +61 127 | xmm1 = +300 128 | xmm2 = +0 129 | xmm3 = +0 130 | xmm4 = +3.2252605360517e-319 131 | xmm5 = +0 132 | xmm6 = +59 133 | xmm7 = +1770 134 | xmm8 = +0 135 | xmm9 = +0 136 | xmm10 = +0 137 | xmm11 = +0 138 | xmm12 = +3.2252605360517e-319 139 | xmm13 = +0 140 | xmm14 = +0 141 | xmm15 = +0 142 | 143 | ---- TRACE 1 exit 1 144 | General-purpose registers 145 | rax = 0x000000000bccff83 146 | rcx = 0x00007f5c3bfe1620 147 | rdx = 000000000000000000 148 | rbx = 0x00007f5c3bfec138 149 | rsp = 0x00007fffc278c790 150 | rbp = 0x000000000000003e 151 | rsi = 0x00007f5c3bfec114 152 | rdi = 0x00007f5c3bfde790 153 | r8 = 0x00007f5c3bffe780 154 | r9 = 0x00007f5c3bffe780 155 | r10 = 0x00007f5c3bfe0c38 156 | r11 = 0x0000000000439ccf 157 | r12 = 0x0000000000405560 158 | r13 = 0x00007fffc278cb70 159 | r14 = 0x00007f5c3bfe03d8 160 | r15 = 0x00007f5c3bfec150 161 | Floating-point registers 162 | xmm0 = +62 163 | xmm1 = +300 164 | xmm2 = +0 165 | xmm3 = +0 166 | xmm4 = +3.2252605360517e-319 167 | xmm5 = +0 168 | xmm6 = +59 169 | xmm7 = +1770 170 | xmm8 = +0 171 | xmm9 = +0 172 | xmm10 = +0 173 | xmm11 = +0 174 | xmm12 = +3.2252605360517e-319 175 | xmm13 = +0 176 | xmm14 = +0 177 | xmm15 = +0 178 | 179 | ---- TRACE 1 exit 1 180 | General-purpose registers 181 | rax = 0x000000000bccff83 182 | rcx = 0x00007f5c3bfe1620 183 | rdx = 000000000000000000 184 | rbx = 0x00007f5c3bfec138 185 | rsp = 0x00007fffc278c790 186 | rbp = 0x000000000000003f 187 | rsi = 0x00007f5c3bfec114 188 | rdi = 0x00007f5c3bfde790 189 | r8 = 0x00007f5c3bffe780 190 | r9 = 0x00007f5c3bffe780 191 | r10 = 0x00007f5c3bfe0c38 192 | r11 = 0x0000000000439ccf 193 | r12 = 0x0000000000405560 194 | r13 = 0x00007fffc278cb70 195 | r14 = 0x00007f5c3bfe03d8 196 | r15 = 0x00007f5c3bfec150 197 | Floating-point registers 198 | xmm0 = +63 199 | xmm1 = +300 200 | xmm2 = +0 201 | xmm3 = +0 202 | xmm4 = +3.2252605360517e-319 203 | xmm5 = +0 204 | xmm6 = +59 205 | xmm7 = +1770 206 | xmm8 = +0 207 | xmm9 = +0 208 | xmm10 = +0 209 | xmm11 = +0 210 | xmm12 = +3.2252605360517e-319 211 | xmm13 = +0 212 | xmm14 = +0 213 | xmm15 = +0 214 | 215 | ---- TRACE 1 exit 1 216 | General-purpose registers 217 | rax = 0x000000000bccff83 218 | rcx = 0x00007f5c3bfe1620 219 | rdx = 000000000000000000 220 | rbx = 0x00007f5c3bfec138 221 | rsp = 0x00007fffc278c790 222 | rbp = 0x0000000000000040 223 | rsi = 0x00007f5c3bfec114 224 | rdi = 0x00007f5c3bfde790 225 | r8 = 0x00007f5c3bffe780 226 | r9 = 0x00007f5c3bffe780 227 | r10 = 0x00007f5c3bfe0c38 228 | r11 = 0x0000000000439ccf 229 | r12 = 0x0000000000405560 230 | r13 = 0x00007fffc278cb70 231 | r14 = 0x00007f5c3bfe03d8 232 | r15 = 0x00007f5c3bfec150 233 | Floating-point registers 234 | xmm0 = +64 235 | xmm1 = +300 236 | xmm2 = +0 237 | xmm3 = +0 238 | xmm4 = +3.2252605360517e-319 239 | xmm5 = +0 240 | xmm6 = +59 241 | xmm7 = +1770 242 | xmm8 = +0 243 | xmm9 = +0 244 | xmm10 = +0 245 | xmm11 = +0 246 | xmm12 = +3.2252605360517e-319 247 | xmm13 = +0 248 | xmm14 = +0 249 | xmm15 = +0 250 | 251 | ---- TRACE 1 exit 1 252 | General-purpose registers 253 | rax = 0x000000000bccff83 254 | rcx = 0x00007f5c3bfe1620 255 | rdx = 000000000000000000 256 | rbx = 0x00007f5c3bfec138 257 | rsp = 0x00007fffc278c790 258 | rbp = 0x0000000000000041 259 | rsi = 0x00007f5c3bfec114 260 | rdi = 0x00007f5c3bfde790 261 | r8 = 0x00007f5c3bffe780 262 | r9 = 0x00007f5c3bffe780 263 | r10 = 0x00007f5c3bfe0c38 264 | r11 = 0x0000000000439ccf 265 | r12 = 0x0000000000405560 266 | r13 = 0x00007fffc278cb70 267 | r14 = 0x00007f5c3bfe03d8 268 | r15 = 0x00007f5c3bfec150 269 | Floating-point registers 270 | xmm0 = +65 271 | xmm1 = +300 272 | xmm2 = +0 273 | xmm3 = +0 274 | xmm4 = +3.2252605360517e-319 275 | xmm5 = +0 276 | xmm6 = +59 277 | xmm7 = +1770 278 | xmm8 = +0 279 | xmm9 = +0 280 | xmm10 = +0 281 | xmm11 = +0 282 | xmm12 = +3.2252605360517e-319 283 | xmm13 = +0 284 | xmm14 = +0 285 | xmm15 = +0 286 | 287 | ---- TRACE 1 exit 1 288 | General-purpose registers 289 | rax = 0x000000000bccff83 290 | rcx = 0x00007f5c3bfe1620 291 | rdx = 000000000000000000 292 | rbx = 0x00007f5c3bfec138 293 | rsp = 0x00007fffc278c790 294 | rbp = 0x0000000000000042 295 | rsi = 0x00007f5c3bfec114 296 | rdi = 0x00007f5c3bfde790 297 | r8 = 0x00007f5c3bffe780 298 | r9 = 0x00007f5c3bffe780 299 | r10 = 0x00007f5c3bfe0c38 300 | r11 = 0x0000000000439ccf 301 | r12 = 0x0000000000405560 302 | r13 = 0x00007fffc278cb70 303 | r14 = 0x00007f5c3bfe03d8 304 | r15 = 0x00007f5c3bfec150 305 | Floating-point registers 306 | xmm0 = +66 307 | xmm1 = +300 308 | xmm2 = +0 309 | xmm3 = +0 310 | xmm4 = +3.2252605360517e-319 311 | xmm5 = +0 312 | xmm6 = +59 313 | xmm7 = +1770 314 | xmm8 = +0 315 | xmm9 = +0 316 | xmm10 = +0 317 | xmm11 = +0 318 | xmm12 = +3.2252605360517e-319 319 | xmm13 = +0 320 | xmm14 = +0 321 | xmm15 = +0 322 | 323 | ---- TRACE 1 exit 1 324 | General-purpose registers 325 | rax = 0x000000000bccff83 326 | rcx = 0x00007f5c3bfe1620 327 | rdx = 000000000000000000 328 | rbx = 0x00007f5c3bfec138 329 | rsp = 0x00007fffc278c790 330 | rbp = 0x0000000000000043 331 | rsi = 0x00007f5c3bfec114 332 | rdi = 0x00007f5c3bfde790 333 | r8 = 0x00007f5c3bffe780 334 | r9 = 0x00007f5c3bffe780 335 | r10 = 0x00007f5c3bfe0c38 336 | r11 = 0x0000000000439ccf 337 | r12 = 0x0000000000405560 338 | r13 = 0x00007fffc278cb70 339 | r14 = 0x00007f5c3bfe03d8 340 | r15 = 0x00007f5c3bfec150 341 | Floating-point registers 342 | xmm0 = +67 343 | xmm1 = +300 344 | xmm2 = +0 345 | xmm3 = +0 346 | xmm4 = +3.2252605360517e-319 347 | xmm5 = +0 348 | xmm6 = +59 349 | xmm7 = +1770 350 | xmm8 = +0 351 | xmm9 = +0 352 | xmm10 = +0 353 | xmm11 = +0 354 | xmm12 = +3.2252605360517e-319 355 | xmm13 = +0 356 | xmm14 = +0 357 | xmm15 = +0 358 | 359 | ---- TRACE 1 exit 1 360 | General-purpose registers 361 | rax = 0x000000000bccff83 362 | rcx = 0x00007f5c3bfe1620 363 | rdx = 000000000000000000 364 | rbx = 0x00007f5c3bfec138 365 | rsp = 0x00007fffc278c790 366 | rbp = 0x0000000000000044 367 | rsi = 0x00007f5c3bfec114 368 | rdi = 0x00007f5c3bfde790 369 | r8 = 0x00007f5c3bffe780 370 | r9 = 0x00007f5c3bffe780 371 | r10 = 0x00007f5c3bfe0c38 372 | r11 = 0x0000000000439ccf 373 | r12 = 0x0000000000405560 374 | r13 = 0x00007fffc278cb70 375 | r14 = 0x00007f5c3bfe03d8 376 | r15 = 0x00007f5c3bfec150 377 | Floating-point registers 378 | xmm0 = +68 379 | xmm1 = +300 380 | xmm2 = +0 381 | xmm3 = +0 382 | xmm4 = +3.2252605360517e-319 383 | xmm5 = +0 384 | xmm6 = +59 385 | xmm7 = +1770 386 | xmm8 = +0 387 | xmm9 = +0 388 | xmm10 = +0 389 | xmm11 = +0 390 | xmm12 = +3.2252605360517e-319 391 | xmm13 = +0 392 | xmm14 = +0 393 | xmm15 = +0 394 | 395 | ---- TRACE 1 exit 1 396 | General-purpose registers 397 | rax = 0x000000000bccff83 398 | rcx = 0x00007f5c3bfe1620 399 | rdx = 000000000000000000 400 | rbx = 0x00007f5c3bfec138 401 | rsp = 0x00007fffc278c790 402 | rbp = 0x0000000000000045 403 | rsi = 0x00007f5c3bfec114 404 | rdi = 0x00007f5c3bfde790 405 | r8 = 0x00007f5c3bffe780 406 | r9 = 0x00007f5c3bffe780 407 | r10 = 0x00007f5c3bfe0c38 408 | r11 = 0x0000000000439ccf 409 | r12 = 0x0000000000405560 410 | r13 = 0x00007fffc278cb70 411 | r14 = 0x00007f5c3bfe03d8 412 | r15 = 0x00007f5c3bfec150 413 | Floating-point registers 414 | xmm0 = +69 415 | xmm1 = +300 416 | xmm2 = +0 417 | xmm3 = +0 418 | xmm4 = +3.2252605360517e-319 419 | xmm5 = +0 420 | xmm6 = +59 421 | xmm7 = +1770 422 | xmm8 = +0 423 | xmm9 = +0 424 | xmm10 = +0 425 | xmm11 = +0 426 | xmm12 = +3.2252605360517e-319 427 | xmm13 = +0 428 | xmm14 = +0 429 | xmm15 = +0 430 | 431 | ---- TRACE 1 exit 1 432 | General-purpose registers 433 | rax = 0x000000000bccff83 434 | rcx = 0x00007f5c3bfe1620 435 | rdx = 000000000000000000 436 | rbx = 0x00007f5c3bfec138 437 | rsp = 0x00007fffc278c790 438 | rbp = 0x0000000000000046 439 | rsi = 0x00007f5c3bfec114 440 | rdi = 0x00007f5c3bfde790 441 | r8 = 0x00007f5c3bffe780 442 | r9 = 0x00007f5c3bffe780 443 | r10 = 0x00007f5c3bfe0c38 444 | r11 = 0x0000000000439ccf 445 | r12 = 0x0000000000405560 446 | r13 = 0x00007fffc278cb70 447 | r14 = 0x00007f5c3bfe03d8 448 | r15 = 0x00007f5c3bfec150 449 | Floating-point registers 450 | xmm0 = +70 451 | xmm1 = +300 452 | xmm2 = +0 453 | xmm3 = +0 454 | xmm4 = +3.2252605360517e-319 455 | xmm5 = +0 456 | xmm6 = +59 457 | xmm7 = +1770 458 | xmm8 = +0 459 | xmm9 = +0 460 | xmm10 = +0 461 | xmm11 = +0 462 | xmm12 = +3.2252605360517e-319 463 | xmm13 = +0 464 | xmm14 = +0 465 | xmm15 = +0 466 | 467 | ---- TRACE 2 start 1/1 =(command line):1 468 | 0011 KSHORT 5 180 469 | 0012 ISGE 4 5 470 | 0014 SUB 0 0 4 471 | 0015 JMP 5 => 0019 472 | 0019 JFORL 1 1 473 | ---- TRACE 2 IR 474 | 0001 rbp int SLOAD #2 PI 475 | .... SNAP #0 [ ---- ---- 0001 ---- ---- 0001 ] 476 | .... SNAP #1 [ ---- ---- 0001 ---- ---- 0001 ] 477 | 0003 > int LT 0001 +180 478 | .... SNAP #2 [ ---- ---- 0001 ---- ---- 0001 ] 479 | 0004 xmm7 > flt SLOAD #1 T 480 | 0005 xmm6 flt CONV 0001 flt.int 481 | 0006 xmm7 flt SUB 0004 0005 482 | 0007 rbp int ADD 0001 +1 483 | .... SNAP #3 [ ---- 0006 ] 484 | 0008 > int LE 0007 +300 485 | 0009 xmm6 flt CONV 0007 flt.int 486 | .... SNAP #4 [ ---- 0006 0009 ---- ---- 0009 ] 487 | ---- TRACE 2 mcode 127 488 | 0bccfefd mov r11, 0x7f5c3bfde608 489 | 0bccff07 mov dword [r11], 0x2 490 | 0bccff0e cmp ebp, 0xb4 491 | 0bccff14 jge 0xbcc0014 ->1 492 | 0bccff1a cmp dword [r10+0x8], 0xfffffff2 493 | 0bccff22 jnz 0xbcc0018 ->2 494 | 0bccff28 movsd xmm7, qword [r10] 495 | 0bccff2d xorps xmm6, xmm6 496 | 0bccff30 cvtsi2sd xmm6, ebp 497 | 0bccff34 subsd xmm7, xmm6 498 | 0bccff38 add ebp, 0x1 499 | 0bccff3b cmp ebp, 0x12c 500 | 0bccff41 jg 0xbcc001c ->3 501 | 0bccff47 xorps xmm6, xmm6 502 | 0bccff4a cvtsi2sd xmm6, ebp 503 | 0bccff4e mov dword [r10+0x48], 0xfffffff2 504 | 0bccff56 movsd [r10+0x40], xmm6 505 | 0bccff5c mov dword [r10+0x18], 0xfffffff2 506 | 0bccff64 movsd [r10+0x10], xmm6 507 | 0bccff6a mov dword [r10+0x8], 0xfffffff2 508 | 0bccff72 movsd [r10], xmm7 509 | 0bccff77 jmp 0xbccff83 510 | ---- TRACE 2 stop -> 1 511 | 512 | ---- TRACE 2 exit 1 513 | General-purpose registers 514 | rax = 0x000000000bccff83 515 | rcx = 0x00007f5c3bfe1620 516 | rdx = 000000000000000000 517 | rbx = 0x00007f5c3bfec138 518 | rsp = 0x00007fffc278c790 519 | rbp = 0x00000000000000b4 520 | rsi = 0x00007f5c3bfe0870 521 | rdi = 0x00007f5c3bfe03d8 522 | r8 = 0x0000000000000026 523 | r9 = 0x0000000000000026 524 | r10 = 0x00007f5c3bfe0c38 525 | r11 = 0x0000000000439ccf 526 | r12 = 0x0000000000405560 527 | r13 = 0x00007fffc278cb70 528 | r14 = 0x00007f5c3bfe03d8 529 | r15 = 0x00007f5c3bfec150 530 | Floating-point registers 531 | xmm0 = +71 532 | xmm1 = +300 533 | xmm2 = +0 534 | xmm3 = +0 535 | xmm4 = +7.0632744564455e-304 536 | xmm5 = +0 537 | xmm6 = +180 538 | xmm7 = -12570 539 | xmm8 = +2.1840409025922e-317 540 | xmm9 = +0 541 | xmm10 = +0 542 | xmm11 = +0 543 | xmm12 = -nan 544 | xmm13 = +0 545 | xmm14 = +0 546 | xmm15 = +0 547 | 548 | ---- TRACE 2 exit 1 549 | General-purpose registers 550 | rax = 0x000000000bccff83 551 | rcx = 0x00007f5c3bfe1620 552 | rdx = 0x000000000000000a 553 | rbx = 0x00007f5c3bfec138 554 | rsp = 0x00007fffc278c790 555 | rbp = 0x00000000000000b5 556 | rsi = 0x00007f5c3b2a79e0 557 | rdi = 0x0000000000000001 558 | r8 = 0x000000000000000a 559 | r9 = 0x00007f5c3bffe780 560 | r10 = 0x00007f5c3bfe0c38 561 | r11 = 0x0000000000439ccf 562 | r12 = 0x0000000000405560 563 | r13 = 0x00007fffc278cb70 564 | r14 = 0x00007f5c3bfe03d8 565 | r15 = 0x00007f5c3bfec150 566 | Floating-point registers 567 | xmm0 = +181 568 | xmm1 = +300 569 | xmm2 = +0 570 | xmm3 = +0 571 | xmm4 = -5.486124068794e+303 572 | xmm5 = +0 573 | xmm6 = +180 574 | xmm7 = +180 575 | xmm8 = +0 576 | xmm9 = +0 577 | xmm10 = +0 578 | xmm11 = +0 579 | xmm12 = +3.2252605360517e-319 580 | xmm13 = +0 581 | xmm14 = +0 582 | xmm15 = +0 583 | 584 | ---- TRACE 2 exit 1 585 | General-purpose registers 586 | rax = 0x000000000bccff83 587 | rcx = 0x00007f5c3bfe1620 588 | rdx = 0x000000000000000a 589 | rbx = 0x00007f5c3bfec138 590 | rsp = 0x00007fffc278c790 591 | rbp = 0x00000000000000b6 592 | rsi = 0x00007f5c3b2a79e0 593 | rdi = 0x0000000000000001 594 | r8 = 0x000000000000000a 595 | r9 = 0x00007f5c3bffe780 596 | r10 = 0x00007f5c3bfe0c38 597 | r11 = 0x0000000000439ccf 598 | r12 = 0x0000000000405560 599 | r13 = 0x00007fffc278cb70 600 | r14 = 0x00007f5c3bfe03d8 601 | r15 = 0x00007f5c3bfec150 602 | Floating-point registers 603 | xmm0 = +182 604 | xmm1 = +300 605 | xmm2 = +0 606 | xmm3 = +0 607 | xmm4 = -5.486124068794e+303 608 | xmm5 = +0 609 | xmm6 = +180 610 | xmm7 = +181 611 | xmm8 = +0 612 | xmm9 = +0 613 | xmm10 = +0 614 | xmm11 = +0 615 | xmm12 = +3.2252605360517e-319 616 | xmm13 = +0 617 | xmm14 = +0 618 | xmm15 = +0 619 | 620 | ---- TRACE 2 exit 1 621 | General-purpose registers 622 | rax = 0x000000000bccff83 623 | rcx = 0x00007f5c3bfe1620 624 | rdx = 0x000000000000000a 625 | rbx = 0x00007f5c3bfec138 626 | rsp = 0x00007fffc278c790 627 | rbp = 0x00000000000000b7 628 | rsi = 0x00007f5c3b2a79e0 629 | rdi = 0x0000000000000001 630 | r8 = 0x000000000000000a 631 | r9 = 0x00007f5c3bffe780 632 | r10 = 0x00007f5c3bfe0c38 633 | r11 = 0x0000000000439ccf 634 | r12 = 0x0000000000405560 635 | r13 = 0x00007fffc278cb70 636 | r14 = 0x00007f5c3bfe03d8 637 | r15 = 0x00007f5c3bfec150 638 | Floating-point registers 639 | xmm0 = +183 640 | xmm1 = +300 641 | xmm2 = +0 642 | xmm3 = +0 643 | xmm4 = -5.486124068794e+303 644 | xmm5 = +0 645 | xmm6 = +180 646 | xmm7 = +182 647 | xmm8 = +0 648 | xmm9 = +0 649 | xmm10 = +0 650 | xmm11 = +0 651 | xmm12 = +3.2252605360517e-319 652 | xmm13 = +0 653 | xmm14 = +0 654 | xmm15 = +0 655 | 656 | ---- TRACE 2 exit 1 657 | General-purpose registers 658 | rax = 0x000000000bccff83 659 | rcx = 0x00007f5c3bfe1620 660 | rdx = 0x000000000000000a 661 | rbx = 0x00007f5c3bfec138 662 | rsp = 0x00007fffc278c790 663 | rbp = 0x00000000000000b8 664 | rsi = 0x00007f5c3b2a79e0 665 | rdi = 0x0000000000000001 666 | r8 = 0x000000000000000a 667 | r9 = 0x00007f5c3bffe780 668 | r10 = 0x00007f5c3bfe0c38 669 | r11 = 0x0000000000439ccf 670 | r12 = 0x0000000000405560 671 | r13 = 0x00007fffc278cb70 672 | r14 = 0x00007f5c3bfe03d8 673 | r15 = 0x00007f5c3bfec150 674 | Floating-point registers 675 | xmm0 = +184 676 | xmm1 = +300 677 | xmm2 = +0 678 | xmm3 = +0 679 | xmm4 = -5.486124068794e+303 680 | xmm5 = +0 681 | xmm6 = +180 682 | xmm7 = +183 683 | xmm8 = +0 684 | xmm9 = +0 685 | xmm10 = +0 686 | xmm11 = +0 687 | xmm12 = +3.2252605360517e-319 688 | xmm13 = +0 689 | xmm14 = +0 690 | xmm15 = +0 691 | 692 | ---- TRACE 2 exit 1 693 | General-purpose registers 694 | rax = 0x000000000bccff83 695 | rcx = 0x00007f5c3bfe1620 696 | rdx = 0x000000000000000a 697 | rbx = 0x00007f5c3bfec138 698 | rsp = 0x00007fffc278c790 699 | rbp = 0x00000000000000b9 700 | rsi = 0x00007f5c3b2a79e0 701 | rdi = 0x0000000000000001 702 | r8 = 0x000000000000000a 703 | r9 = 0x00007f5c3bffe780 704 | r10 = 0x00007f5c3bfe0c38 705 | r11 = 0x0000000000439ccf 706 | r12 = 0x0000000000405560 707 | r13 = 0x00007fffc278cb70 708 | r14 = 0x00007f5c3bfe03d8 709 | r15 = 0x00007f5c3bfec150 710 | Floating-point registers 711 | xmm0 = +185 712 | xmm1 = +300 713 | xmm2 = +0 714 | xmm3 = +0 715 | xmm4 = -5.486124068794e+303 716 | xmm5 = +0 717 | xmm6 = +180 718 | xmm7 = +184 719 | xmm8 = +0 720 | xmm9 = +0 721 | xmm10 = +0 722 | xmm11 = +0 723 | xmm12 = +3.2252605360517e-319 724 | xmm13 = +0 725 | xmm14 = +0 726 | xmm15 = +0 727 | 728 | ---- TRACE 2 exit 1 729 | General-purpose registers 730 | rax = 0x000000000bccff83 731 | rcx = 0x00007f5c3bfe1620 732 | rdx = 0x000000000000000a 733 | rbx = 0x00007f5c3bfec138 734 | rsp = 0x00007fffc278c790 735 | rbp = 0x00000000000000ba 736 | rsi = 0x00007f5c3b2a79e0 737 | rdi = 0x0000000000000001 738 | r8 = 0x000000000000000a 739 | r9 = 0x00007f5c3bffe780 740 | r10 = 0x00007f5c3bfe0c38 741 | r11 = 0x0000000000439ccf 742 | r12 = 0x0000000000405560 743 | r13 = 0x00007fffc278cb70 744 | r14 = 0x00007f5c3bfe03d8 745 | r15 = 0x00007f5c3bfec150 746 | Floating-point registers 747 | xmm0 = +186 748 | xmm1 = +300 749 | xmm2 = +0 750 | xmm3 = +0 751 | xmm4 = -5.486124068794e+303 752 | xmm5 = +0 753 | xmm6 = +180 754 | xmm7 = +185 755 | xmm8 = +0 756 | xmm9 = +0 757 | xmm10 = +0 758 | xmm11 = +0 759 | xmm12 = +3.2252605360517e-319 760 | xmm13 = +0 761 | xmm14 = +0 762 | xmm15 = +0 763 | 764 | ---- TRACE 2 exit 1 765 | General-purpose registers 766 | rax = 0x000000000bccff83 767 | rcx = 0x00007f5c3bfe1620 768 | rdx = 0x000000000000000a 769 | rbx = 0x00007f5c3bfec138 770 | rsp = 0x00007fffc278c790 771 | rbp = 0x00000000000000bb 772 | rsi = 0x00007f5c3b2a79e0 773 | rdi = 0x0000000000000001 774 | r8 = 0x000000000000000a 775 | r9 = 0x00007f5c3bffe780 776 | r10 = 0x00007f5c3bfe0c38 777 | r11 = 0x0000000000439ccf 778 | r12 = 0x0000000000405560 779 | r13 = 0x00007fffc278cb70 780 | r14 = 0x00007f5c3bfe03d8 781 | r15 = 0x00007f5c3bfec150 782 | Floating-point registers 783 | xmm0 = +187 784 | xmm1 = +300 785 | xmm2 = +0 786 | xmm3 = +0 787 | xmm4 = -5.486124068794e+303 788 | xmm5 = +0 789 | xmm6 = +180 790 | xmm7 = +186 791 | xmm8 = +0 792 | xmm9 = +0 793 | xmm10 = +0 794 | xmm11 = +0 795 | xmm12 = +3.2252605360517e-319 796 | xmm13 = +0 797 | xmm14 = +0 798 | xmm15 = +0 799 | 800 | ---- TRACE 2 exit 1 801 | General-purpose registers 802 | rax = 0x000000000bccff83 803 | rcx = 0x00007f5c3bfe1620 804 | rdx = 0x000000000000000a 805 | rbx = 0x00007f5c3bfec138 806 | rsp = 0x00007fffc278c790 807 | rbp = 0x00000000000000bc 808 | rsi = 0x00007f5c3b2a79e0 809 | rdi = 0x0000000000000001 810 | r8 = 0x000000000000000a 811 | r9 = 0x00007f5c3bffe780 812 | r10 = 0x00007f5c3bfe0c38 813 | r11 = 0x0000000000439ccf 814 | r12 = 0x0000000000405560 815 | r13 = 0x00007fffc278cb70 816 | r14 = 0x00007f5c3bfe03d8 817 | r15 = 0x00007f5c3bfec150 818 | Floating-point registers 819 | xmm0 = +188 820 | xmm1 = +300 821 | xmm2 = +0 822 | xmm3 = +0 823 | xmm4 = -5.486124068794e+303 824 | xmm5 = +0 825 | xmm6 = +180 826 | xmm7 = +187 827 | xmm8 = +0 828 | xmm9 = +0 829 | xmm10 = +0 830 | xmm11 = +0 831 | xmm12 = +3.2252605360517e-319 832 | xmm13 = +0 833 | xmm14 = +0 834 | xmm15 = +0 835 | 836 | ---- TRACE 2 exit 1 837 | General-purpose registers 838 | rax = 0x000000000bccff83 839 | rcx = 0x00007f5c3bfe1620 840 | rdx = 0x000000000000000a 841 | rbx = 0x00007f5c3bfec138 842 | rsp = 0x00007fffc278c790 843 | rbp = 0x00000000000000bd 844 | rsi = 0x00007f5c3b2a79e0 845 | rdi = 0x0000000000000001 846 | r8 = 0x000000000000000a 847 | r9 = 0x00007f5c3bffe780 848 | r10 = 0x00007f5c3bfe0c38 849 | r11 = 0x0000000000439ccf 850 | r12 = 0x0000000000405560 851 | r13 = 0x00007fffc278cb70 852 | r14 = 0x00007f5c3bfe03d8 853 | r15 = 0x00007f5c3bfec150 854 | Floating-point registers 855 | xmm0 = +189 856 | xmm1 = +300 857 | xmm2 = +0 858 | xmm3 = +0 859 | xmm4 = -5.486124068794e+303 860 | xmm5 = +0 861 | xmm6 = +180 862 | xmm7 = +188 863 | xmm8 = +0 864 | xmm9 = +0 865 | xmm10 = +0 866 | xmm11 = +0 867 | xmm12 = +3.2252605360517e-319 868 | xmm13 = +0 869 | xmm14 = +0 870 | xmm15 = +0 871 | 872 | ---- TRACE 3 start 2/1 =(command line):1 873 | 0016 GGET 5 0 ; "print" 874 | 0017 MOV 6 4 875 | 0018 CALL 5 1 2 876 | 0000 . FUNCC ; print 877 | ---- TRACE 3 IR 878 | 0001 rax int SLOAD #2 PI 879 | .... SNAP #0 [ ---- ---- 0001 ---- ---- 0001 ] 880 | 0002 [200] fun SLOAD #0 R 881 | 0003 rax tab FLOAD 0002 func.env 882 | 0004 [200] int FLOAD 0003 tab.hmask 883 | 0005 rax > int EQ 0004 +63 884 | 0006 [200] p32 FLOAD 0003 tab.node 885 | 0007 rax > p32 HREFK 0006 "print" @55 886 | 0008 rax > fun HLOAD 0007 887 | 0009 [200] > fun EQ 0008 print 888 | ---- TRACE 3 abort =(command line):1 -- NYI: FastFunc print 889 | 890 | ---- TRACE 2 exit 1 891 | General-purpose registers 892 | rax = 0x000000000bccff83 893 | rcx = 0x00007f5c3bfe1620 894 | rdx = 0x000000000000000a 895 | rbx = 0x00007f5c3bfec138 896 | rsp = 0x00007fffc278c790 897 | rbp = 0x00000000000000be 898 | rsi = 0x00007f5c3b2a79e0 899 | rdi = 0x0000000000000001 900 | r8 = 0x000000000000000a 901 | r9 = 0x00007f5c3bffe780 902 | r10 = 0x00007f5c3bfe0c38 903 | r11 = 0x0000000000439ccf 904 | r12 = 0x0000000000405560 905 | r13 = 0x00007fffc278cb70 906 | r14 = 0x00007f5c3bfe03d8 907 | r15 = 0x00007f5c3bfec150 908 | Floating-point registers 909 | xmm0 = +190 910 | xmm1 = +300 911 | xmm2 = +0 912 | xmm3 = +0 913 | xmm4 = -5.486124068794e+303 914 | xmm5 = +0 915 | xmm6 = +180 916 | xmm7 = +189 917 | xmm8 = +0 918 | xmm9 = +0 919 | xmm10 = +0 920 | xmm11 = +0 921 | xmm12 = +3.2252605360517e-319 922 | xmm13 = +0 923 | xmm14 = +0 924 | xmm15 = +0 925 | 926 | ---- TRACE 3 start 2/1 =(command line):1 927 | 0016 GGET 5 0 ; "print" 928 | 0017 MOV 6 4 929 | 0018 CALL 5 1 2 930 | 0000 . FUNCC ; print 931 | ---- TRACE 3 IR 932 | 0001 rax int SLOAD #2 PI 933 | .... SNAP #0 [ ---- ---- 0001 ---- ---- 0001 ] 934 | 0002 [200] fun SLOAD #0 R 935 | 0003 rax tab FLOAD 0002 func.env 936 | 0004 [200] int FLOAD 0003 tab.hmask 937 | 0005 rax > int EQ 0004 +63 938 | 0006 [200] p32 FLOAD 0003 tab.node 939 | 0007 rax > p32 HREFK 0006 "print" @55 940 | 0008 rax > fun HLOAD 0007 941 | 0009 [200] > fun EQ 0008 print 942 | ---- TRACE 3 abort =(command line):1 -- NYI: FastFunc print 943 | 944 | ---- TRACE 2 exit 1 945 | General-purpose registers 946 | rax = 0x000000000bccff83 947 | rcx = 0x00007f5c3bfe1620 948 | rdx = 0x000000000000000a 949 | rbx = 0x00007f5c3bfec138 950 | rsp = 0x00007fffc278c790 951 | rbp = 0x00000000000000bf 952 | rsi = 0x00007f5c3b2a79e0 953 | rdi = 0x0000000000000001 954 | r8 = 0x000000000000000a 955 | r9 = 0x00007f5c3bffe780 956 | r10 = 0x00007f5c3bfe0c38 957 | r11 = 0x0000000000439ccf 958 | r12 = 0x0000000000405560 959 | r13 = 0x00007fffc278cb70 960 | r14 = 0x00007f5c3bfe03d8 961 | r15 = 0x00007f5c3bfec150 962 | Floating-point registers 963 | xmm0 = +191 964 | xmm1 = +300 965 | xmm2 = +0 966 | xmm3 = +0 967 | xmm4 = -5.486124068794e+303 968 | xmm5 = +0 969 | xmm6 = +180 970 | xmm7 = +190 971 | xmm8 = +0 972 | xmm9 = +0 973 | xmm10 = +0 974 | xmm11 = +0 975 | xmm12 = +3.2252605360517e-319 976 | xmm13 = +0 977 | xmm14 = +0 978 | xmm15 = +0 979 | 980 | ---- TRACE 3 start 2/1 =(command line):1 981 | 0016 GGET 5 0 ; "print" 982 | 0017 MOV 6 4 983 | 0018 CALL 5 1 2 984 | 0000 . FUNCC ; print 985 | ---- TRACE 3 IR 986 | 0001 rax int SLOAD #2 PI 987 | .... SNAP #0 [ ---- ---- 0001 ---- ---- 0001 ] 988 | 0002 [200] fun SLOAD #0 R 989 | 0003 rax tab FLOAD 0002 func.env 990 | 0004 [200] int FLOAD 0003 tab.hmask 991 | 0005 rax > int EQ 0004 +63 992 | 0006 [200] p32 FLOAD 0003 tab.node 993 | 0007 rax > p32 HREFK 0006 "print" @55 994 | 0008 rax > fun HLOAD 0007 995 | 0009 [200] > fun EQ 0008 print 996 | ---- TRACE 3 abort =(command line):1 -- NYI: FastFunc print 997 | 998 | ---- TRACE 2 exit 1 999 | General-purpose registers 1000 | rax = 0x000000000bccff83 1001 | rcx = 0x00007f5c3bfe1620 1002 | rdx = 0x000000000000000a 1003 | rbx = 0x00007f5c3bfec138 1004 | rsp = 0x00007fffc278c790 1005 | rbp = 0x00000000000000c0 1006 | rsi = 0x00007f5c3b2a79e0 1007 | rdi = 0x0000000000000001 1008 | r8 = 0x000000000000000a 1009 | r9 = 0x00007f5c3bffe780 1010 | r10 = 0x00007f5c3bfe0c38 1011 | r11 = 0x0000000000439ccf 1012 | r12 = 0x0000000000405560 1013 | r13 = 0x00007fffc278cb70 1014 | r14 = 0x00007f5c3bfe03d8 1015 | r15 = 0x00007f5c3bfec150 1016 | Floating-point registers 1017 | xmm0 = +192 1018 | xmm1 = +300 1019 | xmm2 = +0 1020 | xmm3 = +0 1021 | xmm4 = -5.486124068794e+303 1022 | xmm5 = +0 1023 | xmm6 = +180 1024 | xmm7 = +191 1025 | xmm8 = +0 1026 | xmm9 = +0 1027 | xmm10 = +0 1028 | xmm11 = +0 1029 | xmm12 = +3.2252605360517e-319 1030 | xmm13 = +0 1031 | xmm14 = +0 1032 | xmm15 = +0 1033 | 1034 | ---- TRACE 3 start 2/1 =(command line):1 1035 | 0016 GGET 5 0 ; "print" 1036 | 0017 MOV 6 4 1037 | 0018 CALL 5 1 2 1038 | 0000 . FUNCC ; print 1039 | ---- TRACE 3 IR 1040 | 0001 rax int SLOAD #2 PI 1041 | .... SNAP #0 [ ---- ---- 0001 ---- ---- 0001 ] 1042 | 0002 [200] fun SLOAD #0 R 1043 | 0003 rax tab FLOAD 0002 func.env 1044 | 0004 [200] int FLOAD 0003 tab.hmask 1045 | 0005 rax > int EQ 0004 +63 1046 | 0006 [200] p32 FLOAD 0003 tab.node 1047 | 0007 rax > p32 HREFK 0006 "print" @55 1048 | 0008 rax > fun HLOAD 0007 1049 | 0009 [200] > fun EQ 0008 print 1050 | ---- TRACE 3 abort =(command line):1 -- NYI: FastFunc print 1051 | 1052 | ---- TRACE 2 exit 1 1053 | General-purpose registers 1054 | rax = 0x000000000bccff83 1055 | rcx = 0x00007f5c3bfe1620 1056 | rdx = 0x000000000000000a 1057 | rbx = 0x00007f5c3bfec138 1058 | rsp = 0x00007fffc278c790 1059 | rbp = 0x00000000000000c1 1060 | rsi = 0x00007f5c3b2a79e0 1061 | rdi = 0x0000000000000001 1062 | r8 = 0x000000000000000a 1063 | r9 = 0x00007f5c3bffe780 1064 | r10 = 0x00007f5c3bfe0c38 1065 | r11 = 0x0000000000439ccf 1066 | r12 = 0x0000000000405560 1067 | r13 = 0x00007fffc278cb70 1068 | r14 = 0x00007f5c3bfe03d8 1069 | r15 = 0x00007f5c3bfec150 1070 | Floating-point registers 1071 | xmm0 = +193 1072 | xmm1 = +300 1073 | xmm2 = +0 1074 | xmm3 = +0 1075 | xmm4 = -5.486124068794e+303 1076 | xmm5 = +0 1077 | xmm6 = +180 1078 | xmm7 = +192 1079 | xmm8 = +0 1080 | xmm9 = +0 1081 | xmm10 = +0 1082 | xmm11 = +0 1083 | xmm12 = +3.2252605360517e-319 1084 | xmm13 = +0 1085 | xmm14 = +0 1086 | xmm15 = +0 1087 | 1088 | ---- TRACE 3 start 2/1 =(command line):1 1089 | ---- TRACE 3 IR 1090 | 0001 rbp int SLOAD #2 PI 1091 | .... SNAP #0 [ ---- ---- 0001 ---- ---- 0001 ] 1092 | 0002 xmm7 flt CONV 0001 flt.int 1093 | .... SNAP #1 [ ---- ---- 0002 ---- ---- 0002 ] 1094 | ---- TRACE 3 mcode 79 1095 | 0bccfea7 mov r11, 0x7f5c3bfde608 1096 | 0bccfeb1 mov dword [r11], 0x3 1097 | 0bccfeb8 xorps xmm7, xmm7 1098 | 0bccfebb cvtsi2sd xmm7, ebp 1099 | 0bccfebf mov dword [r10+0x48], 0xfffffff2 1100 | 0bccfec7 movsd [r10+0x40], xmm7 1101 | 0bccfecd mov dword [r10+0x18], 0xfffffff2 1102 | 0bccfed5 movsd [r10+0x10], xmm7 1103 | 0bccfedb xor eax, eax 1104 | 0bccfedd mov rbx, 0x7f5c3bfec128 1105 | 0bccfee7 mov r14, 0x7f5c3bfe03d8 1106 | 0bccfef1 jmp 0x439dcc 1107 | ---- TRACE 3 stop -> interpreter 1108 | 1109 | -------------------------------------------------------------------------------- /tests/dump-files/test_objects.txt: -------------------------------------------------------------------------------- 1 | ---- TRACE 1 start =(command line):1 2 | 0006 KSHORT 5 60 3 | 0007 ISGE 4 5 4 | 0009 ADD 0 0 4 5 | 0010 JMP 5 => 0019 6 | 0019 FORL 1 => 0006 7 | ---- TRACE 1 IR 8 | .... SNAP #0 [ ---- ] 9 | 0001 rbp int SLOAD #2 CI 10 | .... SNAP #1 [ ---- ---- 0001 ---- ---- 0001 ] 11 | 0002 > int LT 0001 +60 12 | .... SNAP #2 [ ---- ---- 0001 ---- ---- 0001 ] 13 | 0003 xmm0 > flt SLOAD #1 T 14 | 0004 xmm7 flt CONV 0001 flt.int 15 | 0005 xmm7 + flt ADD 0004 0003 16 | 0006 rbp + int ADD 0001 +1 17 | .... SNAP #3 [ ---- 0005 ] 18 | 0007 > int LE 0006 +300 19 | .... SNAP #4 [ ---- 0005 0006 ---- ---- 0006 ] 20 | 0008 ------------ LOOP ------------ 21 | .... SNAP #5 [ ---- 0005 0006 ---- ---- 0006 ] 22 | 0009 > int LT 0006 +60 23 | 0010 xmm6 flt CONV 0006 flt.int 24 | 0011 xmm7 + flt ADD 0010 0005 25 | 0012 rbp + int ADD 0006 +1 26 | .... SNAP #6 [ ---- 0011 ] 27 | 0013 > int LE 0012 +300 28 | 0014 rbp int PHI 0006 0012 29 | 0015 xmm7 flt PHI 0005 0011 30 | ---- TRACE 1 mcode 113 31 | 0bccff83 mov r11, 0x7f5c3bfde608 32 | 0bccff8d mov dword [r11], 0x1 33 | 0bccff94 cvtsd2si ebp, qword [r10+0x10] 34 | 0bccff9a cmp ebp, 0x3c 35 | 0bccff9d jge 0xbcc0014 ->1 36 | 0bccffa3 cmp dword [r10+0x8], 0xfffffff2 37 | 0bccffab jnz 0xbcc0018 ->2 38 | 0bccffb1 movsd xmm0, qword [r10] 39 | 0bccffb6 xorps xmm7, xmm7 40 | 0bccffb9 cvtsi2sd xmm7, ebp 41 | 0bccffbd addsd xmm7, xmm0 42 | 0bccffc1 add ebp, 0x1 43 | 0bccffc4 cmp ebp, 0x12c 44 | 0bccffca jg 0xbcc001c ->3 45 | -> LOOP: 46 | 0bccffd0 cmp ebp, 0x3c 47 | 0bccffd3 jge 0xbcc0024 ->5 48 | 0bccffd9 xorps xmm6, xmm6 49 | 0bccffdc cvtsi2sd xmm6, ebp 50 | 0bccffe0 addsd xmm7, xmm6 51 | 0bccffe4 add ebp, 0x1 52 | 0bccffe7 cmp ebp, 0x12c 53 | 0bccffed jle 0xbccffd0 ->LOOP 54 | 0bccffef jmp 0xbcc0028 ->6 55 | ---- TRACE 1 stop -> loop 56 | 57 | ---- TRACE 1 exit 5 58 | General-purpose registers 59 | rax = 0x000000000bccff83 60 | rcx = 0x00007f5c3bfe1620 61 | rdx = 000000000000000000 62 | rbx = 0x00007f5c3bfec138 63 | rsp = 0x00007fffc278c790 64 | rbp = 0x000000000000003c 65 | rsi = 0x00007f5c3bfe0870 66 | rdi = 0x00007f5c3bfe03d8 67 | r8 = 0x0000000000000026 68 | r9 = 0x0000000000000026 69 | r10 = 0x00007f5c3bfe0c38 70 | r11 = 0x0000000000439ccf 71 | r12 = 0x0000000000405560 72 | r13 = 0x00007fffc278cb70 73 | r14 = 0x00007f5c3bfe03d8 74 | r15 = 0x00007f5c3bfec150 75 | Floating-point registers 76 | xmm0 = +1653 77 | xmm1 = +300 78 | xmm2 = +0 79 | xmm3 = +0 80 | xmm4 = -5.4874582225771e+303 81 | xmm5 = +0 82 | xmm6 = +59 83 | xmm7 = +1770 84 | xmm8 = +2.1840409025922e-317 85 | xmm9 = +0 86 | xmm10 = +0 87 | xmm11 = +0 88 | xmm12 = +5.4110892669614e-312 89 | xmm13 = +0 90 | xmm14 = +0 91 | xmm15 = +0 92 | 93 | ---- TRACE 1 exit 1 94 | General-purpose registers 95 | rax = 0x000000000bccff83 96 | rcx = 0x00007f5c3bfe1620 97 | rdx = 000000000000000000 98 | rbx = 0x00007f5c3bfec138 99 | rsp = 0x00007fffc278c790 100 | rbp = 0x000000000000003d 101 | rsi = 0x00007f5c3bfec114 102 | rdi = 0x00007f5c3bfde790 103 | r8 = 0x00007f5c3bffe780 104 | r9 = 0x00007f5c3bffe780 105 | r10 = 0x00007f5c3bfe0c38 106 | r11 = 0x0000000000439ccf 107 | r12 = 0x0000000000405560 108 | r13 = 0x00007fffc278cb70 109 | r14 = 0x00007f5c3bfe03d8 110 | r15 = 0x00007f5c3bfec150 111 | Floating-point registers 112 | xmm0 = +61 113 | xmm1 = +300 114 | xmm2 = +0 115 | xmm3 = +0 116 | xmm4 = +3.2252605360517e-319 117 | xmm5 = +0 118 | xmm6 = +59 119 | xmm7 = +1770 120 | xmm8 = +0 121 | xmm9 = +0 122 | xmm10 = +0 123 | xmm11 = +0 124 | xmm12 = +3.2252605360517e-319 125 | xmm13 = +0 126 | xmm14 = +0 127 | xmm15 = +0 128 | 129 | ---- TRACE 1 exit 1 130 | General-purpose registers 131 | rax = 0x000000000bccff83 132 | rcx = 0x00007f5c3bfe1620 133 | rdx = 000000000000000000 134 | rbx = 0x00007f5c3bfec138 135 | rsp = 0x00007fffc278c790 136 | rbp = 0x000000000000003e 137 | rsi = 0x00007f5c3bfec114 138 | rdi = 0x00007f5c3bfde790 139 | r8 = 0x00007f5c3bffe780 140 | r9 = 0x00007f5c3bffe780 141 | r10 = 0x00007f5c3bfe0c38 142 | r11 = 0x0000000000439ccf 143 | r12 = 0x0000000000405560 144 | r13 = 0x00007fffc278cb70 145 | r14 = 0x00007f5c3bfe03d8 146 | r15 = 0x00007f5c3bfec150 147 | Floating-point registers 148 | xmm0 = +62 149 | xmm1 = +300 150 | xmm2 = +0 151 | xmm3 = +0 152 | xmm4 = +3.2252605360517e-319 153 | xmm5 = +0 154 | xmm6 = +59 155 | xmm7 = +1770 156 | xmm8 = +0 157 | xmm9 = +0 158 | xmm10 = +0 159 | xmm11 = +0 160 | xmm12 = +3.2252605360517e-319 161 | xmm13 = +0 162 | xmm14 = +0 163 | xmm15 = +0 164 | 165 | ---- TRACE 1 exit 1 166 | General-purpose registers 167 | rax = 0x000000000bccff83 168 | rcx = 0x00007f5c3bfe1620 169 | rdx = 000000000000000000 170 | rbx = 0x00007f5c3bfec138 171 | rsp = 0x00007fffc278c790 172 | rbp = 0x000000000000003f 173 | rsi = 0x00007f5c3bfec114 174 | rdi = 0x00007f5c3bfde790 175 | r8 = 0x00007f5c3bffe780 176 | r9 = 0x00007f5c3bffe780 177 | r10 = 0x00007f5c3bfe0c38 178 | r11 = 0x0000000000439ccf 179 | r12 = 0x0000000000405560 180 | r13 = 0x00007fffc278cb70 181 | r14 = 0x00007f5c3bfe03d8 182 | r15 = 0x00007f5c3bfec150 183 | Floating-point registers 184 | xmm0 = +63 185 | xmm1 = +300 186 | xmm2 = +0 187 | xmm3 = +0 188 | xmm4 = +3.2252605360517e-319 189 | xmm5 = +0 190 | xmm6 = +59 191 | xmm7 = +1770 192 | xmm8 = +0 193 | xmm9 = +0 194 | xmm10 = +0 195 | xmm11 = +0 196 | xmm12 = +3.2252605360517e-319 197 | xmm13 = +0 198 | xmm14 = +0 199 | xmm15 = +0 200 | 201 | ---- TRACE 1 exit 1 202 | General-purpose registers 203 | rax = 0x000000000bccff83 204 | rcx = 0x00007f5c3bfe1620 205 | rdx = 000000000000000000 206 | rbx = 0x00007f5c3bfec138 207 | rsp = 0x00007fffc278c790 208 | rbp = 0x0000000000000040 209 | rsi = 0x00007f5c3bfec114 210 | rdi = 0x00007f5c3bfde790 211 | r8 = 0x00007f5c3bffe780 212 | r9 = 0x00007f5c3bffe780 213 | r10 = 0x00007f5c3bfe0c38 214 | r11 = 0x0000000000439ccf 215 | r12 = 0x0000000000405560 216 | r13 = 0x00007fffc278cb70 217 | r14 = 0x00007f5c3bfe03d8 218 | r15 = 0x00007f5c3bfec150 219 | Floating-point registers 220 | xmm0 = +64 221 | xmm1 = +300 222 | xmm2 = +0 223 | xmm3 = +0 224 | xmm4 = +3.2252605360517e-319 225 | xmm5 = +0 226 | xmm6 = +59 227 | xmm7 = +1770 228 | xmm8 = +0 229 | xmm9 = +0 230 | xmm10 = +0 231 | xmm11 = +0 232 | xmm12 = +3.2252605360517e-319 233 | xmm13 = +0 234 | xmm14 = +0 235 | xmm15 = +0 236 | 237 | ---- TRACE 1 exit 1 238 | General-purpose registers 239 | rax = 0x000000000bccff83 240 | rcx = 0x00007f5c3bfe1620 241 | rdx = 000000000000000000 242 | rbx = 0x00007f5c3bfec138 243 | rsp = 0x00007fffc278c790 244 | rbp = 0x0000000000000041 245 | rsi = 0x00007f5c3bfec114 246 | rdi = 0x00007f5c3bfde790 247 | r8 = 0x00007f5c3bffe780 248 | r9 = 0x00007f5c3bffe780 249 | r10 = 0x00007f5c3bfe0c38 250 | r11 = 0x0000000000439ccf 251 | r12 = 0x0000000000405560 252 | r13 = 0x00007fffc278cb70 253 | r14 = 0x00007f5c3bfe03d8 254 | r15 = 0x00007f5c3bfec150 255 | Floating-point registers 256 | xmm0 = +65 257 | xmm1 = +300 258 | xmm2 = +0 259 | xmm3 = +0 260 | xmm4 = +3.2252605360517e-319 261 | xmm5 = +0 262 | xmm6 = +59 263 | xmm7 = +1770 264 | xmm8 = +0 265 | xmm9 = +0 266 | xmm10 = +0 267 | xmm11 = +0 268 | xmm12 = +3.2252605360517e-319 269 | xmm13 = +0 270 | xmm14 = +0 271 | xmm15 = +0 272 | 273 | ---- TRACE 1 exit 1 274 | General-purpose registers 275 | rax = 0x000000000bccff83 276 | rcx = 0x00007f5c3bfe1620 277 | rdx = 000000000000000000 278 | rbx = 0x00007f5c3bfec138 279 | rsp = 0x00007fffc278c790 280 | rbp = 0x0000000000000042 281 | rsi = 0x00007f5c3bfec114 282 | rdi = 0x00007f5c3bfde790 283 | r8 = 0x00007f5c3bffe780 284 | r9 = 0x00007f5c3bffe780 285 | r10 = 0x00007f5c3bfe0c38 286 | r11 = 0x0000000000439ccf 287 | r12 = 0x0000000000405560 288 | r13 = 0x00007fffc278cb70 289 | r14 = 0x00007f5c3bfe03d8 290 | r15 = 0x00007f5c3bfec150 291 | Floating-point registers 292 | xmm0 = +66 293 | xmm1 = +300 294 | xmm2 = +0 295 | xmm3 = +0 296 | xmm4 = +3.2252605360517e-319 297 | xmm5 = +0 298 | xmm6 = +59 299 | xmm7 = +1770 300 | xmm8 = +0 301 | xmm9 = +0 302 | xmm10 = +0 303 | xmm11 = +0 304 | xmm12 = +3.2252605360517e-319 305 | xmm13 = +0 306 | xmm14 = +0 307 | xmm15 = +0 308 | 309 | ---- TRACE 1 exit 1 310 | General-purpose registers 311 | rax = 0x000000000bccff83 312 | rcx = 0x00007f5c3bfe1620 313 | rdx = 000000000000000000 314 | rbx = 0x00007f5c3bfec138 315 | rsp = 0x00007fffc278c790 316 | rbp = 0x0000000000000043 317 | rsi = 0x00007f5c3bfec114 318 | rdi = 0x00007f5c3bfde790 319 | r8 = 0x00007f5c3bffe780 320 | r9 = 0x00007f5c3bffe780 321 | r10 = 0x00007f5c3bfe0c38 322 | r11 = 0x0000000000439ccf 323 | r12 = 0x0000000000405560 324 | r13 = 0x00007fffc278cb70 325 | r14 = 0x00007f5c3bfe03d8 326 | r15 = 0x00007f5c3bfec150 327 | Floating-point registers 328 | xmm0 = +67 329 | xmm1 = +300 330 | xmm2 = +0 331 | xmm3 = +0 332 | xmm4 = +3.2252605360517e-319 333 | xmm5 = +0 334 | xmm6 = +59 335 | xmm7 = +1770 336 | xmm8 = +0 337 | xmm9 = +0 338 | xmm10 = +0 339 | xmm11 = +0 340 | xmm12 = +3.2252605360517e-319 341 | xmm13 = +0 342 | xmm14 = +0 343 | xmm15 = +0 344 | 345 | ---- TRACE 1 exit 1 346 | General-purpose registers 347 | rax = 0x000000000bccff83 348 | rcx = 0x00007f5c3bfe1620 349 | rdx = 000000000000000000 350 | rbx = 0x00007f5c3bfec138 351 | rsp = 0x00007fffc278c790 352 | rbp = 0x0000000000000044 353 | rsi = 0x00007f5c3bfec114 354 | rdi = 0x00007f5c3bfde790 355 | r8 = 0x00007f5c3bffe780 356 | r9 = 0x00007f5c3bffe780 357 | r10 = 0x00007f5c3bfe0c38 358 | r11 = 0x0000000000439ccf 359 | r12 = 0x0000000000405560 360 | r13 = 0x00007fffc278cb70 361 | r14 = 0x00007f5c3bfe03d8 362 | r15 = 0x00007f5c3bfec150 363 | Floating-point registers 364 | xmm0 = +68 365 | xmm1 = +300 366 | xmm2 = +0 367 | xmm3 = +0 368 | xmm4 = +3.2252605360517e-319 369 | xmm5 = +0 370 | xmm6 = +59 371 | xmm7 = +1770 372 | xmm8 = +0 373 | xmm9 = +0 374 | xmm10 = +0 375 | xmm11 = +0 376 | xmm12 = +3.2252605360517e-319 377 | xmm13 = +0 378 | xmm14 = +0 379 | xmm15 = +0 380 | 381 | ---- TRACE 1 exit 1 382 | General-purpose registers 383 | rax = 0x000000000bccff83 384 | rcx = 0x00007f5c3bfe1620 385 | rdx = 000000000000000000 386 | rbx = 0x00007f5c3bfec138 387 | rsp = 0x00007fffc278c790 388 | rbp = 0x0000000000000045 389 | rsi = 0x00007f5c3bfec114 390 | rdi = 0x00007f5c3bfde790 391 | r8 = 0x00007f5c3bffe780 392 | r9 = 0x00007f5c3bffe780 393 | r10 = 0x00007f5c3bfe0c38 394 | r11 = 0x0000000000439ccf 395 | r12 = 0x0000000000405560 396 | r13 = 0x00007fffc278cb70 397 | r14 = 0x00007f5c3bfe03d8 398 | r15 = 0x00007f5c3bfec150 399 | Floating-point registers 400 | xmm0 = +69 401 | xmm1 = +300 402 | xmm2 = +0 403 | xmm3 = +0 404 | xmm4 = +3.2252605360517e-319 405 | xmm5 = +0 406 | xmm6 = +59 407 | xmm7 = +1770 408 | xmm8 = +0 409 | xmm9 = +0 410 | xmm10 = +0 411 | xmm11 = +0 412 | xmm12 = +3.2252605360517e-319 413 | xmm13 = +0 414 | xmm14 = +0 415 | xmm15 = +0 416 | 417 | ---- TRACE 1 exit 1 418 | General-purpose registers 419 | rax = 0x000000000bccff83 420 | rcx = 0x00007f5c3bfe1620 421 | rdx = 000000000000000000 422 | rbx = 0x00007f5c3bfec138 423 | rsp = 0x00007fffc278c790 424 | rbp = 0x0000000000000046 425 | rsi = 0x00007f5c3bfec114 426 | rdi = 0x00007f5c3bfde790 427 | r8 = 0x00007f5c3bffe780 428 | r9 = 0x00007f5c3bffe780 429 | r10 = 0x00007f5c3bfe0c38 430 | r11 = 0x0000000000439ccf 431 | r12 = 0x0000000000405560 432 | r13 = 0x00007fffc278cb70 433 | r14 = 0x00007f5c3bfe03d8 434 | r15 = 0x00007f5c3bfec150 435 | Floating-point registers 436 | xmm0 = +70 437 | xmm1 = +300 438 | xmm2 = +0 439 | xmm3 = +0 440 | xmm4 = +3.2252605360517e-319 441 | xmm5 = +0 442 | xmm6 = +59 443 | xmm7 = +1770 444 | xmm8 = +0 445 | xmm9 = +0 446 | xmm10 = +0 447 | xmm11 = +0 448 | xmm12 = +3.2252605360517e-319 449 | xmm13 = +0 450 | xmm14 = +0 451 | xmm15 = +0 452 | 453 | ---- TRACE 2 start 1/1 =(command line):1 454 | 0011 KSHORT 5 180 455 | 0012 ISGE 4 5 456 | 0014 SUB 0 0 4 457 | 0015 JMP 5 => 0019 458 | 0019 JFORL 1 1 459 | ---- TRACE 2 IR 460 | 0001 rbp int SLOAD #2 PI 461 | .... SNAP #0 [ ---- ---- 0001 ---- ---- 0001 ] 462 | .... SNAP #1 [ ---- ---- 0001 ---- ---- 0001 ] 463 | 0003 > int LT 0001 +180 464 | .... SNAP #2 [ ---- ---- 0001 ---- ---- 0001 ] 465 | 0004 xmm7 > flt SLOAD #1 T 466 | 0005 xmm6 flt CONV 0001 flt.int 467 | 0006 xmm7 flt SUB 0004 0005 468 | 0007 rbp int ADD 0001 +1 469 | .... SNAP #3 [ ---- 0006 ] 470 | 0008 > int LE 0007 +300 471 | 0009 xmm6 flt CONV 0007 flt.int 472 | .... SNAP #4 [ ---- 0006 0009 ---- ---- 0009 ] 473 | ---- TRACE 2 mcode 127 474 | 0bccfefd mov r11, 0x7f5c3bfde608 475 | 0bccff07 mov dword [r11], 0x2 476 | 0bccff0e cmp ebp, 0xb4 477 | 0bccff14 jge 0xbcc0014 ->1 478 | 0bccff1a cmp dword [r10+0x8], 0xfffffff2 479 | 0bccff22 jnz 0xbcc0018 ->2 480 | 0bccff28 movsd xmm7, qword [r10] 481 | 0bccff2d xorps xmm6, xmm6 482 | 0bccff30 cvtsi2sd xmm6, ebp 483 | 0bccff34 subsd xmm7, xmm6 484 | 0bccff38 add ebp, 0x1 485 | 0bccff3b cmp ebp, 0x12c 486 | 0bccff41 jg 0xbcc001c ->3 487 | 0bccff47 xorps xmm6, xmm6 488 | 0bccff4a cvtsi2sd xmm6, ebp 489 | 0bccff4e mov dword [r10+0x48], 0xfffffff2 490 | 0bccff56 movsd [r10+0x40], xmm6 491 | 0bccff5c mov dword [r10+0x18], 0xfffffff2 492 | 0bccff64 movsd [r10+0x10], xmm6 493 | 0bccff6a mov dword [r10+0x8], 0xfffffff2 494 | 0bccff72 movsd [r10], xmm7 495 | 0bccff77 jmp 0xbccff83 496 | ---- TRACE 2 stop -> 1 497 | 498 | ---- TRACE 2 exit 1 499 | General-purpose registers 500 | rax = 0x000000000bccff83 501 | rcx = 0x00007f5c3bfe1620 502 | rdx = 000000000000000000 503 | rbx = 0x00007f5c3bfec138 504 | rsp = 0x00007fffc278c790 505 | rbp = 0x00000000000000b4 506 | rsi = 0x00007f5c3bfe0870 507 | rdi = 0x00007f5c3bfe03d8 508 | r8 = 0x0000000000000026 509 | r9 = 0x0000000000000026 510 | r10 = 0x00007f5c3bfe0c38 511 | r11 = 0x0000000000439ccf 512 | r12 = 0x0000000000405560 513 | r13 = 0x00007fffc278cb70 514 | r14 = 0x00007f5c3bfe03d8 515 | r15 = 0x00007f5c3bfec150 516 | Floating-point registers 517 | xmm0 = +71 518 | xmm1 = +300 519 | xmm2 = +0 520 | xmm3 = +0 521 | xmm4 = +7.0632744564455e-304 522 | xmm5 = +0 523 | xmm6 = +180 524 | xmm7 = -12570 525 | xmm8 = +2.1840409025922e-317 526 | xmm9 = +0 527 | xmm10 = +0 528 | xmm11 = +0 529 | xmm12 = -nan 530 | xmm13 = +0 531 | xmm14 = +0 532 | xmm15 = +0 533 | 534 | ---- TRACE 2 exit 1 535 | General-purpose registers 536 | rax = 0x000000000bccff83 537 | rcx = 0x00007f5c3bfe1620 538 | rdx = 0x000000000000000a 539 | rbx = 0x00007f5c3bfec138 540 | rsp = 0x00007fffc278c790 541 | rbp = 0x00000000000000b5 542 | rsi = 0x00007f5c3b2a79e0 543 | rdi = 0x0000000000000001 544 | r8 = 0x000000000000000a 545 | r9 = 0x00007f5c3bffe780 546 | r10 = 0x00007f5c3bfe0c38 547 | r11 = 0x0000000000439ccf 548 | r12 = 0x0000000000405560 549 | r13 = 0x00007fffc278cb70 550 | r14 = 0x00007f5c3bfe03d8 551 | r15 = 0x00007f5c3bfec150 552 | Floating-point registers 553 | xmm0 = +181 554 | xmm1 = +300 555 | xmm2 = +0 556 | xmm3 = +0 557 | xmm4 = -5.486124068794e+303 558 | xmm5 = +0 559 | xmm6 = +180 560 | xmm7 = +180 561 | xmm8 = +0 562 | xmm9 = +0 563 | xmm10 = +0 564 | xmm11 = +0 565 | xmm12 = +3.2252605360517e-319 566 | xmm13 = +0 567 | xmm14 = +0 568 | xmm15 = +0 569 | 570 | ---- TRACE 2 exit 1 571 | General-purpose registers 572 | rax = 0x000000000bccff83 573 | rcx = 0x00007f5c3bfe1620 574 | rdx = 0x000000000000000a 575 | rbx = 0x00007f5c3bfec138 576 | rsp = 0x00007fffc278c790 577 | rbp = 0x00000000000000b6 578 | rsi = 0x00007f5c3b2a79e0 579 | rdi = 0x0000000000000001 580 | r8 = 0x000000000000000a 581 | r9 = 0x00007f5c3bffe780 582 | r10 = 0x00007f5c3bfe0c38 583 | r11 = 0x0000000000439ccf 584 | r12 = 0x0000000000405560 585 | r13 = 0x00007fffc278cb70 586 | r14 = 0x00007f5c3bfe03d8 587 | r15 = 0x00007f5c3bfec150 588 | Floating-point registers 589 | xmm0 = +182 590 | xmm1 = +300 591 | xmm2 = +0 592 | xmm3 = +0 593 | xmm4 = -5.486124068794e+303 594 | xmm5 = +0 595 | xmm6 = +180 596 | xmm7 = +181 597 | xmm8 = +0 598 | xmm9 = +0 599 | xmm10 = +0 600 | xmm11 = +0 601 | xmm12 = +3.2252605360517e-319 602 | xmm13 = +0 603 | xmm14 = +0 604 | xmm15 = +0 605 | 606 | ---- TRACE 2 exit 1 607 | General-purpose registers 608 | rax = 0x000000000bccff83 609 | rcx = 0x00007f5c3bfe1620 610 | rdx = 0x000000000000000a 611 | rbx = 0x00007f5c3bfec138 612 | rsp = 0x00007fffc278c790 613 | rbp = 0x00000000000000b7 614 | rsi = 0x00007f5c3b2a79e0 615 | rdi = 0x0000000000000001 616 | r8 = 0x000000000000000a 617 | r9 = 0x00007f5c3bffe780 618 | r10 = 0x00007f5c3bfe0c38 619 | r11 = 0x0000000000439ccf 620 | r12 = 0x0000000000405560 621 | r13 = 0x00007fffc278cb70 622 | r14 = 0x00007f5c3bfe03d8 623 | r15 = 0x00007f5c3bfec150 624 | Floating-point registers 625 | xmm0 = +183 626 | xmm1 = +300 627 | xmm2 = +0 628 | xmm3 = +0 629 | xmm4 = -5.486124068794e+303 630 | xmm5 = +0 631 | xmm6 = +180 632 | xmm7 = +182 633 | xmm8 = +0 634 | xmm9 = +0 635 | xmm10 = +0 636 | xmm11 = +0 637 | xmm12 = +3.2252605360517e-319 638 | xmm13 = +0 639 | xmm14 = +0 640 | xmm15 = +0 641 | 642 | ---- TRACE 2 exit 1 643 | General-purpose registers 644 | rax = 0x000000000bccff83 645 | rcx = 0x00007f5c3bfe1620 646 | rdx = 0x000000000000000a 647 | rbx = 0x00007f5c3bfec138 648 | rsp = 0x00007fffc278c790 649 | rbp = 0x00000000000000b8 650 | rsi = 0x00007f5c3b2a79e0 651 | rdi = 0x0000000000000001 652 | r8 = 0x000000000000000a 653 | r9 = 0x00007f5c3bffe780 654 | r10 = 0x00007f5c3bfe0c38 655 | r11 = 0x0000000000439ccf 656 | r12 = 0x0000000000405560 657 | r13 = 0x00007fffc278cb70 658 | r14 = 0x00007f5c3bfe03d8 659 | r15 = 0x00007f5c3bfec150 660 | Floating-point registers 661 | xmm0 = +184 662 | xmm1 = +300 663 | xmm2 = +0 664 | xmm3 = +0 665 | xmm4 = -5.486124068794e+303 666 | xmm5 = +0 667 | xmm6 = +180 668 | xmm7 = +183 669 | xmm8 = +0 670 | xmm9 = +0 671 | xmm10 = +0 672 | xmm11 = +0 673 | xmm12 = +3.2252605360517e-319 674 | xmm13 = +0 675 | xmm14 = +0 676 | xmm15 = +0 677 | 678 | ---- TRACE 2 exit 1 679 | General-purpose registers 680 | rax = 0x000000000bccff83 681 | rcx = 0x00007f5c3bfe1620 682 | rdx = 0x000000000000000a 683 | rbx = 0x00007f5c3bfec138 684 | rsp = 0x00007fffc278c790 685 | rbp = 0x00000000000000b9 686 | rsi = 0x00007f5c3b2a79e0 687 | rdi = 0x0000000000000001 688 | r8 = 0x000000000000000a 689 | r9 = 0x00007f5c3bffe780 690 | r10 = 0x00007f5c3bfe0c38 691 | r11 = 0x0000000000439ccf 692 | r12 = 0x0000000000405560 693 | r13 = 0x00007fffc278cb70 694 | r14 = 0x00007f5c3bfe03d8 695 | r15 = 0x00007f5c3bfec150 696 | Floating-point registers 697 | xmm0 = +185 698 | xmm1 = +300 699 | xmm2 = +0 700 | xmm3 = +0 701 | xmm4 = -5.486124068794e+303 702 | xmm5 = +0 703 | xmm6 = +180 704 | xmm7 = +184 705 | xmm8 = +0 706 | xmm9 = +0 707 | xmm10 = +0 708 | xmm11 = +0 709 | xmm12 = +3.2252605360517e-319 710 | xmm13 = +0 711 | xmm14 = +0 712 | xmm15 = +0 713 | 714 | ---- TRACE 2 exit 1 715 | General-purpose registers 716 | rax = 0x000000000bccff83 717 | rcx = 0x00007f5c3bfe1620 718 | rdx = 0x000000000000000a 719 | rbx = 0x00007f5c3bfec138 720 | rsp = 0x00007fffc278c790 721 | rbp = 0x00000000000000ba 722 | rsi = 0x00007f5c3b2a79e0 723 | rdi = 0x0000000000000001 724 | r8 = 0x000000000000000a 725 | r9 = 0x00007f5c3bffe780 726 | r10 = 0x00007f5c3bfe0c38 727 | r11 = 0x0000000000439ccf 728 | r12 = 0x0000000000405560 729 | r13 = 0x00007fffc278cb70 730 | r14 = 0x00007f5c3bfe03d8 731 | r15 = 0x00007f5c3bfec150 732 | Floating-point registers 733 | xmm0 = +186 734 | xmm1 = +300 735 | xmm2 = +0 736 | xmm3 = +0 737 | xmm4 = -5.486124068794e+303 738 | xmm5 = +0 739 | xmm6 = +180 740 | xmm7 = +185 741 | xmm8 = +0 742 | xmm9 = +0 743 | xmm10 = +0 744 | xmm11 = +0 745 | xmm12 = +3.2252605360517e-319 746 | xmm13 = +0 747 | xmm14 = +0 748 | xmm15 = +0 749 | 750 | ---- TRACE 2 exit 1 751 | General-purpose registers 752 | rax = 0x000000000bccff83 753 | rcx = 0x00007f5c3bfe1620 754 | rdx = 0x000000000000000a 755 | rbx = 0x00007f5c3bfec138 756 | rsp = 0x00007fffc278c790 757 | rbp = 0x00000000000000bb 758 | rsi = 0x00007f5c3b2a79e0 759 | rdi = 0x0000000000000001 760 | r8 = 0x000000000000000a 761 | r9 = 0x00007f5c3bffe780 762 | r10 = 0x00007f5c3bfe0c38 763 | r11 = 0x0000000000439ccf 764 | r12 = 0x0000000000405560 765 | r13 = 0x00007fffc278cb70 766 | r14 = 0x00007f5c3bfe03d8 767 | r15 = 0x00007f5c3bfec150 768 | Floating-point registers 769 | xmm0 = +187 770 | xmm1 = +300 771 | xmm2 = +0 772 | xmm3 = +0 773 | xmm4 = -5.486124068794e+303 774 | xmm5 = +0 775 | xmm6 = +180 776 | xmm7 = +186 777 | xmm8 = +0 778 | xmm9 = +0 779 | xmm10 = +0 780 | xmm11 = +0 781 | xmm12 = +3.2252605360517e-319 782 | xmm13 = +0 783 | xmm14 = +0 784 | xmm15 = +0 785 | 786 | ---- TRACE 2 exit 1 787 | General-purpose registers 788 | rax = 0x000000000bccff83 789 | rcx = 0x00007f5c3bfe1620 790 | rdx = 0x000000000000000a 791 | rbx = 0x00007f5c3bfec138 792 | rsp = 0x00007fffc278c790 793 | rbp = 0x00000000000000bc 794 | rsi = 0x00007f5c3b2a79e0 795 | rdi = 0x0000000000000001 796 | r8 = 0x000000000000000a 797 | r9 = 0x00007f5c3bffe780 798 | r10 = 0x00007f5c3bfe0c38 799 | r11 = 0x0000000000439ccf 800 | r12 = 0x0000000000405560 801 | r13 = 0x00007fffc278cb70 802 | r14 = 0x00007f5c3bfe03d8 803 | r15 = 0x00007f5c3bfec150 804 | Floating-point registers 805 | xmm0 = +188 806 | xmm1 = +300 807 | xmm2 = +0 808 | xmm3 = +0 809 | xmm4 = -5.486124068794e+303 810 | xmm5 = +0 811 | xmm6 = +180 812 | xmm7 = +187 813 | xmm8 = +0 814 | xmm9 = +0 815 | xmm10 = +0 816 | xmm11 = +0 817 | xmm12 = +3.2252605360517e-319 818 | xmm13 = +0 819 | xmm14 = +0 820 | xmm15 = +0 821 | 822 | ---- TRACE 2 exit 1 823 | General-purpose registers 824 | rax = 0x000000000bccff83 825 | rcx = 0x00007f5c3bfe1620 826 | rdx = 0x000000000000000a 827 | rbx = 0x00007f5c3bfec138 828 | rsp = 0x00007fffc278c790 829 | rbp = 0x00000000000000bd 830 | rsi = 0x00007f5c3b2a79e0 831 | rdi = 0x0000000000000001 832 | r8 = 0x000000000000000a 833 | r9 = 0x00007f5c3bffe780 834 | r10 = 0x00007f5c3bfe0c38 835 | r11 = 0x0000000000439ccf 836 | r12 = 0x0000000000405560 837 | r13 = 0x00007fffc278cb70 838 | r14 = 0x00007f5c3bfe03d8 839 | r15 = 0x00007f5c3bfec150 840 | Floating-point registers 841 | xmm0 = +189 842 | xmm1 = +300 843 | xmm2 = +0 844 | xmm3 = +0 845 | xmm4 = -5.486124068794e+303 846 | xmm5 = +0 847 | xmm6 = +180 848 | xmm7 = +188 849 | xmm8 = +0 850 | xmm9 = +0 851 | xmm10 = +0 852 | xmm11 = +0 853 | xmm12 = +3.2252605360517e-319 854 | xmm13 = +0 855 | xmm14 = +0 856 | xmm15 = +0 857 | 858 | ---- TRACE 3 start 2/1 =(command line):1 859 | 0016 GGET 5 0 ; "print" 860 | 0017 MOV 6 4 861 | 0018 CALL 5 1 2 862 | 0000 . FUNCC ; print 863 | ---- TRACE 3 IR 864 | 0001 rax int SLOAD #2 PI 865 | .... SNAP #0 [ ---- ---- 0001 ---- ---- 0001 ] 866 | 0002 [200] fun SLOAD #0 R 867 | 0003 rax tab FLOAD 0002 func.env 868 | 0004 [200] int FLOAD 0003 tab.hmask 869 | 0005 rax > int EQ 0004 +63 870 | 0006 [200] p32 FLOAD 0003 tab.node 871 | 0007 rax > p32 HREFK 0006 "print" @55 872 | 0008 rax > fun HLOAD 0007 873 | 0009 [200] > fun EQ 0008 print 874 | ---- TRACE 3 abort =(command line):1 -- NYI: FastFunc print 875 | 876 | ---- TRACE 2 exit 1 877 | General-purpose registers 878 | rax = 0x000000000bccff83 879 | rcx = 0x00007f5c3bfe1620 880 | rdx = 0x000000000000000a 881 | rbx = 0x00007f5c3bfec138 882 | rsp = 0x00007fffc278c790 883 | rbp = 0x00000000000000be 884 | rsi = 0x00007f5c3b2a79e0 885 | rdi = 0x0000000000000001 886 | r8 = 0x000000000000000a 887 | r9 = 0x00007f5c3bffe780 888 | r10 = 0x00007f5c3bfe0c38 889 | r11 = 0x0000000000439ccf 890 | r12 = 0x0000000000405560 891 | r13 = 0x00007fffc278cb70 892 | r14 = 0x00007f5c3bfe03d8 893 | r15 = 0x00007f5c3bfec150 894 | Floating-point registers 895 | xmm0 = +190 896 | xmm1 = +300 897 | xmm2 = +0 898 | xmm3 = +0 899 | xmm4 = -5.486124068794e+303 900 | xmm5 = +0 901 | xmm6 = +180 902 | xmm7 = +189 903 | xmm8 = +0 904 | xmm9 = +0 905 | xmm10 = +0 906 | xmm11 = +0 907 | xmm12 = +3.2252605360517e-319 908 | xmm13 = +0 909 | xmm14 = +0 910 | xmm15 = +0 911 | 912 | ---- TRACE 3 start 2/1 =(command line):1 913 | 0016 GGET 5 0 ; "print" 914 | 0017 MOV 6 4 915 | 0018 CALL 5 1 2 916 | 0000 . FUNCC ; print 917 | ---- TRACE 3 IR 918 | 0001 rax int SLOAD #2 PI 919 | .... SNAP #0 [ ---- ---- 0001 ---- ---- 0001 ] 920 | 0002 [200] fun SLOAD #0 R 921 | 0003 rax tab FLOAD 0002 func.env 922 | 0004 [200] int FLOAD 0003 tab.hmask 923 | 0005 rax > int EQ 0004 +63 924 | 0006 [200] p32 FLOAD 0003 tab.node 925 | 0007 rax > p32 HREFK 0006 "print" @55 926 | 0008 rax > fun HLOAD 0007 927 | 0009 [200] > fun EQ 0008 print 928 | ---- TRACE 3 abort =(command line):1 -- NYI: FastFunc print 929 | 930 | ---- TRACE 2 exit 1 931 | General-purpose registers 932 | rax = 0x000000000bccff83 933 | rcx = 0x00007f5c3bfe1620 934 | rdx = 0x000000000000000a 935 | rbx = 0x00007f5c3bfec138 936 | rsp = 0x00007fffc278c790 937 | rbp = 0x00000000000000bf 938 | rsi = 0x00007f5c3b2a79e0 939 | rdi = 0x0000000000000001 940 | r8 = 0x000000000000000a 941 | r9 = 0x00007f5c3bffe780 942 | r10 = 0x00007f5c3bfe0c38 943 | r11 = 0x0000000000439ccf 944 | r12 = 0x0000000000405560 945 | r13 = 0x00007fffc278cb70 946 | r14 = 0x00007f5c3bfe03d8 947 | r15 = 0x00007f5c3bfec150 948 | Floating-point registers 949 | xmm0 = +191 950 | xmm1 = +300 951 | xmm2 = +0 952 | xmm3 = +0 953 | xmm4 = -5.486124068794e+303 954 | xmm5 = +0 955 | xmm6 = +180 956 | xmm7 = +190 957 | xmm8 = +0 958 | xmm9 = +0 959 | xmm10 = +0 960 | xmm11 = +0 961 | xmm12 = +3.2252605360517e-319 962 | xmm13 = +0 963 | xmm14 = +0 964 | xmm15 = +0 965 | 966 | ---- TRACE 3 start 2/1 =(command line):1 967 | 0016 GGET 5 0 ; "print" 968 | 0017 MOV 6 4 969 | 0018 CALL 5 1 2 970 | 0000 . FUNCC ; print 971 | ---- TRACE 3 IR 972 | 0001 rax int SLOAD #2 PI 973 | .... SNAP #0 [ ---- ---- 0001 ---- ---- 0001 ] 974 | 0002 [200] fun SLOAD #0 R 975 | 0003 rax tab FLOAD 0002 func.env 976 | 0004 [200] int FLOAD 0003 tab.hmask 977 | 0005 rax > int EQ 0004 +63 978 | 0006 [200] p32 FLOAD 0003 tab.node 979 | 0007 rax > p32 HREFK 0006 "print" @55 980 | 0008 rax > fun HLOAD 0007 981 | 0009 [200] > fun EQ 0008 print 982 | ---- TRACE 3 abort =(command line):1 -- NYI: FastFunc print 983 | 984 | ---- TRACE 2 exit 1 985 | General-purpose registers 986 | rax = 0x000000000bccff83 987 | rcx = 0x00007f5c3bfe1620 988 | rdx = 0x000000000000000a 989 | rbx = 0x00007f5c3bfec138 990 | rsp = 0x00007fffc278c790 991 | rbp = 0x00000000000000c0 992 | rsi = 0x00007f5c3b2a79e0 993 | rdi = 0x0000000000000001 994 | r8 = 0x000000000000000a 995 | r9 = 0x00007f5c3bffe780 996 | r10 = 0x00007f5c3bfe0c38 997 | r11 = 0x0000000000439ccf 998 | r12 = 0x0000000000405560 999 | r13 = 0x00007fffc278cb70 1000 | r14 = 0x00007f5c3bfe03d8 1001 | r15 = 0x00007f5c3bfec150 1002 | Floating-point registers 1003 | xmm0 = +192 1004 | xmm1 = +300 1005 | xmm2 = +0 1006 | xmm3 = +0 1007 | xmm4 = -5.486124068794e+303 1008 | xmm5 = +0 1009 | xmm6 = +180 1010 | xmm7 = +191 1011 | xmm8 = +0 1012 | xmm9 = +0 1013 | xmm10 = +0 1014 | xmm11 = +0 1015 | xmm12 = +3.2252605360517e-319 1016 | xmm13 = +0 1017 | xmm14 = +0 1018 | xmm15 = +0 1019 | 1020 | ---- TRACE 3 start 2/1 =(command line):1 1021 | 0016 GGET 5 0 ; "print" 1022 | 0017 MOV 6 4 1023 | 0018 CALL 5 1 2 1024 | 0000 . FUNCC ; print 1025 | ---- TRACE 3 IR 1026 | 0001 rax int SLOAD #2 PI 1027 | .... SNAP #0 [ ---- ---- 0001 ---- ---- 0001 ] 1028 | 0002 [200] fun SLOAD #0 R 1029 | 0003 rax tab FLOAD 0002 func.env 1030 | 0004 [200] int FLOAD 0003 tab.hmask 1031 | 0005 rax > int EQ 0004 +63 1032 | 0006 [200] p32 FLOAD 0003 tab.node 1033 | 0007 rax > p32 HREFK 0006 "print" @55 1034 | 0008 rax > fun HLOAD 0007 1035 | 0009 [200] > fun EQ 0008 print 1036 | ---- TRACE 3 abort =(command line):1 -- NYI: FastFunc print 1037 | 1038 | ---- TRACE 2 exit 1 1039 | General-purpose registers 1040 | rax = 0x000000000bccff83 1041 | rcx = 0x00007f5c3bfe1620 1042 | rdx = 0x000000000000000a 1043 | rbx = 0x00007f5c3bfec138 1044 | rsp = 0x00007fffc278c790 1045 | rbp = 0x00000000000000c1 1046 | rsi = 0x00007f5c3b2a79e0 1047 | rdi = 0x0000000000000001 1048 | r8 = 0x000000000000000a 1049 | r9 = 0x00007f5c3bffe780 1050 | r10 = 0x00007f5c3bfe0c38 1051 | r11 = 0x0000000000439ccf 1052 | r12 = 0x0000000000405560 1053 | r13 = 0x00007fffc278cb70 1054 | r14 = 0x00007f5c3bfe03d8 1055 | r15 = 0x00007f5c3bfec150 1056 | Floating-point registers 1057 | xmm0 = +193 1058 | xmm1 = +300 1059 | xmm2 = +0 1060 | xmm3 = +0 1061 | xmm4 = -5.486124068794e+303 1062 | xmm5 = +0 1063 | xmm6 = +180 1064 | xmm7 = +192 1065 | xmm8 = +0 1066 | xmm9 = +0 1067 | xmm10 = +0 1068 | xmm11 = +0 1069 | xmm12 = +3.2252605360517e-319 1070 | xmm13 = +0 1071 | xmm14 = +0 1072 | xmm15 = +0 1073 | 1074 | ---- TRACE 3 start 2/1 =(command line):1 1075 | ---- TRACE 3 IR 1076 | 0001 rbp int SLOAD #2 PI 1077 | .... SNAP #0 [ ---- ---- 0001 ---- ---- 0001 ] 1078 | 0002 xmm7 flt CONV 0001 flt.int 1079 | .... SNAP #1 [ ---- ---- 0002 ---- ---- 0002 ] 1080 | ---- TRACE 3 mcode 79 1081 | 0bccfea7 mov r11, 0x7f5c3bfde608 1082 | 0bccfeb1 mov dword [r11], 0x3 1083 | 0bccfeb8 xorps xmm7, xmm7 1084 | 0bccfebb cvtsi2sd xmm7, ebp 1085 | 0bccfebf mov dword [r10+0x48], 0xfffffff2 1086 | 0bccfec7 movsd [r10+0x40], xmm7 1087 | 0bccfecd mov dword [r10+0x18], 0xfffffff2 1088 | 0bccfed5 movsd [r10+0x10], xmm7 1089 | 0bccfedb xor eax, eax 1090 | 0bccfedd mov rbx, 0x7f5c3bfec128 1091 | 0bccfee7 mov r14, 0x7f5c3bfe03d8 1092 | 0bccfef1 jmp 0x439dcc 1093 | ---- TRACE 3 stop -> interpreter 1094 | 1095 | -------------------------------------------------------------------------------- /tests/test_cli.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # This file is a part of the testing suite for dumpanalyze. 4 | # 5 | # Copyright 2017-2019 IPONWEB Ltd. 6 | # 7 | 8 | import sys 9 | import os 10 | import subprocess 11 | import shutil 12 | import tempfile 13 | 14 | CLI_NAME = "dumpanalyze" 15 | DATA_DIR = os.path.join( 16 | os.path.abspath(os.path.dirname(__file__)), "dump-files" 17 | ) 18 | DUMP_FNAME = "test_cli.txt" 19 | DUMP_FPATH = os.path.join(DATA_DIR, DUMP_FNAME) 20 | 21 | 22 | def _prepare_cli_run(params): 23 | params.insert(0, sys.executable) 24 | command = " ".join(params) 25 | return subprocess.Popen( 26 | command, 27 | shell=True, 28 | stdout=subprocess.PIPE, 29 | stderr=subprocess.PIPE, 30 | universal_newlines=True, 31 | ) 32 | 33 | 34 | def test_help(): 35 | process = _prepare_cli_run([CLI_NAME, "-h"]) 36 | out, err = process.communicate() 37 | assert process.returncode == 0 38 | assert " --help " in out 39 | assert " --dump " in out 40 | assert " --out-dir " in out 41 | 42 | 43 | def test_bad_dump_path(): 44 | with tempfile.TemporaryDirectory() as tmpdir: 45 | assert not os.path.isfile(tmpdir) 46 | process = _prepare_cli_run([CLI_NAME, "--dump", tmpdir]) 47 | out, err = process.communicate() 48 | assert process.returncode != 0 49 | assert "Bad dump file name " in err 50 | 51 | 52 | def _assert_view_traces_csv_1(fname): 53 | assert os.path.isfile(fname) 54 | data = list(open(fname)) 55 | assert len(data) == 1 56 | assert "ID,PARENT,LINK_TYPE,NUM_BC,NUM_IR,NUM_SN,SIZE_MC\n" in data 57 | 58 | 59 | def _assert_view_traces_csv_2(fname): 60 | assert os.path.isfile(fname) 61 | data = open(fname).read() 62 | assert "1,0,loop,5,15,7,113" in data 63 | assert "2,1,1,5,8,5,127" in data 64 | assert "3,2,interpreter,0,2,2,79" in data 65 | 66 | 67 | def _assert_view_abort_reasons_csv_1(fname): 68 | assert os.path.isfile(fname) 69 | data = open(fname).read() 70 | assert "failed to allocate mcode memory,1" in data 71 | 72 | 73 | def _assert_view_abort_reasons_csv_2(fname): 74 | assert os.path.isfile(fname) 75 | data = open(fname).read() 76 | assert "NYI: FastFunc print,4" in data 77 | 78 | 79 | def _assert_view_abort_reasons_txt_1(fname): 80 | assert os.path.isfile(fname) 81 | data = open(fname).read() 82 | assert "failed to allocate mcode memory: 1" in data 83 | 84 | 85 | def _assert_view_abort_reasons_txt_2(fname): 86 | assert os.path.isfile(fname) 87 | data = open(fname).read() 88 | assert "NYI: FastFunc print: 4" in data 89 | 90 | 91 | # A single trace bush is rendered in the same txt format as the original dump. 92 | def _assert_view_tracebush_txt(fname): 93 | from dumpanalyze.dumpparser import DumpParser 94 | from dumpanalyze.trace import Trace 95 | 96 | assert os.path.isfile(fname) 97 | 98 | parser = DumpParser(fname) 99 | assert isinstance(parser, DumpParser) 100 | 101 | assert parser.parse() == DumpParser.PARSED_DUMP 102 | 103 | assert isinstance(parser.traces, list) 104 | assert isinstance(parser.abort_reasons, list) 105 | 106 | assert len(parser.traces) == 3 107 | assert len(parser.abort_reasons) == 0 108 | 109 | root_trace = parser.traces[0] 110 | assert isinstance(root_trace, Trace) 111 | assert root_trace.id == 1 112 | assert root_trace.parent_id == 0 113 | assert root_trace.parent_side == 0 114 | assert root_trace.parent == "" 115 | assert root_trace.is_root 116 | assert root_trace.file == "=(command line)" 117 | assert root_trace.line == 1 118 | assert root_trace.link_type == "loop" 119 | assert root_trace.num_bc == 5 120 | assert root_trace.num_ir == 15 121 | assert root_trace.num_sn == 7 122 | assert root_trace.size_mcode == 113 123 | 124 | side_trace = parser.traces[1] 125 | assert isinstance(side_trace, Trace) 126 | assert side_trace.id == 2 127 | assert side_trace.parent_id == 1 128 | assert side_trace.parent_side == 1 129 | assert side_trace.parent == "1/1" 130 | assert not side_trace.is_root 131 | assert side_trace.file == "=(command line)" 132 | assert side_trace.line == 1 133 | assert side_trace.link_type == str(root_trace.id) 134 | assert side_trace.num_bc == 5 135 | assert side_trace.num_ir == 8 136 | assert side_trace.num_sn == 5 137 | assert side_trace.size_mcode == 127 138 | 139 | stub_trace = parser.traces[2] 140 | assert isinstance(stub_trace, Trace) 141 | assert stub_trace.id == 3 142 | assert stub_trace.parent_id == 2 143 | assert stub_trace.parent_side == 1 144 | assert stub_trace.parent == "2/1" 145 | assert not stub_trace.is_root 146 | assert stub_trace.file == "=(command line)" 147 | assert stub_trace.line == 1 148 | assert stub_trace.link_type == "interpreter" 149 | assert stub_trace.num_bc == 0 150 | assert stub_trace.num_ir == 2 151 | assert stub_trace.num_sn == 2 152 | assert stub_trace.size_mcode == 79 153 | 154 | 155 | def test_normal_run(): 156 | with tempfile.TemporaryDirectory() as tmpdir: 157 | dump_fname = os.path.join(tmpdir, DUMP_FNAME) 158 | out_dir = dump_fname + "-parsed" 159 | 160 | shutil.copy(DUMP_FPATH, tmpdir) 161 | process = _prepare_cli_run([CLI_NAME, "--dump", dump_fname]) 162 | __, __ = process.communicate() 163 | assert process.returncode == 0 164 | assert os.path.isdir(out_dir) 165 | 166 | fname_traces = os.path.join(out_dir, "gen-1-traces.csv") 167 | fname_reasons_csv = os.path.join(out_dir, "gen-1-abort-reasons.csv") 168 | fname_reasons_txt = os.path.join(out_dir, "gen-1-abort-reasons.txt") 169 | 170 | _assert_view_traces_csv_1(fname_traces) 171 | _assert_view_abort_reasons_csv_1(fname_reasons_csv) 172 | _assert_view_abort_reasons_txt_1(fname_reasons_txt) 173 | 174 | assert not os.path.isfile(os.path.join(out_dir, "gen-1-bush-1.txt")) 175 | assert not os.path.isfile(os.path.join(out_dir, "gen-1-bush-1.png")) 176 | 177 | fname_traces = os.path.join(out_dir, "gen-2-traces.csv") 178 | fname_reasons_csv = os.path.join(out_dir, "gen-2-abort-reasons.csv") 179 | fname_reasons_txt = os.path.join(out_dir, "gen-2-abort-reasons.txt") 180 | fname_tracebush = os.path.join(out_dir, "gen-2-bush-1.txt") 181 | 182 | _assert_view_traces_csv_2(fname_traces) 183 | _assert_view_abort_reasons_csv_2(fname_reasons_csv) 184 | _assert_view_abort_reasons_txt_2(fname_reasons_txt) 185 | _assert_view_tracebush_txt(fname_tracebush) 186 | 187 | assert os.path.isfile(os.path.join(out_dir, "gen-2-bush-1.png")) 188 | -------------------------------------------------------------------------------- /tests/test_objects.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # This file is a part of the testing suite for dumpanalyze. 4 | # 5 | # Copyright 2017-2019 IPONWEB Ltd. 6 | # 7 | 8 | import os 9 | 10 | from dumpanalyze.dumpparser import DumpParser 11 | from dumpanalyze.trace import Trace 12 | from dumpanalyze.tracebush import TraceBush 13 | from dumpanalyze.traceforest import TraceForest 14 | from dumpanalyze.abortreason import AbortReason 15 | 16 | DATA_DIR = os.path.join( 17 | os.path.abspath(os.path.dirname(__file__)), "dump-files" 18 | ) 19 | DUMP_FNAME = os.path.join(DATA_DIR, "test_objects.txt") 20 | 21 | 22 | def test_parser(): 23 | parser = DumpParser(DUMP_FNAME) 24 | assert isinstance(parser, DumpParser) 25 | 26 | assert parser.parse() == DumpParser.PARSED_DUMP 27 | 28 | assert isinstance(parser.traces, list) 29 | assert isinstance(parser.abort_reasons, list) 30 | 31 | assert len(parser.traces) == 3 32 | assert len(parser.abort_reasons) == 4 33 | 34 | 35 | def test_traces(): 36 | parser = DumpParser(DUMP_FNAME) 37 | parser.parse() 38 | 39 | root_trace = parser.traces[0] 40 | assert isinstance(root_trace, Trace) 41 | assert root_trace.id == 1 42 | assert root_trace.parent_id == 0 43 | assert root_trace.parent_side == 0 44 | assert root_trace.parent == "" 45 | assert root_trace.is_root 46 | assert root_trace.file == "=(command line)" 47 | assert root_trace.line == 1 48 | assert root_trace.link_type == "loop" 49 | assert root_trace.num_bc == 5 50 | assert root_trace.num_ir == 15 51 | assert root_trace.num_sn == 7 52 | assert root_trace.size_mcode == 113 53 | 54 | side_trace = parser.traces[1] 55 | assert isinstance(side_trace, Trace) 56 | assert side_trace.id == 2 57 | assert side_trace.parent_id == 1 58 | assert side_trace.parent_side == 1 59 | assert side_trace.parent == "1/1" 60 | assert not side_trace.is_root 61 | assert side_trace.file == "=(command line)" 62 | assert side_trace.line == 1 63 | assert side_trace.link_type == str(root_trace.id) 64 | assert side_trace.num_bc == 5 65 | assert side_trace.num_ir == 8 66 | assert side_trace.num_sn == 5 67 | assert side_trace.size_mcode == 127 68 | 69 | stub_trace = parser.traces[2] 70 | assert isinstance(stub_trace, Trace) 71 | assert stub_trace.id == 3 72 | assert stub_trace.parent_id == 2 73 | assert stub_trace.parent_side == 1 74 | assert stub_trace.parent == "2/1" 75 | assert not stub_trace.is_root 76 | assert stub_trace.file == "=(command line)" 77 | assert stub_trace.line == 1 78 | assert stub_trace.link_type == "interpreter" 79 | assert stub_trace.num_bc == 0 80 | assert stub_trace.num_ir == 2 81 | assert stub_trace.num_sn == 2 82 | assert stub_trace.size_mcode == 79 83 | 84 | 85 | # Testing bushes and forests withing a single test 86 | def test_trace_grouping(): 87 | parser = DumpParser(DUMP_FNAME) 88 | parser.parse() 89 | 90 | forest = TraceForest(parser.traces) 91 | assert isinstance(forest, TraceForest) 92 | assert isinstance(forest.bushes, dict) 93 | assert len(forest.bushes) == 1 94 | 95 | bush = forest.bushes[1] 96 | assert isinstance(bush, TraceBush) 97 | assert bush.root_id == 1 98 | assert bush.size == 3 99 | assert isinstance(bush.traces, list) 100 | 101 | 102 | def test_abort_reason(): 103 | parser = DumpParser(DUMP_FNAME) 104 | parser.parse() 105 | 106 | abort_reason = parser.abort_reasons[0] 107 | assert isinstance(abort_reason, AbortReason) 108 | assert abort_reason.file == "=(command line)" 109 | assert abort_reason.line == 1 110 | assert abort_reason.reason == "NYI: FastFunc print" 111 | --------------------------------------------------------------------------------