mirror of
https://git.suyu.dev/suyu/breakpad.git
synced 2026-02-13 07:13:02 +00:00
A .dSYM may validly contain a __DWARF segment without any __debug_info section. This can occur for Chromium Framework in a component build of Chromium, because in that case, all of the code is in other libraries that Chromium Framework depends on. This was previously tested by an assertion, but the assertion did not trigger in NDEBUG (release) builds. In NDEBUG builds, this condition would lead to an out-of-bounds read, detected by AddressSanitizer. Instead of an assertion, the check is now always done at runtime. Instead of being fatal, it's now just a warning, because it's been established that __DWARF without __debug_info can occur. (In the Chromium case, it remains pointless to run dump_syms via the "chrome_dump_syms" target on a component build, as it'll only attempt to symbolize Chromium Framework, and not any of the libraries that Chromium Framework depends on that actually contain the code.) Bug: chromium:991206 Change-Id: I6c9c75f0be7901813e3eaae54aff38c1afe73ca9 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/1741610 Reviewed-by: Robert Sesek <rsesek@chromium.org>
197 lines
7.9 KiB
C++
197 lines
7.9 KiB
C++
// -*- mode: c++ -*-
|
|
|
|
// Copyright (c) 2011, Google Inc.
|
|
// All rights reserved.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions are
|
|
// met:
|
|
//
|
|
// * Redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
// * Redistributions in binary form must reproduce the above
|
|
// copyright notice, this list of conditions and the following disclaimer
|
|
// in the documentation and/or other materials provided with the
|
|
// distribution.
|
|
// * Neither the name of Google Inc. nor the names of its
|
|
// contributors may be used to endorse or promote products derived from
|
|
// this software without specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
// Author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
|
|
|
|
// dump_syms.h: Declaration of google_breakpad::DumpSymbols, a class for
|
|
// reading debugging information from Mach-O files and writing it out as a
|
|
// Breakpad symbol file.
|
|
|
|
#include <mach-o/loader.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <ostream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "common/byte_cursor.h"
|
|
#include "common/mac/macho_reader.h"
|
|
#include "common/mac/super_fat_arch.h"
|
|
#include "common/module.h"
|
|
#include "common/scoped_ptr.h"
|
|
#include "common/symbol_data.h"
|
|
|
|
namespace google_breakpad {
|
|
|
|
class DumpSymbols {
|
|
public:
|
|
DumpSymbols(SymbolData symbol_data, bool handle_inter_cu_refs)
|
|
: symbol_data_(symbol_data),
|
|
handle_inter_cu_refs_(handle_inter_cu_refs),
|
|
input_pathname_(),
|
|
object_filename_(),
|
|
contents_(),
|
|
object_files_(),
|
|
selected_object_file_(),
|
|
selected_object_name_() { }
|
|
~DumpSymbols() {
|
|
}
|
|
|
|
// Prepare to read debugging information from |filename|. |filename| may be
|
|
// the name of a universal binary, a Mach-O file, or a dSYM bundle
|
|
// containing either of the above. On success, return true; if there is a
|
|
// problem reading |filename|, report it and return false.
|
|
bool Read(const std::string &filename);
|
|
|
|
// If this dumper's file includes an object file for |cpu_type| and
|
|
// |cpu_subtype|, then select that object file for dumping, and return
|
|
// true. Otherwise, return false, and leave this dumper's selected
|
|
// architecture unchanged.
|
|
//
|
|
// By default, if this dumper's file contains only one object file, then
|
|
// the dumper will dump those symbols; and if it contains more than one
|
|
// object file, then the dumper will dump the object file whose
|
|
// architecture matches that of this dumper program.
|
|
bool SetArchitecture(cpu_type_t cpu_type, cpu_subtype_t cpu_subtype);
|
|
|
|
// If this dumper's file includes an object file for |arch_name|, then select
|
|
// that object file for dumping, and return true. Otherwise, return false,
|
|
// and leave this dumper's selected architecture unchanged.
|
|
//
|
|
// By default, if this dumper's file contains only one object file, then
|
|
// the dumper will dump those symbols; and if it contains more than one
|
|
// object file, then the dumper will dump the object file whose
|
|
// architecture matches that of this dumper program.
|
|
bool SetArchitecture(const std::string &arch_name);
|
|
|
|
// Return a pointer to an array of SuperFatArch structures describing the
|
|
// object files contained in this dumper's file. Set *|count| to the number
|
|
// of elements in the array. The returned array is owned by this DumpSymbols
|
|
// instance.
|
|
//
|
|
// If there are no available architectures, this function
|
|
// may return NULL.
|
|
const SuperFatArch* AvailableArchitectures(size_t *count) {
|
|
*count = object_files_.size();
|
|
if (object_files_.size() > 0)
|
|
return &object_files_[0];
|
|
return NULL;
|
|
}
|
|
|
|
// Read the selected object file's debugging information, and write it out to
|
|
// |stream|. Return true on success; if an error occurs, report it and
|
|
// return false.
|
|
bool WriteSymbolFile(std::ostream &stream);
|
|
|
|
// Read the selected object file's debugging information, and write out the
|
|
// header only to |stream|. Return true on success; if an error occurs, report
|
|
// it and return false.
|
|
bool WriteSymbolFileHeader(std::ostream &stream);
|
|
|
|
// As above, but simply return the debugging information in module
|
|
// instead of writing it to a stream. The caller owns the resulting
|
|
// module object and must delete it when finished.
|
|
bool ReadSymbolData(Module** module);
|
|
|
|
private:
|
|
// Used internally.
|
|
class DumperLineToModule;
|
|
class DumperRangesHandler;
|
|
class LoadCommandDumper;
|
|
|
|
// This method behaves similarly to NXFindBestFatArch, but it supports
|
|
// SuperFatArch.
|
|
SuperFatArch* FindBestMatchForArchitecture(
|
|
cpu_type_t cpu_type, cpu_subtype_t cpu_subtype);
|
|
|
|
// Return an identifier string for the file this DumpSymbols is dumping.
|
|
std::string Identifier();
|
|
|
|
|
|
// Creates an empty module object.
|
|
bool CreateEmptyModule(scoped_ptr<Module>& module);
|
|
|
|
// Read debugging information from |dwarf_sections|, which was taken from
|
|
// |macho_reader|, and add it to |module|.
|
|
void ReadDwarf(google_breakpad::Module *module,
|
|
const mach_o::Reader &macho_reader,
|
|
const mach_o::SectionMap &dwarf_sections,
|
|
bool handle_inter_cu_refs) const;
|
|
|
|
// Read DWARF CFI or .eh_frame data from |section|, belonging to
|
|
// |macho_reader|, and record it in |module|. If |eh_frame| is true,
|
|
// then the data is .eh_frame-format data; otherwise, it is standard DWARF
|
|
// .debug_frame data. On success, return true; on failure, report
|
|
// the problem and return false.
|
|
bool ReadCFI(google_breakpad::Module *module,
|
|
const mach_o::Reader &macho_reader,
|
|
const mach_o::Section §ion,
|
|
bool eh_frame) const;
|
|
|
|
// The selection of what type of symbol data to read/write.
|
|
const SymbolData symbol_data_;
|
|
|
|
// Whether to handle references between compilation units.
|
|
const bool handle_inter_cu_refs_;
|
|
|
|
// The name of the file or bundle whose symbols this will dump.
|
|
// This is the path given to Read, for use in error messages.
|
|
std::string input_pathname_;
|
|
|
|
// The name of the file this DumpSymbols will actually read debugging
|
|
// information from. Normally, this is the same as input_pathname_, but if
|
|
// filename refers to a dSYM bundle, then this is the resource file
|
|
// within that bundle.
|
|
std::string object_filename_;
|
|
|
|
// The complete contents of object_filename_, mapped into memory.
|
|
scoped_array<uint8_t> contents_;
|
|
|
|
// A vector of SuperFatArch structures describing the object files
|
|
// object_filename_ contains. If object_filename_ refers to a fat binary,
|
|
// this may have more than one element; if it refers to a Mach-O file, this
|
|
// has exactly one element.
|
|
vector<SuperFatArch> object_files_;
|
|
|
|
// The object file in object_files_ selected to dump, or NULL if
|
|
// SetArchitecture hasn't been called yet.
|
|
const SuperFatArch *selected_object_file_;
|
|
|
|
// A string that identifies the selected object file, for use in error
|
|
// messages. This is usually object_filename_, but if that refers to a
|
|
// fat binary, it includes an indication of the particular architecture
|
|
// within that binary.
|
|
string selected_object_name_;
|
|
};
|
|
|
|
} // namespace google_breakpad
|