def dump_info(self, pinfo, take_dump): """Dump info.""" debugger = "lldb" dbg = self._find_debugger(debugger) logger = _get_process_logger(self._dbg_output, pinfo.name) if dbg is None: self._root_logger.warning( "Debugger %s not found, skipping dumping of %s", debugger, str(pinfo.pidv)) return self._root_logger.info( "Debugger %s, analyzing %s processes with PIDs %s", dbg, pinfo.name, str(pinfo.pidv)) lldb_version = callo([dbg, "--version"], logger) logger.info(lldb_version) # Do we have the XCode or LLVM version of lldb? # Old versions of lldb do not work well when taking commands via a file # XCode (7.2): lldb-340.4.119 # LLVM - lldb version 3.7.0 ( revision ) if 'version' not in lldb_version: # We have XCode's lldb lldb_version = lldb_version[lldb_version.index("lldb-"):] lldb_version = lldb_version.replace('lldb-', '') lldb_major_version = int(lldb_version[:lldb_version.index('.')]) if lldb_major_version < 340: logger.warning( "Debugger lldb is too old, please upgrade to XCode 7.2") return cmds = self._process_specific(pinfo, take_dump) + self._postfix() tf = tempfile.NamedTemporaryFile(mode='w', encoding='utf-8') for cmd in cmds: tf.write(cmd + "\n") tf.flush() # Works on in MacOS 10.9 & later #call([dbg] + list( itertools.chain.from_iterable([['-o', b] for b in cmds])), logger) call(['cat', tf.name], logger) call([dbg, '--source', tf.name], logger) self._root_logger.info("Done analyzing %s processes with PIDs %s", pinfo.name, str(pinfo.pidv)) if take_dump: need_sigabrt = {} files = self._dump_files(pinfo) for pid in files: if not os.path.exists(files[pid]): need_sigabrt[pid] = files[pid] if need_sigabrt: raise DumpError(need_sigabrt)
def dump_processes(self, logger): """Get list of [Pid, Process Name].""" ps = self.__find_ps() logger.info("Getting list of processes using %s", ps) ret = callo([ps, "/FO", "CSV"], logger) buff = io.StringIO(ret) csv_reader = csv.reader(buff) return [[int(row[1]), row[0]] for row in csv_reader if row[1] != "PID"]
def dump_processes(self, logger): """Get list of [Pid, Process Name].""" ps = self.__find_ps() logger.info("Getting list of processes using %s", ps) ret = callo([ps, "-axco", "pid,comm"], logger) buff = io.StringIO(ret) csv_reader = csv.reader(buff, delimiter=' ', quoting=csv.QUOTE_NONE, skipinitialspace=True) return [[int(row[0]), row[1]] for row in csv_reader if row[0] != "PID"]
def dump_info( # pylint: disable=too-many-arguments,too-many-locals self, root_logger, logger, pinfo, take_dump): """Dump info.""" debugger = "lldb" dbg = self.__find_debugger(debugger) if dbg is None: root_logger.warning("Debugger %s not found, skipping dumping of %d", debugger, pinfo.pid) return root_logger.info("Debugger %s, analyzing %s process with PID %d", dbg, pinfo.name, pinfo.pid) lldb_version = callo([dbg, "--version"], logger) logger.info(lldb_version) # Do we have the XCode or LLVM version of lldb? # Old versions of lldb do not work well when taking commands via a file # XCode (7.2): lldb-340.4.119 # LLVM - lldb version 3.7.0 ( revision ) if 'version' not in lldb_version: # We have XCode's lldb lldb_version = lldb_version[lldb_version.index("lldb-"):] lldb_version = lldb_version.replace('lldb-', '') lldb_major_version = int(lldb_version[:lldb_version.index('.')]) if lldb_major_version < 340: logger.warning("Debugger lldb is too old, please upgrade to XCode 7.2") return dump_command = "" if take_dump: # Dump to file, dump_<process name>.<pid>.core dump_file = "dump_%s.%d.%s" % (pinfo.name, pinfo.pid, self.get_dump_ext()) dump_command = "process save-core %s" % dump_file root_logger.info("Dumping core to %s", dump_file) cmds = [ "attach -p %d" % pinfo.pid, "target modules list", "thread backtrace all", dump_command, "settings set interpreter.prompt-on-quit false", "quit", ] tf = tempfile.NamedTemporaryFile(mode='w', encoding='utf-8') for cmd in cmds: tf.write(cmd + "\n") tf.flush() # Works on in MacOS 10.9 & later #call([dbg] + list( itertools.chain.from_iterable([['-o', b] for b in cmds])), logger) call(['cat', tf.name], logger) call([dbg, '--source', tf.name], logger) root_logger.info("Done analyzing %s process with PID %d", pinfo.name, pinfo.pid)