[prof] export slide offset in profile log

When exporting `shared-library` in profile log, additionally export a
slide offset. This is required to parse profile logs generated on
systems with ASLR (OS X), otherwise it is impossible to assign C++
symbol names to their addresses in the log.

See: https://github.com/nodejs/node/issues/6466

BUG=

Review-Url: https://codereview.chromium.org/1934453003
Cr-Commit-Position: refs/heads/master@{#35921}
This commit is contained in:
fedor 2016-05-02 01:00:48 -07:00 committed by Commit bot
parent 914ad0a379
commit aee17a63b3
8 changed files with 51 additions and 43 deletions

View File

@ -86,10 +86,10 @@ std::vector<OS::SharedLibraryAddress> OS::GetSharedLibraryAddresses() {
char* code_ptr = getsectdatafromheader(header, SEG_TEXT, SECT_TEXT, &size); char* code_ptr = getsectdatafromheader(header, SEG_TEXT, SECT_TEXT, &size);
#endif #endif
if (code_ptr == NULL) continue; if (code_ptr == NULL) continue;
const uintptr_t slide = _dyld_get_image_vmaddr_slide(i); const intptr_t slide = _dyld_get_image_vmaddr_slide(i);
const uintptr_t start = reinterpret_cast<uintptr_t>(code_ptr) + slide; const uintptr_t start = reinterpret_cast<uintptr_t>(code_ptr) + slide;
result.push_back( result.push_back(SharedLibraryAddress(_dyld_get_image_name(i), start,
SharedLibraryAddress(_dyld_get_image_name(i), start, start + size)); start + size, slide));
} }
return result; return result;
} }

View File

@ -235,13 +235,20 @@ class OS {
// Support for the profiler. Can do nothing, in which case ticks // Support for the profiler. Can do nothing, in which case ticks
// occuring in shared libraries will not be properly accounted for. // occuring in shared libraries will not be properly accounted for.
struct SharedLibraryAddress { struct SharedLibraryAddress {
SharedLibraryAddress( SharedLibraryAddress(const std::string& library_path, uintptr_t start,
const std::string& library_path, uintptr_t start, uintptr_t end) uintptr_t end)
: library_path(library_path), start(start), end(end) {} : library_path(library_path), start(start), end(end), aslr_slide(0) {}
SharedLibraryAddress(const std::string& library_path, uintptr_t start,
uintptr_t end, intptr_t aslr_slide)
: library_path(library_path),
start(start),
end(end),
aslr_slide(aslr_slide) {}
std::string library_path; std::string library_path;
uintptr_t start; uintptr_t start;
uintptr_t end; uintptr_t end;
intptr_t aslr_slide;
}; };
static std::vector<SharedLibraryAddress> GetSharedLibraryAddresses(); static std::vector<SharedLibraryAddress> GetSharedLibraryAddresses();

View File

@ -665,8 +665,9 @@ void Profiler::Engage() {
std::vector<base::OS::SharedLibraryAddress> addresses = std::vector<base::OS::SharedLibraryAddress> addresses =
base::OS::GetSharedLibraryAddresses(); base::OS::GetSharedLibraryAddresses();
for (size_t i = 0; i < addresses.size(); ++i) { for (size_t i = 0; i < addresses.size(); ++i) {
LOG(isolate_, SharedLibraryEvent( LOG(isolate_,
addresses[i].library_path, addresses[i].start, addresses[i].end)); SharedLibraryEvent(addresses[i].library_path, addresses[i].start,
addresses[i].end, addresses[i].aslr_slide));
} }
// Start thread processing the profiler buffer. // Start thread processing the profiler buffer.
@ -825,14 +826,14 @@ void Logger::ApiSecurityCheck() {
ApiEvent("api,check-security"); ApiEvent("api,check-security");
} }
void Logger::SharedLibraryEvent(const std::string& library_path, void Logger::SharedLibraryEvent(const std::string& library_path,
uintptr_t start, uintptr_t start, uintptr_t end,
uintptr_t end) { intptr_t aslr_slide) {
if (!log_->IsEnabled() || !FLAG_prof_cpp) return; if (!log_->IsEnabled() || !FLAG_prof_cpp) return;
Log::MessageBuilder msg(log_); Log::MessageBuilder msg(log_);
msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR, msg.Append("shared-library,\"%s\",0x%08" V8PRIxPTR ",0x%08" V8PRIxPTR
library_path.c_str(), start, end); ",%" V8PRIdPTR,
library_path.c_str(), start, end, aslr_slide);
msg.WriteToLogFile(); msg.WriteToLogFile();
} }

View File

@ -270,9 +270,8 @@ class Logger {
void HeapSampleStats(const char* space, const char* kind, void HeapSampleStats(const char* space, const char* kind,
intptr_t capacity, intptr_t used); intptr_t capacity, intptr_t used);
void SharedLibraryEvent(const std::string& library_path, void SharedLibraryEvent(const std::string& library_path, uintptr_t start,
uintptr_t start, uintptr_t end, intptr_t aslr_slide);
uintptr_t end);
void CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta); void CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta);
void CurrentTimeEvent(); void CurrentTimeEvent();

View File

@ -1,6 +1,6 @@
shared-library,"shell",0x08048000,0x081ee000 shared-library,"shell",0x08048000,0x081ee000,0
shared-library,"/lib32/libm-2.7.so",0xf7db6000,0xf7dd9000 shared-library,"/lib32/libm-2.7.so",0xf7db6000,0xf7dd9000,0
shared-library,"ffffe000-fffff000",0xffffe000,0xfffff000 shared-library,"ffffe000-fffff000",0xffffe000,0xfffff000,0
profiler,"begin",1 profiler,"begin",1
code-creation,Stub,0,0x424260,348,"CompareStub_GE" code-creation,Stub,0,0x424260,348,"CompareStub_GE"
code-creation,LazyCompile,0,0x2a8100,18535,"DrawQube 3d-cube.js:188",0xf43abcac, code-creation,LazyCompile,0,0x2a8100,18535,"DrawQube 3d-cube.js:188",0xf43abcac,

View File

@ -1,6 +1,6 @@
shared-library,"shell",0x08048000,0x081ee000 shared-library,"shell",0x08048000,0x081ee000,0
shared-library,"/lib32/libm-2.7.so",0xf7db6000,0xf7dd9000 shared-library,"/lib32/libm-2.7.so",0xf7db6000,0xf7dd9000,0
shared-library,"ffffe000-fffff000",0xffffe000,0xfffff000 shared-library,"ffffe000-fffff000",0xffffe000,0xfffff000,0
profiler,"begin",1 profiler,"begin",1
code-creation,Stub,0,0xf540a100,474,"CEntryStub" code-creation,Stub,0,0xf540a100,474,"CEntryStub"
code-creation,Script,0,0xf541cd80,736,"exp.js" code-creation,Script,0,0xf541cd80,736,"exp.js"

View File

@ -81,7 +81,7 @@
var shell_prov = new UnixCppEntriesProvider(); var shell_prov = new UnixCppEntriesProvider();
var shell_syms = []; var shell_syms = [];
shell_prov.parseVmSymbols('shell', 0x08048000, 0x081ee000, shell_prov.parseVmSymbols('shell', 0x08048000, 0x081ee000, 0,
function (name, start, end) { function (name, start, end) {
shell_syms.push(Array.prototype.slice.apply(arguments, [0])); shell_syms.push(Array.prototype.slice.apply(arguments, [0]));
}); });
@ -107,7 +107,7 @@
}; };
var libc_prov = new UnixCppEntriesProvider(); var libc_prov = new UnixCppEntriesProvider();
var libc_syms = []; var libc_syms = [];
libc_prov.parseVmSymbols('libc', 0xf7c5c000, 0xf7da5000, libc_prov.parseVmSymbols('libc', 0xf7c5c000, 0xf7da5000, 0,
function (name, start, end) { function (name, start, end) {
libc_syms.push(Array.prototype.slice.apply(arguments, [0])); libc_syms.push(Array.prototype.slice.apply(arguments, [0]));
}); });
@ -145,17 +145,17 @@
var shell_prov = new MacCppEntriesProvider(); var shell_prov = new MacCppEntriesProvider();
var shell_syms = []; var shell_syms = [];
shell_prov.parseVmSymbols('shell', 0x00001b00, 0x00163156, shell_prov.parseVmSymbols('shell', 0x00001c00, 0x00163256, 0x100,
function (name, start, end) { function (name, start, end) {
shell_syms.push(Array.prototype.slice.apply(arguments, [0])); shell_syms.push(Array.prototype.slice.apply(arguments, [0]));
}); });
assertEquals( assertEquals(
[['start', 0x00001b00, 0x00001b40], [['start', 0x00001c00, 0x00001c40],
['dyld_stub_binding_helper', 0x00001b40, 0x0011b710], ['dyld_stub_binding_helper', 0x00001c40, 0x0011b810],
['v8::internal::RegExpMacroAssembler::CheckPosition', 0x0011b710, 0x00134250], ['v8::internal::RegExpMacroAssembler::CheckPosition', 0x0011b810, 0x00134350],
['v8::internal::Runtime_StringReplaceRegExpWithString', 0x00134250, 0x00137220], ['v8::internal::Runtime_StringReplaceRegExpWithString', 0x00134350, 0x00137320],
['v8::internal::Runtime::GetElementOrCharAt', 0x00137220, 0x00137400], ['v8::internal::Runtime::GetElementOrCharAt', 0x00137320, 0x00137500],
['v8::internal::Runtime_DebugGetPropertyDetails', 0x00137400, 0x00163156]], ['v8::internal::Runtime_DebugGetPropertyDetails', 0x00137500, 0x00163256]],
shell_syms); shell_syms);
// stdc++ library // stdc++ library
@ -168,7 +168,7 @@
}; };
var stdc_prov = new MacCppEntriesProvider(); var stdc_prov = new MacCppEntriesProvider();
var stdc_syms = []; var stdc_syms = [];
stdc_prov.parseVmSymbols('stdc++', 0x95728fb4, 0x95770005, stdc_prov.parseVmSymbols('stdc++', 0x95728fb4, 0x95770005, 0,
function (name, start, end) { function (name, start, end) {
stdc_syms.push(Array.prototype.slice.apply(arguments, [0])); stdc_syms.push(Array.prototype.slice.apply(arguments, [0]));
}); });
@ -211,7 +211,7 @@
}; };
var shell_prov = new WindowsCppEntriesProvider(); var shell_prov = new WindowsCppEntriesProvider();
var shell_syms = []; var shell_syms = [];
shell_prov.parseVmSymbols('shell.exe', 0x00400000, 0x0057c000, shell_prov.parseVmSymbols('shell.exe', 0x00400000, 0x0057c000, 0,
function (name, start, end) { function (name, start, end) {
shell_syms.push(Array.prototype.slice.apply(arguments, [0])); shell_syms.push(Array.prototype.slice.apply(arguments, [0]));
}); });
@ -252,7 +252,7 @@
read = exeSymbols; read = exeSymbols;
var exe_exe_syms = []; var exe_exe_syms = [];
(new WindowsCppEntriesProvider()).parseVmSymbols( (new WindowsCppEntriesProvider()).parseVmSymbols(
'chrome.exe', 0x00400000, 0x00472000, 'chrome.exe', 0x00400000, 0x00472000, 0,
function (name, start, end) { function (name, start, end) {
exe_exe_syms.push(Array.prototype.slice.apply(arguments, [0])); exe_exe_syms.push(Array.prototype.slice.apply(arguments, [0]));
}); });
@ -264,7 +264,7 @@
read = dllSymbols; read = dllSymbols;
var exe_dll_syms = []; var exe_dll_syms = [];
(new WindowsCppEntriesProvider()).parseVmSymbols( (new WindowsCppEntriesProvider()).parseVmSymbols(
'chrome.exe', 0x00400000, 0x00472000, 'chrome.exe', 0x00400000, 0x00472000, 0,
function (name, start, end) { function (name, start, end) {
exe_dll_syms.push(Array.prototype.slice.apply(arguments, [0])); exe_dll_syms.push(Array.prototype.slice.apply(arguments, [0]));
}); });
@ -275,7 +275,7 @@
read = dllSymbols; read = dllSymbols;
var dll_dll_syms = []; var dll_dll_syms = [];
(new WindowsCppEntriesProvider()).parseVmSymbols( (new WindowsCppEntriesProvider()).parseVmSymbols(
'chrome.dll', 0x01c30000, 0x02b80000, 'chrome.dll', 0x01c30000, 0x02b80000, 0,
function (name, start, end) { function (name, start, end) {
dll_dll_syms.push(Array.prototype.slice.apply(arguments, [0])); dll_dll_syms.push(Array.prototype.slice.apply(arguments, [0]));
}); });
@ -287,7 +287,7 @@
read = exeSymbols; read = exeSymbols;
var dll_exe_syms = []; var dll_exe_syms = [];
(new WindowsCppEntriesProvider()).parseVmSymbols( (new WindowsCppEntriesProvider()).parseVmSymbols(
'chrome.dll', 0x01c30000, 0x02b80000, 'chrome.dll', 0x01c30000, 0x02b80000, 0,
function (name, start, end) { function (name, start, end) {
dll_exe_syms.push(Array.prototype.slice.apply(arguments, [0])); dll_exe_syms.push(Array.prototype.slice.apply(arguments, [0]));
}); });
@ -304,7 +304,7 @@ function CppEntriesProviderMock() {
CppEntriesProviderMock.prototype.parseVmSymbols = function( CppEntriesProviderMock.prototype.parseVmSymbols = function(
name, startAddr, endAddr, symbolAdder) { name, startAddr, endAddr, slideAddr, symbolAdder) {
var symbols = { var symbols = {
'shell': 'shell':
[['v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)', 0x080f8800, 0x080f8d90], [['v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)', 0x080f8800, 0x080f8d90],

View File

@ -83,7 +83,7 @@ function TickProcessor(
pairwiseTimedRange, pairwiseTimedRange,
onlySummary) { onlySummary) {
LogReader.call(this, { LogReader.call(this, {
'shared-library': { parsers: [null, parseInt, parseInt], 'shared-library': { parsers: [null, parseInt, parseInt, parseInt],
processor: this.processSharedLibrary }, processor: this.processSharedLibrary },
'code-creation': { 'code-creation': {
parsers: [null, parseInt, parseInt, parseInt, null, 'var-args'], parsers: [null, parseInt, parseInt, parseInt, null, 'var-args'],
@ -242,13 +242,13 @@ TickProcessor.prototype.processLogFileInTest = function(fileName) {
TickProcessor.prototype.processSharedLibrary = function( TickProcessor.prototype.processSharedLibrary = function(
name, startAddr, endAddr) { name, startAddr, endAddr, aslrSlide) {
var entry = this.profile_.addLibrary(name, startAddr, endAddr); var entry = this.profile_.addLibrary(name, startAddr, endAddr, aslrSlide);
this.setCodeType(entry.getName(), 'SHARED_LIB'); this.setCodeType(entry.getName(), 'SHARED_LIB');
var self = this; var self = this;
var libFuncs = this.cppEntriesProvider_.parseVmSymbols( var libFuncs = this.cppEntriesProvider_.parseVmSymbols(
name, startAddr, endAddr, function(fName, fStart, fEnd) { name, startAddr, endAddr, aslrSlide, function(fName, fStart, fEnd) {
self.profile_.addStaticCode(fName, fStart, fEnd); self.profile_.addStaticCode(fName, fStart, fEnd);
self.setCodeType(fName, 'CPP'); self.setCodeType(fName, 'CPP');
}); });
@ -559,7 +559,7 @@ function CppEntriesProvider() {
CppEntriesProvider.prototype.parseVmSymbols = function( CppEntriesProvider.prototype.parseVmSymbols = function(
libName, libStart, libEnd, processorFunc) { libName, libStart, libEnd, libASLRSlide, processorFunc) {
this.loadSymbols(libName); this.loadSymbols(libName);
var prevEntry; var prevEntry;
@ -588,6 +588,7 @@ CppEntriesProvider.prototype.parseVmSymbols = function(
} else if (funcInfo === false) { } else if (funcInfo === false) {
break; break;
} }
funcInfo.start += libASLRSlide;
if (funcInfo.start < libStart && funcInfo.start < libEnd - libStart) { if (funcInfo.start < libStart && funcInfo.start < libEnd - libStart) {
funcInfo.start += libStart; funcInfo.start += libStart;
} }