diff options
Diffstat (limited to 'V8Binding/v8/src/platform-linux.cc')
-rw-r--r-- | V8Binding/v8/src/platform-linux.cc | 99 |
1 files changed, 50 insertions, 49 deletions
diff --git a/V8Binding/v8/src/platform-linux.cc b/V8Binding/v8/src/platform-linux.cc index bccf9e6..6ec5070 100644 --- a/V8Binding/v8/src/platform-linux.cc +++ b/V8Binding/v8/src/platform-linux.cc @@ -223,62 +223,63 @@ PosixMemoryMappedFile::~PosixMemoryMappedFile() { } +void OS::LogSharedLibraryAddresses() { #ifdef ENABLE_LOGGING_AND_PROFILING -static uintptr_t StringToULong(char* buffer) { - return strtoul(buffer, NULL, 16); // NOLINT -} -#endif + // This function assumes that the layout of the file is as follows: + // hex_start_addr-hex_end_addr rwxp <unused data> [binary_file_name] + // If we encounter an unexpected situation we abort scanning further entries. + FILE *fp = fopen("/proc/self/maps", "r"); + if (fp == NULL) return; + // Allocate enough room to be able to store a full file name. + const int kLibNameLen = FILENAME_MAX + 1; + char* lib_name = reinterpret_cast<char*>(malloc(kLibNameLen)); -void OS::LogSharedLibraryAddresses() { -#ifdef ENABLE_LOGGING_AND_PROFILING - static const int MAP_LENGTH = 1024; - int fd = open("/proc/self/maps", O_RDONLY); - if (fd < 0) return; + // This loop will terminate once the scanning hits an EOF. while (true) { - char addr_buffer[11]; - addr_buffer[0] = '0'; - addr_buffer[1] = 'x'; - addr_buffer[10] = 0; - int result = read(fd, addr_buffer + 2, 8); - if (result < 8) break; - uintptr_t start = StringToULong(addr_buffer); - result = read(fd, addr_buffer + 2, 1); - if (result < 1) break; - if (addr_buffer[2] != '-') break; - result = read(fd, addr_buffer + 2, 8); - if (result < 8) break; - uintptr_t end = StringToULong(addr_buffer); - char buffer[MAP_LENGTH]; - int bytes_read = -1; - do { - bytes_read++; - if (bytes_read >= MAP_LENGTH - 1) - break; - result = read(fd, buffer + bytes_read, 1); - if (result < 1) break; - } while (buffer[bytes_read] != '\n'); - buffer[bytes_read] = 0; - // Ignore mappings that are not executable. - if (buffer[3] != 'x') continue; - char* start_of_path = index(buffer, '/'); - // If there is no filename for this line then log it as an anonymous - // mapping and use the address as its name. - if (start_of_path == NULL) { - // 40 is enough to print a 64 bit address range. - ASSERT(sizeof(buffer) > 40); - snprintf(buffer, - sizeof(buffer), - "%08" V8PRIxPTR "-%08" V8PRIxPTR, - start, - end); - LOG(SharedLibraryEvent(buffer, start, end)); + uintptr_t start, end; + char attr_r, attr_w, attr_x, attr_p; + // Parse the addresses and permission bits at the beginning of the line. + if (fscanf(fp, "%" V8PRIxPTR "-%" V8PRIxPTR, &start, &end) != 2) break; + if (fscanf(fp, " %c%c%c%c", &attr_r, &attr_w, &attr_x, &attr_p) != 4) break; + + int c; + if (attr_r == 'r' && attr_x == 'x') { + // Found a readable and executable entry. Skip characters until we reach + // the beginning of the filename or the end of the line. + do { + c = getc(fp); + } while ((c != EOF) && (c != '\n') && (c != '/')); + if (c == EOF) break; // EOF: Was unexpected, just exit. + + // Process the filename if found. + if (c == '/') { + ungetc(c, fp); // Push the '/' back into the stream to be read below. + + // Read to the end of the line. Exit if the read fails. + if (fgets(lib_name, kLibNameLen, fp) == NULL) break; + + // Drop the newline character read by fgets. We do not need to check + // for a zero-length string because we know that we at least read the + // '/' character. + lib_name[strlen(lib_name) - 1] = '\0'; + } else { + // No library name found, just record the raw address range. + snprintf(lib_name, kLibNameLen, + "%08" V8PRIxPTR "-%08" V8PRIxPTR, start, end); + } + LOG(SharedLibraryEvent(lib_name, start, end)); } else { - buffer[bytes_read] = 0; - LOG(SharedLibraryEvent(start_of_path, start, end)); + // Entry not describing executable data. Skip to end of line to setup + // reading the next entry. + do { + c = getc(fp); + } while ((c != EOF) && (c != '\n')); + if (c == EOF) break; } } - close(fd); + free(lib_name); + fclose(fp); #endif } |