зеркало из https://github.com/mozilla/gecko-dev.git
Bug 718025 - Add support for stacktraces on Windows to the built-in profiler; r=jrmuizel
This commit is contained in:
Родитель
265d407dc3
Коммит
9600e90ef3
|
@ -56,6 +56,13 @@
|
|||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
#define USE_NS_STACKWALK
|
||||
#endif
|
||||
#ifdef USE_NS_STACKWALK
|
||||
#include "nsStackWalk.h"
|
||||
#endif
|
||||
|
||||
using std::string;
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -272,7 +279,12 @@ class TableTicker: public Sampler {
|
|||
{
|
||||
return &mProfile;
|
||||
}
|
||||
private:
|
||||
|
||||
private:
|
||||
// Not implemented on platforms which do not support backtracing
|
||||
void doBacktrace(Profile &aProfile);
|
||||
|
||||
private:
|
||||
Profile mProfile;
|
||||
Stack *mStack;
|
||||
bool mSaveRequested;
|
||||
|
@ -337,8 +349,7 @@ void TableTicker::HandleSaveRequest()
|
|||
}
|
||||
|
||||
#ifdef USE_BACKTRACE
|
||||
static
|
||||
void doBacktrace(Profile &aProfile)
|
||||
void TableTicker::doBacktrace(Profile &aProfile)
|
||||
{
|
||||
void *array[100];
|
||||
int count = backtrace (array, 100);
|
||||
|
@ -352,6 +363,45 @@ void doBacktrace(Profile &aProfile)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_NS_STACKWALK
|
||||
typedef struct {
|
||||
void* array[];
|
||||
size_t size;
|
||||
size_t count;
|
||||
} PCArray;
|
||||
|
||||
static
|
||||
void StackWalkCallback(void* aPC, void* aClosure)
|
||||
{
|
||||
PCArray* array = static_cast<PCArray*>(aClosure);
|
||||
if (array->count >= array->size) {
|
||||
// too many frames, ignore
|
||||
return;
|
||||
}
|
||||
array->array[array->count++] = aPC;
|
||||
}
|
||||
|
||||
void TableTicker::doBacktrace(Profile &aProfile)
|
||||
{
|
||||
uintptr_t thread = GetThreadHandle(platform_data());
|
||||
MOZ_ASSERT(thread);
|
||||
void* pc_array[1000];
|
||||
PCArray array = {
|
||||
pc_array,
|
||||
mozilla::ArrayLength(array),
|
||||
0
|
||||
};
|
||||
nsresult rv = NS_StackWalk(StackWalkCallback, 0, &array, thread);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aProfile.addTag(ProfileEntry('s', "XRE_Main", 0));
|
||||
|
||||
for (size_t i = array.count; i > 0; --i) {
|
||||
aProfile.addTag(ProfileEntry('l', (const char*)array.array[i - 1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
void doSampleStackTrace(Stack *aStack, Profile &aProfile, TickSample *sample)
|
||||
{
|
||||
|
@ -395,7 +445,7 @@ void TableTicker::Tick(TickSample* sample)
|
|||
}
|
||||
|
||||
if (recordSample) {
|
||||
#ifdef USE_BACKTRACE
|
||||
#if defined(USE_BACKTRACE) || defined(USE_NS_STACKWALK)
|
||||
if (mUseStackWalk) {
|
||||
doBacktrace(mProfile);
|
||||
} else {
|
||||
|
|
|
@ -33,6 +33,11 @@ class Sampler::PlatformData : public Malloced {
|
|||
HANDLE profiled_thread_;
|
||||
};
|
||||
|
||||
uintptr_t
|
||||
Sampler::GetThreadHandle(Sampler::PlatformData* aData)
|
||||
{
|
||||
return (uintptr_t) aData->profiled_thread();
|
||||
}
|
||||
|
||||
class SamplerThread : public Thread {
|
||||
public:
|
||||
|
|
|
@ -203,6 +203,11 @@ class Sampler {
|
|||
|
||||
PlatformData* platform_data() { return data_; }
|
||||
|
||||
#ifdef XP_WIN
|
||||
// xxxehsan sucky hack :(
|
||||
static uintptr_t GetThreadHandle(PlatformData*);
|
||||
#endif
|
||||
|
||||
private:
|
||||
void SetActive(bool value) { NoBarrier_Store(&active_, value); }
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче