def read_source_code(ctx, trace, fileobj): filename = read_string(fileobj, True) count = read_le_u16(fileobj) for i in range(count): lineno = read_le_u16(fileobj) indent = read_byte(fileobj) text = read_string(fileobj, True) ctx.forest.add_source_code_line(filename, lineno, indent, text)
def read_start_trace(ctx, trace, fileobj): trace_id = ctx.read_le_addr(fileobj) trace_type = read_string(fileobj, True) trace_nmr = ctx.read_le_addr(fileobj) # version 2 adds the jitdriver name if ctx.forest.version >= 2: jd_name = read_string(fileobj, True) else: jd_name= None # assert trace_id not in ctx.forest.traces ctx.forest.add_trace(trace_type, trace_id, trace_nmr, jd_name)
def read_start_trace(ctx, trace, fileobj): trace_id = ctx.read_le_addr(fileobj) trace_type = read_string(fileobj, True) trace_nmr = ctx.read_le_addr(fileobj) # version 2 adds the jitdriver name if ctx.forest.version >= 2: jd_name = read_string(fileobj, True) else: jd_name = None # assert trace_id not in ctx.forest.traces ctx.forest.add_trace(trace_type, trace_id, trace_nmr, jd_name)
def read_resop(ctx, trace, fileobj): assert trace is not None opnum = read_le_u16(fileobj) args = read_string(fileobj, True).split(',') failargs = None if 2 <= ctx.forest.version: failargs = read_string(fileobj, True).split(',') result = args[0] args = args[1:] assert opnum in ctx.forest.resops, "opnum is not known: " + str(opnum) + \ " at binary pos " + str(hex(fileobj.tell())) opname = ctx.forest.resops[opnum] op = FlatOp(opnum, opname, args, result, None, -1, failargs=failargs) trace.add_instr(op)
def read_one_marker(fileobj, status, buffer_so_far=None): fileobj = FileObjWrapper(fileobj, buffer_so_far) marker = fileobj.read(1) if marker == MARKER_STACKTRACE: count = read_word(fileobj) # for now assert count == 1 depth = read_word(fileobj) assert depth <= 2**16, 'stack strace depth too high' trace = read_trace(fileobj, depth, status.version, status.profile_lines) if status.version >= VERSION_THREAD_ID: thread_id, = struct.unpack('l', fileobj.read(WORD_SIZE)) else: thread_id = 0 if status.profile_memory: mem_in_kb, = struct.unpack('l', fileobj.read(WORD_SIZE)) else: mem_in_kb = 0 trace.reverse() status.profiles.append((trace, 1, thread_id, mem_in_kb)) elif marker == MARKER_VIRTUAL_IP: unique_id = read_word(fileobj) name = read_string(fileobj) if PY3: name = name.decode() status.virtual_ips[unique_id] = name elif marker == MARKER_TRAILER: return True # finished else: raise FileReadError("unexpected marker: %d" % ord(marker)) return False
def read_resop(ctx, trace, fileobj): assert trace is not None opnum = read_le_u16(fileobj) args = read_string(fileobj, True).split(",") failargs = None if 2 <= ctx.forest.version: failargs = read_string(fileobj, True).split(",") result = args[0] args = args[1:] assert opnum in ctx.forest.resops, ( "opnum is not known: " + str(opnum) + " at binary pos " + str(hex(fileobj.tell())) ) opname = ctx.forest.resops[opnum] op = FlatOp(opnum, opname, args, result, None, -1, failargs=failargs) trace.add_instr(op)
def read_resop_meta(ctx, trace, fileobj): assert len(ctx.forest.resops) == 0 count = read_le_u16(fileobj) for i in range(count): opnum = read_le_u16(fileobj) opname = read_string(fileobj, True) ctx.forest.resops[opnum] = opname
def decode(self, fileobj): type = fileobj.read(1) if type == b'\xef': return self.last_prefix[:] string = read_string(fileobj, True) if type == b'\x00': return self.last_prefix + string else: assert type == b'\xff' return string
def _parse_jitlog(fileobj): """ JitLog is parsed. if an exception is raised after the header has been read, it is saved in the field 'exc' on the forest returned. This allows to parse an incomplete log file an still display everything that was readable! If a ParseException is directly raised, this is an error that cannot be recovered from! """ try: is_jit_log = fileobj.read(1) == const.MARK_JITLOG_HEADER version = ord(fileobj.read(1)) | (ord(fileobj.read(1)) << 8) is_32bit = ord(fileobj.read(1)) machine = read_string(fileobj, True) forest = TraceForest(version, is_32bit, machine) ctx = ParseContext(forest) except Exception: raise ParseException("Header malformed") # if not is_jit_log: raise ParseException("Missing header. Provided input might not be a jitlog!") if version < JITLOG_MIN_VERSION: raise ParseException("Version %d is not supported" % version) while True: marker = fileobj.read(1) if len(marker) == 0: break # end of file! if not forest.is_jitlog_marker(marker): msg = "marker unknown: 0x%x at pos 0x%x" % \ (ord(marker), fileobj.tell()) forest.exc = ParseException(msg) break trace = forest.last_trace try: read = marks.get_reader(version, marker) read(ctx, trace, fileobj) forest.time_tick() except KeyError as e: forest.exc = e break except ParseException as e: forest.exc = e break except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() tb = traceback.extract_tb(exc_traceback, limit=3) msg = "failed at 0x%x with marker %s with exc \"%s\". trace back: \"%s\"" %\ (fileobj.tell(), marker, str(e), tb) forest.exc = ParseException(msg) break return forest
def read_one_marker(fileobj, status, buffer_so_far=None): fileobj = FileObjWrapper(fileobj, buffer_so_far) marker = fileobj.read(1) if marker == MARKER_STACKTRACE: count = read_word(fileobj) # for now assert count == 1 depth = read_word(fileobj) assert depth <= 2**16, 'stack strace depth too high' trace = read_trace(fileobj, depth, status.version, status.profile_lines) if status.version >= VERSION_THREAD_ID: thread_id = read_addr(fileobj) else: thread_id = 0 if status.profile_memory: mem_in_kb = read_addr(fileobj) else: mem_in_kb = 0 trace.reverse() status.profiles.append((trace, 1, thread_id, mem_in_kb)) elif marker == MARKER_VIRTUAL_IP or marker == MARKER_NATIVE_SYMBOLS: unique_id = read_addr(fileobj) name = read_string(fileobj) if PY3K: name = name.decode() status.virtual_ips[unique_id] = name elif marker == MARKER_META: read_string(fileobj) read_string(fileobj) # TODO save the for the tests? elif marker == MARKER_TRAILER: return True # finished elif marker == MARKER_TIME_N_ZONE: read_time_and_zone(fileobj) else: raise FileReadError("unexpected marker: %d" % ord(marker)) return False
def read_common_prefix(ctx, trace, fileobj): index = ord(fileobj.read(1)) prefix = read_string(fileobj, True) stage = trace.get_last_stage() stage.merge_point_types[index].set_prefix(prefix)
def read_input_args(ctx, trace, fileobj): assert trace is not None argnames = read_string(fileobj, True).split(",") trace.set_inputargs(argnames)
def read_input_args(ctx, trace, fileobj): assert trace is not None argnames = read_string(fileobj, True).split(',') trace.set_inputargs(argnames)
def read_prof(fileobj, virtual_ips_only=False): fileobj = gunzip(fileobj) assert read_word(fileobj) == 0 # header count assert read_word(fileobj) == 3 # header size assert read_word(fileobj) == 0 period = read_word(fileobj) assert read_word(fileobj) == 0 virtual_ips = [] profiles = [] interp_name = None version = 0 profile_memory = False profile_lines = False while True: marker = fileobj.read(1) if marker == MARKER_HEADER: assert not version, "multiple headers" version, = struct.unpack("!h", fileobj.read(2)) if version >= VERSION_MODE_AWARE: mode = ord(fileobj.read(1)) profile_memory = (mode & PROFILE_MEMORY) != 0 profile_lines = (mode & PROFILE_LINES) != 0 else: profile_memory = version == VERSION_MEMORY profile_lines = False lgt = ord(fileobj.read(1)) interp_name = fileobj.read(lgt) if PY3: interp_name = interp_name.decode() elif marker == MARKER_STACKTRACE: count = read_word(fileobj) # for now assert count == 1 depth = read_word(fileobj) assert depth <= 2**16, 'stack strace depth too high' if virtual_ips_only: fileobj.read(WORD_SIZE * depth) trace = [] else: trace = read_trace(fileobj, depth, version, profile_lines) if version >= VERSION_THREAD_ID: thread_id, = struct.unpack('l', fileobj.read(WORD_SIZE)) else: thread_id = 0 if profile_memory: mem_in_kb, = struct.unpack('l', fileobj.read(WORD_SIZE)) else: mem_in_kb = 0 trace.reverse() profiles.append((trace, 1, thread_id, mem_in_kb)) elif marker == MARKER_INTERP_NAME: assert not version, "multiple headers" assert not interp_name, "Dual interpreter name header" lgt = ord(fileobj.read(1)) interp_name = fileobj.read(lgt) if PY3: interp_name = interp_name.decode() elif marker == MARKER_VIRTUAL_IP: unique_id = read_word(fileobj) name = read_string(fileobj) if PY3: name = name.decode() virtual_ips.append((unique_id, name)) elif marker == MARKER_TRAILER: #if not virtual_ips_only: # symmap = read_ranges(fileobj.read()) break else: assert not marker, (fileobj.tell(), repr(marker)) break virtual_ips.sort() # I think it's sorted, but who knows if virtual_ips_only: return virtual_ips return period, profiles, virtual_ips, interp_name