Bug 718025 - Add support for stacktraces on Windows to the built-in profiler; r=jrmuizel

This commit is contained in:
Ehsan Akhgari 2012-01-16 19:59:15 -05:00
parent 3c3f2843b5
commit c625f6071d
3 changed files with 64 additions and 4 deletions

View File

@ -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 {

View File

@ -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:

View File

@ -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); }