def finished_reading_profile(self): import _vmprof if not hasattr(_vmprof, 'resolve_addr'): # windows does not implement that! return resolve_addr = _vmprof.resolve_addr from _vmprof import resolve_addr LogReader.finished_reading_profile(self) if len(self.dedup) == 0: return self.fileobj.seek(0, os.SEEK_END) # must match '<lang>:<name>:<line>:<file>' # 'n' has been chosen as lang here, because the symbol # can be generated from several languages (e.g. C, C++, ...) for addr in self.dedup: bytelist = [b"\x08"] result = resolve_addr(addr) if result is None: name, lineno, srcfile = None, 0, None else: name, lineno, srcfile = result if not name: name = "<native symbol 0x%x>" % addr if not srcfile: srcfile = "-" string = "n:%s:%d:%s" % (name, lineno, srcfile) bytestring = string.encode('utf-8') bytelist.append(struct.pack("P", addr)) bytelist.append(struct.pack("l", len(bytestring))) bytelist.append(bytestring) self.fileobj.write(b"".join(bytelist))
def dump_native_symbols(fileno): # native symbols cannot be resolved in the signal handler. # it would take far too long. Thus this method should be called # just after the sampling finished and before the file descriptor # is closed. # called from C with the fileno that has been used for this profile # duplicates are avoided if this function is only called once for a profile fileobj = io.open(fileno, mode='rb', closefd=False) fileobj.seek(0) _, profiles, _, _, _, _, _ = read_prof(fileobj) duplicates = set() fileobj = io.open(fileno, mode='ab', closefd=False) for profile in profiles: addrs = profile[0] for addr in addrs: if addr in duplicates: continue duplicates.add(addr) if addr & 0x1 and addr > 1: name, lineno, srcfile = _vmprof.resolve_addr(addr) if name == "" and srcfile == '-': name = "<native symbol 0x%x>" % addr str = "n:%s:%d:%s" % (name, lineno, srcfile) if PY3: str = str.encode() out = [ MARKER_NATIVE_SYMBOLS, struct.pack("l", addr), struct.pack("l", len(str)), str ] fileobj.write(b''.join(out))
def finished_reading_profile(self): import _vmprof if not hasattr(_vmprof, 'resolve_addr'): # windows does not implement that! return resolve_addr = _vmprof.resolve_addr from _vmprof import resolve_addr LogReader.finished_reading_profile(self) if len(self.dedup) == 0: return self.fileobj.seek(0, os.SEEK_END) # must match '<lang>:<name>:<line>:<file>' # 'n' has been chosen as lang here, because the symbol # can be generated from several languages (e.g. C, C++, ...) for addr in self.dedup: bytelist = [b"\x08"] result = resolve_addr(addr) if result is None: name, lineno, srcfile = None, 0, None else: name, lineno, srcfile = result if not name: name = "<native symbol 0x%x>" % addr if not srcfile: srcfile = "-" string = "n:%s:%d:%s" % (name, lineno, srcfile) bytestring = string.encode('utf-8') bytelist.append(struct.pack("P", addr)) bytelist.append(struct.pack("l", len(bytestring))) bytelist.append(bytestring) self.fileobj.write(b"".join(bytelist))
def resolve_addr(addr): """ Private API, returns the symbol name of the given address. Only considers linking symbols found by dladdr. """ return _vmprof.resolve_addr(addr)