Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1720)

Unified Diff: base/third_party/symbolize/symbolize.cc

Issue 1996243002: Workaround ARM tracing issues for non-component builds. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/third_party/symbolize/symbolize.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/third_party/symbolize/symbolize.cc
diff --git a/base/third_party/symbolize/symbolize.cc b/base/third_party/symbolize/symbolize.cc
index db82b04d4df254a345107f532c636511cc5e6753..02500c35f5910164d5bf7b783664b42b3329859c 100644
--- a/base/third_party/symbolize/symbolize.cc
+++ b/base/third_party/symbolize/symbolize.cc
@@ -404,7 +404,7 @@ class LineReader {
//
// Note: if the last line doesn't end with '\n', the line will be
// dropped. It's an intentional behavior to make the code simple.
- bool ReadLine(const char **bol, const char **eol) {
+ bool ReadLine(char **bol, char **eol) {
if (BufferIsEmpty()) { // First time.
const ssize_t num_bytes = ReadPersistent(fd_, buf_, buf_len_);
if (num_bytes <= 0) { // EOF or error.
@@ -443,12 +443,12 @@ class LineReader {
}
// Beginning of line.
- const char *bol() {
+ char *bol() {
return bol_;
}
// End of line.
- const char *eol() {
+ char *eol() {
return eol_;
}
@@ -509,95 +509,141 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
uint64_t &base_address,
char *out_file_name,
int out_file_name_size) {
- int object_fd;
+ struct FindArgs {
+ const uint64_t pc;
+ uint64_t* out_start_address;
+ uint64_t* out_base_address;
+ char* out_file_name;
+ int out_file_name_size;
+ // Fields below are default initialized
+ int num_maps;
+ int out_object_fd;
+ };
+
+ auto find_callback = [](void* data, const MappedRegion& region) -> bool {
+ FindArgs* args = static_cast<FindArgs*>(data);
+ args->num_maps++;
+ // Check start and end addresses.
+ if (!(region.start_address <= args->pc && args->pc < region.end_address)) {
+ return false; // We skip this map. PC isn't in this map.
+ }
+
+ // Check flags. We are only interested in "r-x" maps.
+ if (memcmp(region.flags, "r-x", 3) != 0) { // Not a "r-x" map.
+ return false; // We skip this map.
+ }
+
+ *args->out_start_address = region.start_address;
+
+ // Don't subtract 'start_address' from the first entry:
+ // * If a binary is compiled w/o -pie, then the first entry in
+ // process maps is likely the binary itself (all dynamic libs
+ // are mapped higher in address space). For such a binary,
+ // instruction offset in binary coincides with the actual
+ // instruction address in virtual memory (as code section
+ // is mapped to a fixed memory range).
+ // * If a binary is compiled with -pie, all the modules are
+ // mapped high at address space (in particular, higher than
+ // shadow memory of the tool), so the module can't be the
+ // first entry.
+ *args->out_base_address =
+ ((args->num_maps == 1) ? 0U : region.start_address) -
+ region.file_offset;
+
+ // Open region's file.
+ NO_INTR(args->out_object_fd = open(region.name, O_RDONLY));
+ if (args->out_object_fd < 0) {
+ // Failed to open object file. Copy the object file name to
+ // |out_file_name|.
+ strncpy(args->out_file_name, region.name, args->out_file_name_size);
+ // Making sure |out_file_name| is always null-terminated.
+ args->out_file_name[args->out_file_name_size - 1] = '\0';
+ }
+
+ return true; // We found the entry; stop iterating.
+ };
+
+ FindArgs args = {
+ pc,
+ &start_address,
+ &base_address,
+ out_file_name,
+ out_file_name_size
+ };
+ bool found = FindMappedRegion(&args, find_callback);
+ return found ? args.out_object_fd : -1;
+}
+
+bool FindMappedRegion(void* callback_data,
+ bool (*callback)(void*, const MappedRegion&)) {
// Open /proc/self/maps.
int maps_fd;
NO_INTR(maps_fd = open("/proc/self/maps", O_RDONLY));
FileDescriptor wrapped_maps_fd(maps_fd);
if (wrapped_maps_fd.get() < 0) {
- return -1;
+ return false;
}
- // Iterate over maps and look for the map containing the pc. Then
- // look into the symbol tables inside.
char buf[1024]; // Big enough for line of sane /proc/self/maps
int num_maps = 0;
+ MappedRegion region;
LineReader reader(wrapped_maps_fd.get(), buf, sizeof(buf));
while (true) {
num_maps++;
- const char *cursor;
- const char *eol;
+ char *cursor;
+ char *eol;
if (!reader.ReadLine(&cursor, &eol)) { // EOF or malformed line.
- return -1;
+ break;
}
+ // Zero-terminate the line.
+ *eol = 0;
+
// Start parsing line in /proc/self/maps. Here is an example:
//
// 08048000-0804c000 r-xp 00000000 08:01 2142121 /bin/cat
//
// We want start address (08048000), end address (0804c000), flags
- // (r-xp) and file name (/bin/cat).
+ // (r-xp), file offset (2142121) and file name (/bin/cat).
// Read start address.
- cursor = GetHex(cursor, eol, &start_address);
+ cursor = GetHex(cursor, eol, &region.start_address);
if (cursor == eol || *cursor != '-') {
- return -1; // Malformed line.
+ break; // Malformed line.
}
++cursor; // Skip '-'.
// Read end address.
uint64_t end_address;
- cursor = GetHex(cursor, eol, &end_address);
+ cursor = GetHex(cursor, eol, &region.end_address);
if (cursor == eol || *cursor != ' ') {
- return -1; // Malformed line.
+ break; // Malformed line.
}
++cursor; // Skip ' '.
- // Check start and end addresses.
- if (!(start_address <= pc && pc < end_address)) {
- continue; // We skip this map. PC isn't in this map.
- }
-
// Read flags. Skip flags until we encounter a space or eol.
- const char * const flags_start = cursor;
+ region.flags = cursor;
while (cursor < eol && *cursor != ' ') {
++cursor;
}
// We expect at least four letters for flags (ex. "r-xp").
- if (cursor == eol || cursor < flags_start + 4) {
- return -1; // Malformed line.
+ if (cursor == eol || cursor < region.flags + 4) {
+ break; // Malformed line.
}
-
- // Check flags. We are only interested in "r-x" maps.
- if (memcmp(flags_start, "r-x", 3) != 0) { // Not a "r-x" map.
- continue; // We skip this map.
- }
- ++cursor; // Skip ' '.
+ // Replace ' ' with zero and advance.
+ *cursor++ = 0;
// Read file offset.
- uint64_t file_offset;
- cursor = GetHex(cursor, eol, &file_offset);
+ cursor = GetHex(cursor, eol, &region.file_offset);
if (cursor == eol || *cursor != ' ') {
- return -1; // Malformed line.
+ break; // Malformed line.
}
++cursor; // Skip ' '.
- // Don't subtract 'start_address' from the first entry:
- // * If a binary is compiled w/o -pie, then the first entry in
- // process maps is likely the binary itself (all dynamic libs
- // are mapped higher in address space). For such a binary,
- // instruction offset in binary coincides with the actual
- // instruction address in virtual memory (as code section
- // is mapped to a fixed memory range).
- // * If a binary is compiled with -pie, all the modules are
- // mapped high at address space (in particular, higher than
- // shadow memory of the tool), so the module can't be the
- // first entry.
- base_address = ((num_maps == 1) ? 0U : start_address) - file_offset;
-
// Skip to file name. "cursor" now points to dev. We need to
- // skip at least two spaces for dev and inode.
+ // skip at least two spaces for dev and inode. Note that name can
+ // be empty (cursor == eol).
int num_spaces = 0;
while (cursor < eol) {
if (*cursor == ' ') {
@@ -609,22 +655,17 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
}
++cursor;
}
- if (cursor == eol) {
- return -1; // Malformed line.
- }
- // Finally, "cursor" now points to file name of our interest.
- NO_INTR(object_fd = open(cursor, O_RDONLY));
- if (object_fd < 0) {
- // Failed to open object file. Copy the object file name to
- // |out_file_name|.
- strncpy(out_file_name, cursor, out_file_name_size);
- // Making sure |out_file_name| is always null-terminated.
- out_file_name[out_file_name_size - 1] = '\0';
- return -1;
+ // Finally, "cursor" now points to file name.
+ region.name = cursor;
+
+ // Report found region to the callback.
+ if (callback(callback_data, region)) {
+ return true; // Callback stopped the iteration.
}
- return object_fd;
}
+
+ return false;
}
// POSIX doesn't define any async-signal safe function for converting
« no previous file with comments | « base/third_party/symbolize/symbolize.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698