Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def Finish(self, stop_pool=True):
"""Wait for the expected number of jobs to be submitted, and then
wait for the pool to finish processing them. By default, will close
and clear the pool, but for testcases that need multiple runs, pass
stop_pool = False."""
with Dumper.jobs_condition:
while len(self.jobs_record) != 0:
Dumper.jobs_condition.wait()
if stop_pool:
Dumper.pool.close()
Dumper.pool.join()
@classmethod
def GlobalInit(cls, module=multiprocessing):
"""Initialize the class globals for the multiprocessing setup; must
be called before any Dumper instances are created and used. Test cases
may pass in a different module to supply Manager and Pool objects,
usually multiprocessing.dummy."""
num_cpus = module.cpu_count()
if num_cpus is None:
# assume a dual core machine if we can't find out for some reason
# probably better on single core anyway due to I/O constraints
num_cpus = 2
# have to create any locks etc before the pool
cls.manager = module.Manager()
cls.jobs_condition = Dumper.manager.Condition()
cls.lock = Dumper.manager.RLock()
cls.pool = module.Pool(num_cpus, WorkerInitializer, (cls, cls.lock))
copy_debug=options.copy_debug,
archs=options.archs,
srcdirs=options.srcdir,
vcsinfo=options.vcsinfo,
srcsrv=options.srcsrv,
exclude=options.exclude,
repo_manifest=options.repo_manifest)
for arg in args[2:]:
dumper.Process(arg)
dumper.Finish()
# run main if run directly
if __name__ == "__main__":
# set up the multiprocessing infrastructure before we start;
# note that this needs to be in the __main__ guard, or else Windows will choke
Dumper.GlobalInit()
main()
if subprocess.call([self.objcopy, '--only-keep-debug', file, file_dbg]) == 0 and \
subprocess.call([self.objcopy, '--add-gnu-debuglink=%s' % file_dbg, file]) == 0:
rel_path = os.path.join(debug_file,
guid,
debug_file + ".dbg")
full_path = os.path.normpath(os.path.join(self.symbol_path,
rel_path))
shutil.move(file_dbg, full_path)
# gzip the shipped debug files
os.system("gzip %s" % full_path)
self.output(sys.stdout, rel_path + ".gz")
else:
if os.path.isfile(file_dbg):
os.unlink(file_dbg)
class Dumper_Solaris(Dumper):
def RunFileCommand(self, file):
"""Utility function, returns the output of file(1)"""
try:
output = os.popen("file " + file).read()
return output.split('\t')[1];
except:
return ""
def ShouldProcess(self, file):
"""This function will allow processing of files that are
executable, or end with the .so extension, and additionally
file(1) reports as being ELF files. It expects to find the file
command in PATH."""
if not Dumper.ShouldProcess(self, file):
return False
if file.endswith(".so") or os.access(file, os.X_OK):
if self.copy_debug and arch_num == 0:
self.CopyDebug(file, debug_file, guid)
except StopIteration:
pass
except e:
self.output(sys.stderr, "Unexpected error: %s" % (str(e),))
raise
if result['status']:
# we only need 1 file to work
break
return result
# Platform-specific subclasses. For the most part, these just have
# logic to determine what files to extract symbols from.
class Dumper_Win32(Dumper):
fixedFilenameCaseCache = {}
def ShouldProcess(self, file):
"""This function will allow processing of pdb files that have dll
or exe files with the same base name next to them."""
if not Dumper.ShouldProcess(self, file):
return False
if file.endswith(".pdb"):
(path,ext) = os.path.splitext(file)
if os.path.isfile(path + ".exe") or os.path.isfile(path + ".dll"):
return True
return False
def FixFilenameCase(self, file):
"""Recent versions of Visual C++ put filenames into
PDB files as all lowercase. If the file exists
def ProcessFilesMacFinished(self, result):
if result['status']:
# kick off new jobs per-arch with our new list of files
Dumper.ProcessFiles(self, result['files'], after=AfterMac, after_arg=result['files'][0])
# only decrement jobs *after* that, since otherwise we'll remove the record for this file
self.JobFinished(result['files'][-1])
return False
if file.endswith(".so") or os.access(file, os.X_OK):
return self.RunFileCommand(file).startswith("ELF")
return False
def StartProcessFilesWorkMac(dumper, file):
"""multiprocessing can't handle methods as Process targets, so we define
a simple wrapper function around the work method."""
return dumper.ProcessFilesWorkMac(file)
def AfterMac(status, dsymbundle):
"""Cleanup function to run on Macs after we process the file(s)."""
# CopyDebug will already have been run from Dumper.ProcessFiles
shutil.rmtree(dsymbundle)
class Dumper_Mac(Dumper):
def ShouldProcess(self, file):
"""This function will allow processing of files that are
executable, or end with the .dylib extension, and additionally
file(1) reports as being Mach-O files. It expects to find the file
command in PATH."""
if not Dumper.ShouldProcess(self, file):
return False
if file.endswith(".dylib") or os.access(file, os.X_OK):
return self.RunFileCommand(file).startswith("Mach-O")
return False
def ShouldSkipDir(self, dir):
"""We create .dSYM bundles on the fly, but if someone runs
buildsymbols twice, we should skip any bundles we created
previously, otherwise we'll recurse into them and try to
dump the inner bits again."""
def output(self, dest, output_str):
"""Writes |output_str| to |dest|, holding |lock|;
terminates with a newline."""
with Dumper.lock:
dest.write(output_str + "\n")
dest.flush()
debug_file = os.path.abspath(debug_file)
streamFilename = debug_file + ".stream"
stream_output_path = os.path.abspath(streamFilename)
# Call SourceIndex to create the .stream file
result = SourceIndex(sourceFileStream, stream_output_path, vcs_root)
if self.copy_debug:
pdbstr_path = os.environ.get("PDBSTR_PATH")
pdbstr = os.path.normpath(pdbstr_path)
subprocess.call([pdbstr, "-w", "-p:" + os.path.basename(debug_file),
"-i:" + os.path.basename(streamFilename), "-s:srcsrv"],
cwd=os.path.dirname(stream_output_path))
# clean up all the .stream files when done
os.remove(stream_output_path)
return result
class Dumper_Linux(Dumper):
objcopy = os.environ['OBJCOPY'] if 'OBJCOPY' in os.environ else 'objcopy'
def ShouldProcess(self, file):
"""This function will allow processing of files that are
executable, or end with the .so extension, and additionally
file(1) reports as being ELF files. It expects to find the file
command in PATH."""
if not Dumper.ShouldProcess(self, file):
return False
if file.endswith(".so") or os.access(file, os.X_OK):
return self.RunFileCommand(file).startswith("ELF")
return False
def CopyDebug(self, file, debug_file, guid):
# We want to strip out the debug info, and add a
# .gnu_debuglink section to the object, so the debugger can
# actually load our debug info later.