def create_files_from_macho_zip(fileobj, project=None): """Creates all missing dsym files from the given zip file. This returns a list of all files created. """ if not have_symsynd: raise RuntimeError('symsynd is unavailable. Install sentry with ' 'the dsym feature flag.') scratchpad = tempfile.mkdtemp() try: safe_extract_zip(fileobj, scratchpad) to_create = [] for dirpath, dirnames, filenames in os.walk(scratchpad): for fn in filenames: fn = os.path.join(dirpath, fn) try: uuids = get_macho_uuids(fn) except (IOError, ValueError): # Whatever was contained there, was probably not a # macho file. continue for cpu, uuid in uuids: to_create.append((cpu, uuid, fn)) rv = [] for cpu, uuid, filename in to_create: with open(filename, 'rb') as f: rv.append( (_create_macho_dsym_from_uuid(project, cpu, uuid, f, os.path.basename(filename)))) return rv finally: shutil.rmtree(scratchpad)
def create_files_from_macho_zip(fileobj, project=None): """Creates all missing dsym files from the given zip file. This returns a list of all files created. """ if not have_symsynd: raise RuntimeError('symsynd is unavailable. Install sentry with ' 'the dsym feature flag.') scratchpad = tempfile.mkdtemp() try: safe_extract_zip(fileobj, scratchpad) to_create = [] for dirpath, dirnames, filenames in os.walk(scratchpad): for fn in filenames: fn = os.path.join(dirpath, fn) try: uuids = get_macho_uuids(fn) except (IOError, ValueError): # Whatever was contained there, was probably not a # macho file. continue for cpu, uuid in uuids: to_create.append((cpu, uuid, fn)) rv = [] for cpu, uuid, filename in to_create: with open(filename, 'rb') as f: rv.append((_create_macho_dsym_from_uuid( project, cpu, uuid, f, os.path.basename(filename)))) return rv finally: shutil.rmtree(scratchpad)
def test_uuid(res_path): ct_dsym_path = os.path.join( res_path, 'Crash-Tester.app.dSYM', 'Contents', 'Resources', 'DWARF', 'Crash-Tester') uuids = arch.get_macho_uuids(ct_dsym_path) assert uuids == [ ('armv7', '8094558b-3641-36f7-ba80-a1aaabcf72da'), ('arm64', 'f502dec3-e605-36fd-9b3d-7080a7c6f4fc'), ]
def find_debug_images(dsym_paths, binary_images): images_to_load = set() with timedsection('iterimages0'): for image in binary_images: cpu_name = get_cpu_name(image['cpu_type'], image['cpu_subtype']) if cpu_name is not None: images_to_load.add(image['uuid'].lower()) images = {} # Step one: load images that are named by their UUID with timedsection('loadimages-fast'): for uuid in list(images_to_load): for dsym_path in dsym_paths: fn = os.path.join(dsym_path, uuid) if os.path.isfile(fn): images[uuid] = fn images_to_load.discard(uuid) break # Otherwise fall back to loading images from the dsym bundle. Because # this loading strategy is pretty slow we do't actually want to use it # unless we have a path that looks like a bundle. As a result we # find all the paths which are bundles and then only process those. if images_to_load: slow_paths = [] for dsym_path in dsym_paths: if os.path.isdir(os.path.join(dsym_path, 'Contents')): slow_paths.append(dsym_path) with timedsection('loadimages-slow'): for dsym_path in slow_paths: dwarf_base = os.path.join(dsym_path, 'Contents', 'Resources', 'DWARF') if os.path.isdir(dwarf_base): for fn in os.listdir(dwarf_base): # Looks like a UUID we loaded, skip it if fn in images: continue full_fn = os.path.join(dwarf_base, fn) uuids = get_macho_uuids(full_fn) for _, uuid in uuids: if uuid in images_to_load: images[uuid] = full_fn images_to_load.discard(uuid) rv = {} # Now resolve all the images. with timedsection('resolveimages'): for image in binary_images: cpu_name = get_cpu_name(image['cpu_type'], image['cpu_subtype']) if cpu_name is None: continue uid = image['uuid'].lower() if uid not in images: continue rv[image['image_addr']] = { 'uuid': uid, 'image_addr': image['image_addr'], 'dsym_path': images[uid], 'image_vmaddr': image['image_vmaddr'], 'cpu_name': cpu_name, } return rv