mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
Bug 1634205 - Support Gecko Profiler and Base Profiler on FreeBSD r=mstange
- supports amd64 and arm64 (aarch64) - uses LUL for stack walking Differential Revision: https://phabricator.services.mozilla.com/D73162
This commit is contained in:
parent
3fa67b082d
commit
e65e9412b0
@ -137,7 +137,7 @@ if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
EXPORTS.mozilla += [
|
||||
'WindowsVersion.h',
|
||||
]
|
||||
elif CONFIG['OS_ARCH'] == 'Linux':
|
||||
elif CONFIG['OS_ARCH'] == 'Linux' or CONFIG['OS_ARCH'] == 'FreeBSD':
|
||||
EXPORTS.mozilla += [
|
||||
'LinuxSignal.h',
|
||||
]
|
||||
|
@ -90,6 +90,16 @@
|
||||
# define GP_ARCH_amd64 1
|
||||
# define GP_OS_darwin 1
|
||||
|
||||
#elif defined(__FreeBSD__) && defined(__x86_64__)
|
||||
# define GP_PLAT_amd64_freebsd 1
|
||||
# define GP_ARCH_amd64 1
|
||||
# define GP_OS_freebsd 1
|
||||
|
||||
#elif defined(__FreeBSD__) && defined(__aarch64__)
|
||||
# define GP_PLAT_arm64_freebsd 1
|
||||
# define GP_ARCH_arm64 1
|
||||
# define GP_OS_freebsd 1
|
||||
|
||||
#elif (defined(_MSC_VER) || defined(__MINGW32__)) && \
|
||||
(defined(_M_IX86) || defined(__i386__))
|
||||
# define GP_PLAT_x86_windows 1
|
||||
|
@ -34,6 +34,9 @@
|
||||
#include <math.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#if defined(GP_OS_freebsd)
|
||||
# include <sys/thr.h>
|
||||
#endif
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
@ -75,11 +78,15 @@ namespace baseprofiler {
|
||||
int profiler_current_process_id() { return getpid(); }
|
||||
|
||||
int profiler_current_thread_id() {
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
// glibc doesn't provide a wrapper for gettid().
|
||||
#if defined(__linux__) || !defined(__BIONIC__)
|
||||
return static_cast<int>(static_cast<pid_t>(syscall(SYS_gettid)));
|
||||
#elif defined(GP_OS_freebsd)
|
||||
long id;
|
||||
(void)thr_self(&id);
|
||||
return static_cast<int>(id);
|
||||
#else
|
||||
return static_cast<int>(gettid());
|
||||
# error "bad platform"
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -96,27 +103,37 @@ static void PopulateRegsFromContext(Registers& aRegs, ucontext_t* aContext) {
|
||||
mcontext_t& mcontext = aContext->uc_mcontext;
|
||||
|
||||
// Extracting the sample from the context is extremely machine dependent.
|
||||
#if defined(GP_ARCH_x86)
|
||||
#if defined(GP_PLAT_x86_linux) || defined(GP_PLAT_x86_android)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]);
|
||||
aRegs.mLR = 0;
|
||||
#elif defined(GP_ARCH_amd64)
|
||||
#elif defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_amd64_android)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]);
|
||||
aRegs.mLR = 0;
|
||||
#elif defined(GP_ARCH_arm)
|
||||
#elif defined(GP_PLAT_amd64_freebsd)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.mc_rip);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.mc_rsp);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.mc_rbp);
|
||||
aRegs.mLR = 0;
|
||||
#elif defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.arm_pc);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.arm_sp);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.arm_fp);
|
||||
aRegs.mLR = reinterpret_cast<Address>(mcontext.arm_lr);
|
||||
#elif defined(GP_ARCH_arm64)
|
||||
#elif defined(GP_PLAT_arm64_linux) || defined(GP_PLAT_arm64_android)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.pc);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.sp);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.regs[29]);
|
||||
aRegs.mLR = reinterpret_cast<Address>(mcontext.regs[30]);
|
||||
#elif defined(GP_ARCH_mips64)
|
||||
#elif defined(GP_PLAT_arm64_freebsd)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.mc_gpregs.gp_elr);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.mc_gpregs.gp_sp);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.mc_gpregs.gp_x[29]);
|
||||
aRegs.mLR = reinterpret_cast<Address>(mcontext.mc_gpregs.gp_lr);
|
||||
#elif defined(GP_PLAT_mips64_linux) || defined(GP_PLAT_mips64_android)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.pc);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.gregs[29]);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.gregs[30]);
|
||||
@ -130,9 +147,15 @@ static void PopulateRegsFromContext(Registers& aRegs, ucontext_t* aContext) {
|
||||
# define SYS_tgkill __NR_tgkill
|
||||
#endif
|
||||
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
int tgkill(pid_t tgid, pid_t tid, int signalno) {
|
||||
return syscall(SYS_tgkill, tgid, tid, signalno);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GP_OS_freebsd)
|
||||
# define tgkill thr_kill2
|
||||
#endif
|
||||
|
||||
class PlatformData {
|
||||
public:
|
||||
@ -457,7 +480,7 @@ void SamplerThread::Stop(PSLockRef aLock) {
|
||||
// END SamplerThread target specifics
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(GP_OS_linux)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_freebsd)
|
||||
|
||||
// We use pthread_atfork() to temporarily disable signal delivery during any
|
||||
// fork() call. Without that, fork() can be repeatedly interrupted by signal
|
||||
|
@ -103,11 +103,12 @@
|
||||
# include "EHABIStackWalk.h"
|
||||
#endif
|
||||
|
||||
// Linux builds use LUL, which uses DWARF info to unwind stacks.
|
||||
#if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux) || \
|
||||
defined(GP_PLAT_amd64_android) || defined(GP_PLAT_x86_android) || \
|
||||
defined(GP_PLAT_mips64_linux) || defined(GP_PLAT_arm64_linux) || \
|
||||
defined(GP_PLAT_arm64_android)
|
||||
// Linux/BSD builds use LUL, which uses DWARF info to unwind stacks.
|
||||
#if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux) || \
|
||||
defined(GP_PLAT_amd64_android) || defined(GP_PLAT_x86_android) || \
|
||||
defined(GP_PLAT_mips64_linux) || defined(GP_PLAT_arm64_linux) || \
|
||||
defined(GP_PLAT_arm64_android) || defined(GP_PLAT_amd64_freebsd) || \
|
||||
defined(GP_PLAT_arm64_freebsd)
|
||||
# define HAVE_NATIVE_UNWIND
|
||||
# define USE_LUL_STACKWALK
|
||||
# include "lul/LulMain.h"
|
||||
@ -141,7 +142,7 @@
|
||||
# define VALGRIND_MAKE_MEM_DEFINED(_addr, _len) ((void)0)
|
||||
#endif
|
||||
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android) || defined(GP_OS_freebsd)
|
||||
# include <ucontext.h>
|
||||
#endif
|
||||
|
||||
@ -603,7 +604,7 @@ class ActivePS {
|
||||
#undef HAS_FEATURE
|
||||
,
|
||||
mIsPaused(false)
|
||||
#if defined(GP_OS_linux)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_freebsd)
|
||||
,
|
||||
mWasPaused(false)
|
||||
#endif
|
||||
@ -851,7 +852,7 @@ class ActivePS {
|
||||
|
||||
PS_GET_AND_SET(bool, IsPaused)
|
||||
|
||||
#if defined(GP_OS_linux)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_freebsd)
|
||||
PS_GET_AND_SET(bool, WasPaused)
|
||||
#endif
|
||||
|
||||
@ -1006,7 +1007,7 @@ class ActivePS {
|
||||
// Is the profiler paused?
|
||||
bool mIsPaused;
|
||||
|
||||
#if defined(GP_OS_linux)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_freebsd)
|
||||
// Used to record whether the profiler was paused just before forking. False
|
||||
// at all times except just before/after forking.
|
||||
bool mWasPaused;
|
||||
@ -1159,7 +1160,7 @@ class Registers {
|
||||
Address mSP; // Stack pointer.
|
||||
Address mFP; // Frame pointer.
|
||||
Address mLR; // ARM link register.
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android) || defined(GP_OS_freebsd)
|
||||
// This contains all the registers, which means it duplicates the four fields
|
||||
// above. This is ok.
|
||||
ucontext_t* mContext; // The context from the signal handler.
|
||||
@ -1402,6 +1403,10 @@ static void DoLULBacktrace(PSLockRef aLock,
|
||||
startRegs.xip = lul::TaggedUWord(mc->gregs[REG_RIP]);
|
||||
startRegs.xsp = lul::TaggedUWord(mc->gregs[REG_RSP]);
|
||||
startRegs.xbp = lul::TaggedUWord(mc->gregs[REG_RBP]);
|
||||
# elif defined(GP_PLAT_amd64_freebsd)
|
||||
startRegs.xip = lul::TaggedUWord(mc->mc_rip);
|
||||
startRegs.xsp = lul::TaggedUWord(mc->mc_rsp);
|
||||
startRegs.xbp = lul::TaggedUWord(mc->mc_rbp);
|
||||
# elif defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android)
|
||||
startRegs.r15 = lul::TaggedUWord(mc->arm_pc);
|
||||
startRegs.r14 = lul::TaggedUWord(mc->arm_lr);
|
||||
@ -1414,6 +1419,11 @@ static void DoLULBacktrace(PSLockRef aLock,
|
||||
startRegs.x29 = lul::TaggedUWord(mc->regs[29]);
|
||||
startRegs.x30 = lul::TaggedUWord(mc->regs[30]);
|
||||
startRegs.sp = lul::TaggedUWord(mc->sp);
|
||||
# elif defined(GP_PLAT_arm64_freebsd)
|
||||
startRegs.pc = lul::TaggedUWord(mc->mc_gpregs.gp_elr);
|
||||
startRegs.x29 = lul::TaggedUWord(mc->mc_gpregs.gp_x[29]);
|
||||
startRegs.x30 = lul::TaggedUWord(mc->mc_gpregs.gp_lr);
|
||||
startRegs.sp = lul::TaggedUWord(mc->mc_gpregs.gp_sp);
|
||||
# elif defined(GP_PLAT_x86_linux) || defined(GP_PLAT_x86_android)
|
||||
startRegs.xip = lul::TaggedUWord(mc->gregs[REG_EIP]);
|
||||
startRegs.xsp = lul::TaggedUWord(mc->gregs[REG_ESP]);
|
||||
@ -1460,13 +1470,15 @@ static void DoLULBacktrace(PSLockRef aLock,
|
||||
lul::StackImage stackImg;
|
||||
|
||||
{
|
||||
# if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_amd64_android)
|
||||
# if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_amd64_android) || \
|
||||
defined(GP_PLAT_amd64_freebsd)
|
||||
uintptr_t rEDZONE_SIZE = 128;
|
||||
uintptr_t start = startRegs.xsp.Value() - rEDZONE_SIZE;
|
||||
# elif defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android)
|
||||
uintptr_t rEDZONE_SIZE = 0;
|
||||
uintptr_t start = startRegs.r13.Value() - rEDZONE_SIZE;
|
||||
# elif defined(GP_PLAT_arm64_linux) || defined(GP_PLAT_arm64_android)
|
||||
# elif defined(GP_PLAT_arm64_linux) || defined(GP_PLAT_arm64_android) || \
|
||||
defined(GP_PLAT_arm64_freebsd)
|
||||
uintptr_t rEDZONE_SIZE = 0;
|
||||
uintptr_t start = startRegs.sp.Value() - rEDZONE_SIZE;
|
||||
# elif defined(GP_PLAT_x86_linux) || defined(GP_PLAT_x86_android)
|
||||
@ -2021,7 +2033,7 @@ class Sampler {
|
||||
const TimeStamp& aNow, const Func& aProcessRegs);
|
||||
|
||||
private:
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android) || defined(GP_OS_freebsd)
|
||||
// Used to restore the SIGPROF handler when ours is removed.
|
||||
struct sigaction mOldSigprofHandler;
|
||||
|
||||
@ -2081,7 +2093,8 @@ class SamplerThread {
|
||||
// The OS-specific handle for the sampler thread.
|
||||
#if defined(GP_OS_windows)
|
||||
HANDLE mThread;
|
||||
#elif defined(GP_OS_darwin) || defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
#elif defined(GP_OS_darwin) || defined(GP_OS_linux) || \
|
||||
defined(GP_OS_android) || defined(GP_OS_freebsd)
|
||||
pthread_t mThread;
|
||||
#endif
|
||||
|
||||
@ -2295,7 +2308,7 @@ void SamplerThread::Run() {
|
||||
# include "platform-win32.cpp"
|
||||
#elif defined(GP_OS_darwin)
|
||||
# include "platform-macos.cpp"
|
||||
#elif defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
#elif defined(GP_OS_linux) || defined(GP_OS_android) || defined(GP_OS_freebsd)
|
||||
# include "platform-linux-android.cpp"
|
||||
#else
|
||||
# error "bad platform"
|
||||
|
@ -23,7 +23,9 @@
|
||||
#include <dlfcn.h>
|
||||
#include <elf.h>
|
||||
#include <fcntl.h>
|
||||
#include <features.h>
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
# include <features.h>
|
||||
#endif
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
@ -32,7 +34,7 @@
|
||||
#if defined(MOZ_LINKER)
|
||||
# include "AutoObjectMapper.h"
|
||||
#endif
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android) || defined(GP_OS_freebsd)
|
||||
# include <link.h> // dl_phdr_info, ElfW()
|
||||
#else
|
||||
# error "Unexpected configuration"
|
||||
@ -44,6 +46,10 @@ extern "C" MOZ_EXPORT __attribute__((weak)) int dl_iterate_phdr(
|
||||
void* data);
|
||||
#endif
|
||||
|
||||
#if defined(GP_OS_freebsd) && !defined(ElfW)
|
||||
# define ElfW(type) Elf_##type
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Starting imports from toolkit/crashreporter/google-breakpad/, as needed by
|
||||
// this file when moved to mozglue.
|
||||
@ -179,7 +185,8 @@ class MemoryMappedFile {
|
||||
}
|
||||
|
||||
#if defined(__x86_64__) || defined(__aarch64__) || \
|
||||
(defined(__mips__) && _MIPS_SIM == _ABI64)
|
||||
(defined(__mips__) && _MIPS_SIM == _ABI64) || \
|
||||
!(defined(GP_OS_linux) || defined(GP_OS_android))
|
||||
|
||||
struct stat st;
|
||||
if (fstat(fd, &st) == -1 || st.st_size < 0) {
|
||||
@ -764,6 +771,7 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
// Read info from /proc/self/maps. We ignore most of it.
|
||||
pid_t pid = mozilla::baseprofiler::profiler_current_process_id();
|
||||
char path[PATH_MAX];
|
||||
@ -790,12 +798,12 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
||||
continue;
|
||||
}
|
||||
|
||||
#if defined(GP_OS_linux)
|
||||
# if defined(GP_OS_linux)
|
||||
// Try to establish the main executable's load address.
|
||||
if (exeNameLen > 0 && strcmp(modulePath, exeName) == 0) {
|
||||
exeExeAddr = start;
|
||||
}
|
||||
#elif defined(GP_OS_android)
|
||||
# elif defined(GP_OS_android)
|
||||
// Use /proc/pid/maps to get the dalvik-jit section since it has no
|
||||
// associated phdrs.
|
||||
if (0 == strcmp(modulePath, "/dev/ashmem/dalvik-jit-code-cache")) {
|
||||
@ -807,8 +815,9 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
std::vector<LoadedLibraryInfo> libInfoList;
|
||||
|
||||
|
@ -83,6 +83,14 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(GP_OS_freebsd)
|
||||
|
||||
# ifndef ElfW
|
||||
# define ElfW(type) Elf_##type
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace lul {
|
||||
|
||||
// Traits classes so consumers can write templatized code to deal
|
||||
|
@ -1409,8 +1409,9 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
|
||||
continue;
|
||||
}
|
||||
|
||||
#if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux) || \
|
||||
defined(GP_PLAT_amd64_android) || defined(GP_PLAT_x86_android)
|
||||
#if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux) || \
|
||||
defined(GP_PLAT_amd64_android) || defined(GP_PLAT_x86_android) || \
|
||||
defined(GP_PLAT_amd64_freebsd)
|
||||
// There's no RuleSet for the specified address. On amd64/x86_linux, see if
|
||||
// it's possible to recover the caller's frame by using the frame pointer.
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
void read_procmaps(lul::LUL* aLUL) {
|
||||
MOZ_ASSERT(aLUL->CountMappings() == 0);
|
||||
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android) || defined(GP_OS_freebsd)
|
||||
SharedLibraryInfo info = SharedLibraryInfo::GetInfoForSelf();
|
||||
|
||||
for (size_t i = 0; i < info.GetSize(); i++) {
|
||||
|
@ -32,7 +32,7 @@ if CONFIG['MOZ_GECKO_PROFILER']:
|
||||
'core/RegisteredThread.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['OS_TARGET'] in ('Android', 'Linux'):
|
||||
if CONFIG['OS_TARGET'] in ('Android', 'Linux', 'FreeBSD'):
|
||||
if CONFIG['CPU_ARCH'] in ('arm', 'aarch64', 'x86', 'x86_64', 'mips64'):
|
||||
UNIFIED_SOURCES += [
|
||||
'lul/AutoObjectMapper.cpp',
|
||||
@ -47,7 +47,7 @@ if CONFIG['MOZ_GECKO_PROFILER']:
|
||||
SOURCES += [
|
||||
'core/shared-libraries-linux.cc',
|
||||
]
|
||||
if CONFIG['CPU_ARCH'] == 'arm':
|
||||
if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['OS_TARGET'] != 'FreeBSD':
|
||||
SOURCES += [
|
||||
'core/EHABIStackWalk.cpp',
|
||||
]
|
||||
|
@ -795,6 +795,11 @@ bool MFBT_API MozDescribeCodeAddress(void* aPC,
|
||||
aDetails->library[mozilla::ArrayLength(aDetails->library) - 1] = '\0';
|
||||
aDetails->loffset = (char*)aPC - (char*)info.dli_fbase;
|
||||
|
||||
# if !defined(XP_FREEBSD)
|
||||
// On FreeBSD, dli_sname is unusably bad, it often returns things like
|
||||
// 'gtk_xtbin_new' or 'XRE_GetBootstrap' instead of long C++ symbols. Just let
|
||||
// GetFunction do the lookup directly in the ELF image.
|
||||
|
||||
const char* symbol = info.dli_sname;
|
||||
if (!symbol || symbol[0] == '\0') {
|
||||
return true;
|
||||
@ -809,6 +814,8 @@ bool MFBT_API MozDescribeCodeAddress(void* aPC,
|
||||
}
|
||||
|
||||
aDetails->foffset = (char*)aPC - (char*)info.dli_saddr;
|
||||
# endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,7 @@ MFBT_API void FramePointerStackWalk(MozWalkStackCallback aCallback,
|
||||
void* aClosure, void** aBp,
|
||||
void* aStackEnd);
|
||||
|
||||
#ifdef XP_LINUX
|
||||
#if defined(XP_LINUX) || defined(XP_FREEBSD)
|
||||
MFBT_API void DemangleSymbol(const char* aSymbol, char* aBuffer, int aBufLen);
|
||||
#endif
|
||||
|
||||
|
@ -57,7 +57,7 @@
|
||||
#endif
|
||||
|
||||
// Map Linux macros to their Apple equivalents.
|
||||
#if __APPLE__
|
||||
#if __APPLE__ || __FreeBSD__
|
||||
#ifndef __LITTLE_ENDIAN
|
||||
#define __LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
|
||||
#endif // __LITTLE_ENDIAN
|
||||
|
@ -35,6 +35,10 @@
|
||||
#include "common/linux/linux_libc_support.h"
|
||||
#include "common/linux/elfutils-inl.h"
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
# define ElfW(type) Elf_##type
|
||||
#endif
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
namespace {
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include <sanitizer/msan_interface.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||
#define sys_mmap mmap
|
||||
#define sys_munmap munmap
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
|
@ -4532,5 +4532,22 @@ struct kernel_statfs {
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define sys_readlink readlink
|
||||
|
||||
#define sys_open open
|
||||
#define sys_close close
|
||||
#define sys_fstat fstat
|
||||
#define sys_fstat64 fstat
|
||||
#define kernel_stat stat
|
||||
#define kernel_stat64 stat
|
||||
#define sys_mmap mmap
|
||||
#define sys_munmap munmap
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -73,6 +73,8 @@ def gecko_profiler(target):
|
||||
return target.cpu in ('aarch64', 'arm', 'x86', 'x86_64')
|
||||
elif target.kernel == 'Linux':
|
||||
return target.cpu in ('aarch64', 'arm', 'x86', 'x86_64', 'mips64')
|
||||
elif target.kernel == 'FreeBSD':
|
||||
return target.cpu in ('aarch64', 'x86_64')
|
||||
return target.os in ('OSX', 'WINNT')
|
||||
|
||||
@depends(gecko_profiler)
|
||||
@ -88,7 +90,7 @@ set_define('MOZ_GECKO_PROFILER', gecko_profiler_define)
|
||||
# (for symbol table dumping).
|
||||
@depends(gecko_profiler, target)
|
||||
def gecko_profiler_parse_elf(value, target):
|
||||
# Currently we only want to build this code on Linux (including Android).
|
||||
# Currently we only want to build this code on Linux (including Android) and BSD.
|
||||
# For Android, this is in order to dump symbols from Android system, where
|
||||
# on other platforms there exist alternatives that don't require bloating
|
||||
# up our binary size. For Linux more generally, we use this in profile
|
||||
@ -97,7 +99,7 @@ def gecko_profiler_parse_elf(value, target):
|
||||
# MozDescribeCodeAddress to call into some Rust crates that parse ELF and
|
||||
# DWARF data, but build system issues currently prevent Rust from being
|
||||
# used in mozglue.)
|
||||
if value and target.kernel == 'Linux':
|
||||
if value and (target.kernel == 'Linux' or target.kernel == 'FreeBSD'):
|
||||
return True
|
||||
|
||||
set_config('MOZ_GECKO_PROFILER_PARSE_ELF', gecko_profiler_parse_elf)
|
||||
|
@ -90,6 +90,16 @@
|
||||
# define GP_ARCH_amd64 1
|
||||
# define GP_OS_darwin 1
|
||||
|
||||
#elif defined(__FreeBSD__) && defined(__x86_64__)
|
||||
# define GP_PLAT_amd64_freebsd 1
|
||||
# define GP_ARCH_amd64 1
|
||||
# define GP_OS_freebsd 1
|
||||
|
||||
#elif defined(__FreeBSD__) && defined(__aarch64__)
|
||||
# define GP_PLAT_arm64_freebsd 1
|
||||
# define GP_ARCH_arm64 1
|
||||
# define GP_OS_freebsd 1
|
||||
|
||||
#elif (defined(_MSC_VER) || defined(__MINGW32__)) && \
|
||||
(defined(_M_IX86) || defined(__i386__))
|
||||
# define GP_PLAT_x86_windows 1
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
#ifdef XP_LINUX
|
||||
#if defined(XP_LINUX) || defined(XP_FREEBSD)
|
||||
static char* SearchSymbolTable(SymbolTable& aTable, uint32_t aOffset) {
|
||||
size_t index;
|
||||
bool exact =
|
||||
@ -46,7 +46,7 @@ bool ProfilerCodeAddressService::GetFunction(const void* aPc,
|
||||
nsACString& aResult) {
|
||||
Entry& entry = GetEntry(aPc);
|
||||
|
||||
#ifdef XP_LINUX
|
||||
#if defined(XP_LINUX) || defined(XP_FREEBSD)
|
||||
// On Linux, most symbols will not be found by the MozDescribeCodeAddress call
|
||||
// that GetEntry does. So we read the symbol table directly from the ELF
|
||||
// image.
|
||||
|
@ -28,12 +28,15 @@
|
||||
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
// SUCH DAMAGE.
|
||||
|
||||
// This file is used for both Linux and Android.
|
||||
// This file is used for both Linux and Android as well as FreeBSD.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#if defined(GP_OS_freebsd)
|
||||
# include <sys/thr.h>
|
||||
#endif
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <sys/time.h>
|
||||
@ -63,7 +66,9 @@
|
||||
#include "mozilla/LinuxSignal.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "common/linux/breakpad_getcontext.h"
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
# include "common/linux/breakpad_getcontext.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <list>
|
||||
@ -73,11 +78,15 @@ using namespace mozilla;
|
||||
int profiler_current_process_id() { return getpid(); }
|
||||
|
||||
int profiler_current_thread_id() {
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
// glibc doesn't provide a wrapper for gettid().
|
||||
#if defined(__linux__) || !defined(__BIONIC__)
|
||||
return static_cast<int>(static_cast<pid_t>(syscall(SYS_gettid)));
|
||||
#elif defined(GP_OS_freebsd)
|
||||
long id;
|
||||
(void)thr_self(&id);
|
||||
return static_cast<int>(id);
|
||||
#else
|
||||
return static_cast<int>(gettid());
|
||||
# error "bad platform"
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -88,27 +97,37 @@ static void PopulateRegsFromContext(Registers& aRegs, ucontext_t* aContext) {
|
||||
mcontext_t& mcontext = aContext->uc_mcontext;
|
||||
|
||||
// Extracting the sample from the context is extremely machine dependent.
|
||||
#if defined(GP_ARCH_x86)
|
||||
#if defined(GP_PLAT_x86_linux) || defined(GP_PLAT_x86_android)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]);
|
||||
aRegs.mLR = 0;
|
||||
#elif defined(GP_ARCH_amd64)
|
||||
#elif defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_amd64_android)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]);
|
||||
aRegs.mLR = 0;
|
||||
#elif defined(GP_ARCH_arm)
|
||||
#elif defined(GP_PLAT_amd64_freebsd)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.mc_rip);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.mc_rsp);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.mc_rbp);
|
||||
aRegs.mLR = 0;
|
||||
#elif defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.arm_pc);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.arm_sp);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.arm_fp);
|
||||
aRegs.mLR = reinterpret_cast<Address>(mcontext.arm_lr);
|
||||
#elif defined(GP_ARCH_arm64)
|
||||
#elif defined(GP_PLAT_arm64_linux) || defined(GP_PLAT_arm64_android)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.pc);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.sp);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.regs[29]);
|
||||
aRegs.mLR = reinterpret_cast<Address>(mcontext.regs[30]);
|
||||
#elif defined(GP_ARCH_mips64)
|
||||
#elif defined(GP_PLAT_arm64_freebsd)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.mc_gpregs.gp_elr);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.mc_gpregs.gp_sp);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.mc_gpregs.gp_x[29]);
|
||||
aRegs.mLR = reinterpret_cast<Address>(mcontext.mc_gpregs.gp_lr);
|
||||
#elif defined(GP_PLAT_mips64_linux) || defined(GP_PLAT_mips64_android)
|
||||
aRegs.mPC = reinterpret_cast<Address>(mcontext.pc);
|
||||
aRegs.mSP = reinterpret_cast<Address>(mcontext.gregs[29]);
|
||||
aRegs.mFP = reinterpret_cast<Address>(mcontext.gregs[30]);
|
||||
@ -122,9 +141,15 @@ static void PopulateRegsFromContext(Registers& aRegs, ucontext_t* aContext) {
|
||||
# define SYS_tgkill __NR_tgkill
|
||||
#endif
|
||||
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
int tgkill(pid_t tgid, pid_t tid, int signalno) {
|
||||
return syscall(SYS_tgkill, tgid, tid, signalno);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GP_OS_freebsd)
|
||||
# define tgkill thr_kill2
|
||||
#endif
|
||||
|
||||
class PlatformData {
|
||||
public:
|
||||
@ -463,7 +488,7 @@ void SamplerThread::Stop(PSLockRef aLock) {
|
||||
// END SamplerThread target specifics
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(GP_OS_linux)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_freebsd)
|
||||
|
||||
// We use pthread_atfork() to temporarily disable signal delivery during any
|
||||
// fork() call. Without that, fork() can be repeatedly interrupted by signal
|
||||
|
@ -134,11 +134,12 @@
|
||||
# include "EHABIStackWalk.h"
|
||||
#endif
|
||||
|
||||
// Linux builds use LUL, which uses DWARF info to unwind stacks.
|
||||
#if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux) || \
|
||||
defined(GP_PLAT_amd64_android) || defined(GP_PLAT_x86_android) || \
|
||||
defined(GP_PLAT_mips64_linux) || defined(GP_PLAT_arm64_linux) || \
|
||||
defined(GP_PLAT_arm64_android)
|
||||
// Linux/BSD builds use LUL, which uses DWARF info to unwind stacks.
|
||||
#if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux) || \
|
||||
defined(GP_PLAT_amd64_android) || defined(GP_PLAT_x86_android) || \
|
||||
defined(GP_PLAT_mips64_linux) || defined(GP_PLAT_arm64_linux) || \
|
||||
defined(GP_PLAT_arm64_android) || defined(GP_PLAT_amd64_freebsd) || \
|
||||
defined(GP_PLAT_arm64_freebsd)
|
||||
# define HAVE_NATIVE_UNWIND
|
||||
# define USE_LUL_STACKWALK
|
||||
# include "lul/LulMain.h"
|
||||
@ -172,7 +173,7 @@
|
||||
# define VALGRIND_MAKE_MEM_DEFINED(_addr, _len) ((void)0)
|
||||
#endif
|
||||
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android) || defined(GP_OS_freebsd)
|
||||
# include <ucontext.h>
|
||||
#endif
|
||||
|
||||
@ -710,7 +711,7 @@ class ActivePS {
|
||||
? new ProfilerIOInterposeObserver()
|
||||
: nullptr),
|
||||
mIsPaused(false)
|
||||
#if defined(GP_OS_linux)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_freebsd)
|
||||
,
|
||||
mWasPaused(false)
|
||||
#endif
|
||||
@ -1074,7 +1075,7 @@ class ActivePS {
|
||||
|
||||
PS_GET_AND_SET(bool, IsPaused)
|
||||
|
||||
#if defined(GP_OS_linux)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_freebsd)
|
||||
PS_GET_AND_SET(bool, WasPaused)
|
||||
#endif
|
||||
|
||||
@ -1283,7 +1284,7 @@ class ActivePS {
|
||||
// Is the profiler paused?
|
||||
bool mIsPaused;
|
||||
|
||||
#if defined(GP_OS_linux)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_freebsd)
|
||||
// Used to record whether the profiler was paused just before forking. False
|
||||
// at all times except just before/after forking.
|
||||
bool mWasPaused;
|
||||
@ -1454,7 +1455,7 @@ class Registers {
|
||||
Address mSP; // Stack pointer.
|
||||
Address mFP; // Frame pointer.
|
||||
Address mLR; // ARM link register.
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android) || defined(GP_OS_freebsd)
|
||||
// This contains all the registers, which means it duplicates the four fields
|
||||
// above. This is ok.
|
||||
ucontext_t* mContext; // The context from the signal handler.
|
||||
@ -1839,6 +1840,10 @@ static void DoLULBacktrace(PSLockRef aLock,
|
||||
startRegs.xip = lul::TaggedUWord(mc->gregs[REG_RIP]);
|
||||
startRegs.xsp = lul::TaggedUWord(mc->gregs[REG_RSP]);
|
||||
startRegs.xbp = lul::TaggedUWord(mc->gregs[REG_RBP]);
|
||||
# elif defined(GP_PLAT_amd64_freebsd)
|
||||
startRegs.xip = lul::TaggedUWord(mc->mc_rip);
|
||||
startRegs.xsp = lul::TaggedUWord(mc->mc_rsp);
|
||||
startRegs.xbp = lul::TaggedUWord(mc->mc_rbp);
|
||||
# elif defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android)
|
||||
startRegs.r15 = lul::TaggedUWord(mc->arm_pc);
|
||||
startRegs.r14 = lul::TaggedUWord(mc->arm_lr);
|
||||
@ -1851,6 +1856,11 @@ static void DoLULBacktrace(PSLockRef aLock,
|
||||
startRegs.x29 = lul::TaggedUWord(mc->regs[29]);
|
||||
startRegs.x30 = lul::TaggedUWord(mc->regs[30]);
|
||||
startRegs.sp = lul::TaggedUWord(mc->sp);
|
||||
# elif defined(GP_PLAT_arm64_freebsd)
|
||||
startRegs.pc = lul::TaggedUWord(mc->mc_gpregs.gp_elr);
|
||||
startRegs.x29 = lul::TaggedUWord(mc->mc_gpregs.gp_x[29]);
|
||||
startRegs.x30 = lul::TaggedUWord(mc->mc_gpregs.gp_lr);
|
||||
startRegs.sp = lul::TaggedUWord(mc->mc_gpregs.gp_sp);
|
||||
# elif defined(GP_PLAT_x86_linux) || defined(GP_PLAT_x86_android)
|
||||
startRegs.xip = lul::TaggedUWord(mc->gregs[REG_EIP]);
|
||||
startRegs.xsp = lul::TaggedUWord(mc->gregs[REG_ESP]);
|
||||
@ -1897,13 +1907,15 @@ static void DoLULBacktrace(PSLockRef aLock,
|
||||
lul::StackImage stackImg;
|
||||
|
||||
{
|
||||
# if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_amd64_android)
|
||||
# if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_amd64_android) || \
|
||||
defined(GP_PLAT_amd64_freebsd)
|
||||
uintptr_t rEDZONE_SIZE = 128;
|
||||
uintptr_t start = startRegs.xsp.Value() - rEDZONE_SIZE;
|
||||
# elif defined(GP_PLAT_arm_linux) || defined(GP_PLAT_arm_android)
|
||||
uintptr_t rEDZONE_SIZE = 0;
|
||||
uintptr_t start = startRegs.r13.Value() - rEDZONE_SIZE;
|
||||
# elif defined(GP_PLAT_arm64_linux) || defined(GP_PLAT_arm64_android)
|
||||
# elif defined(GP_PLAT_arm64_linux) || defined(GP_PLAT_arm64_android) || \
|
||||
defined(GP_PLAT_arm64_freebsd)
|
||||
uintptr_t rEDZONE_SIZE = 0;
|
||||
uintptr_t start = startRegs.sp.Value() - rEDZONE_SIZE;
|
||||
# elif defined(GP_PLAT_x86_linux) || defined(GP_PLAT_x86_android)
|
||||
@ -2745,7 +2757,7 @@ class Sampler {
|
||||
const TimeStamp& aNow, const Func& aProcessRegs);
|
||||
|
||||
private:
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android) || defined(GP_OS_freebsd)
|
||||
// Used to restore the SIGPROF handler when ours is removed.
|
||||
struct sigaction mOldSigprofHandler;
|
||||
|
||||
@ -2854,7 +2866,8 @@ class SamplerThread {
|
||||
// The OS-specific handle for the sampler thread.
|
||||
#if defined(GP_OS_windows)
|
||||
HANDLE mThread;
|
||||
#elif defined(GP_OS_darwin) || defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
#elif defined(GP_OS_darwin) || defined(GP_OS_linux) || \
|
||||
defined(GP_OS_android) || defined(GP_OS_freebsd)
|
||||
pthread_t mThread;
|
||||
#endif
|
||||
|
||||
@ -3330,7 +3343,7 @@ void SamplerThread::Run() {
|
||||
# include "platform-win32.cpp"
|
||||
#elif defined(GP_OS_darwin)
|
||||
# include "platform-macos.cpp"
|
||||
#elif defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
#elif defined(GP_OS_linux) || defined(GP_OS_android) || defined(GP_OS_freebsd)
|
||||
# include "platform-linux-android.cpp"
|
||||
#else
|
||||
# error "bad platform"
|
||||
|
@ -25,13 +25,15 @@
|
||||
#include "common/linux/file_id.h"
|
||||
#include <algorithm>
|
||||
#include <dlfcn.h>
|
||||
#include <features.h>
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
# include <features.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
#if defined(MOZ_LINKER)
|
||||
# include "AutoObjectMapper.h"
|
||||
#endif
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android) || defined(GP_OS_freebsd)
|
||||
# include <link.h> // dl_phdr_info
|
||||
#else
|
||||
# error "Unexpected configuration"
|
||||
@ -185,6 +187,7 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
// Read info from /proc/self/maps. We ignore most of it.
|
||||
pid_t pid = profiler_current_process_id();
|
||||
char path[PATH_MAX];
|
||||
@ -211,12 +214,12 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
||||
continue;
|
||||
}
|
||||
|
||||
#if defined(GP_OS_linux)
|
||||
# if defined(GP_OS_linux)
|
||||
// Try to establish the main executable's load address.
|
||||
if (exeNameLen > 0 && strcmp(modulePath, exeName) == 0) {
|
||||
exeExeAddr = start;
|
||||
}
|
||||
#elif defined(GP_OS_android)
|
||||
# elif defined(GP_OS_android)
|
||||
// Use /proc/pid/maps to get the dalvik-jit section since it has no
|
||||
// associated phdrs.
|
||||
if (0 == strcmp(modulePath, "/dev/ashmem/dalvik-jit-code-cache")) {
|
||||
@ -228,8 +231,9 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
nsTArray<LoadedLibraryInfo> libInfoList;
|
||||
|
||||
|
@ -83,6 +83,14 @@
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(GP_OS_freebsd)
|
||||
|
||||
# ifndef ElfW
|
||||
# define ElfW(type) Elf_##type
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
namespace lul {
|
||||
|
||||
// Traits classes so consumers can write templatized code to deal
|
||||
|
@ -1405,8 +1405,9 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
|
||||
continue;
|
||||
}
|
||||
|
||||
#if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux) || \
|
||||
defined(GP_PLAT_amd64_android) || defined(GP_PLAT_x86_android)
|
||||
#if defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux) || \
|
||||
defined(GP_PLAT_amd64_android) || defined(GP_PLAT_x86_android) || \
|
||||
defined(GP_PLAT_amd64_freebsd)
|
||||
// There's no RuleSet for the specified address. On amd64/x86_linux, see if
|
||||
// it's possible to recover the caller's frame by using the frame pointer.
|
||||
|
||||
@ -1517,7 +1518,8 @@ void LUL::Unwind(/*OUT*/ uintptr_t* aFramePCs,
|
||||
}
|
||||
}
|
||||
#endif // defined(GP_PLAT_amd64_linux) || defined(GP_PLAT_x86_linux) ||
|
||||
// defined(GP_PLAT_amd64_android) || defined(GP_PLAT_x86_android)
|
||||
// defined(GP_PLAT_amd64_android) || defined(GP_PLAT_x86_android) ||
|
||||
// defined(GP_PLAT_amd64_freebsd)
|
||||
|
||||
// We failed to recover a frame either using CFI or FP chasing, and we
|
||||
// have no other ways to recover the frame. So we have to give up.
|
||||
|
@ -24,7 +24,7 @@
|
||||
void read_procmaps(lul::LUL* aLUL) {
|
||||
MOZ_ASSERT(aLUL->CountMappings() == 0);
|
||||
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android)
|
||||
#if defined(GP_OS_linux) || defined(GP_OS_android) || defined(GP_OS_freebsd)
|
||||
SharedLibraryInfo info = SharedLibraryInfo::GetInfoForSelf();
|
||||
|
||||
for (size_t i = 0; i < info.GetSize(); i++) {
|
||||
|
@ -59,7 +59,7 @@ if CONFIG['MOZ_GECKO_PROFILER']:
|
||||
'gecko/nsProfiler.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['OS_TARGET'] in ('Android', 'Linux'):
|
||||
if CONFIG['OS_TARGET'] in ('Android', 'Linux', 'FreeBSD'):
|
||||
if CONFIG['CPU_ARCH'] in ('arm', 'aarch64', 'x86', 'x86_64', 'mips64'):
|
||||
UNIFIED_SOURCES += [
|
||||
'lul/AutoObjectMapper.cpp',
|
||||
@ -83,7 +83,7 @@ if CONFIG['MOZ_GECKO_PROFILER']:
|
||||
]
|
||||
if not CONFIG['HAVE_GETCONTEXT']:
|
||||
SOURCES += ['/toolkit/crashreporter/google-breakpad/src/common/linux/breakpad_getcontext.S']
|
||||
if CONFIG['CPU_ARCH'] == 'arm':
|
||||
if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['OS_TARGET'] != 'FreeBSD':
|
||||
SOURCES += [
|
||||
'core/EHABIStackWalk.cpp',
|
||||
]
|
||||
|
@ -39,7 +39,7 @@ class ProfilerCodeAddressService : public mozilla::CodeAddressService<> {
|
||||
bool GetFunction(const void* aPc, nsACString& aResult);
|
||||
|
||||
private:
|
||||
#ifdef XP_LINUX
|
||||
#if defined(XP_LINUX) || defined(XP_FREEBSD)
|
||||
// Map of library names (owned by mLibraryStrings) to SymbolTables filled
|
||||
// in by profiler_get_symbol_table.
|
||||
mozilla::HashMap<const char*, mozilla::SymbolTable,
|
||||
|
Loading…
Reference in New Issue
Block a user