mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 17:23:59 +00:00
Bug 1050445 - Part 5: Print stacks. r=mccr8
--HG-- extra : rebase_source : 6397f4a2021944cc114e871c3d9b8ef0ea2636c8
This commit is contained in:
parent
4099538971
commit
9d7a41f0f8
@ -12,7 +12,10 @@
|
|||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
|
|
||||||
#ifndef MOZ_CALLSTACK_DISABLED
|
#ifndef MOZ_CALLSTACK_DISABLED
|
||||||
|
#include "CodeAddressService.h"
|
||||||
|
#include "nsHashKeys.h"
|
||||||
#include "nsStackWalk.h"
|
#include "nsStackWalk.h"
|
||||||
|
#include "nsTHashtable.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "mozilla/CondVar.h"
|
#include "mozilla/CondVar.h"
|
||||||
@ -58,6 +61,7 @@ void
|
|||||||
BlockingResourceBase::GetStackTrace(AcquisitionState& aState)
|
BlockingResourceBase::GetStackTrace(AcquisitionState& aState)
|
||||||
{
|
{
|
||||||
#ifndef MOZ_CALLSTACK_DISABLED
|
#ifndef MOZ_CALLSTACK_DISABLED
|
||||||
|
// Skip this function and the calling function.
|
||||||
const uint32_t kSkipFrames = 2;
|
const uint32_t kSkipFrames = 2;
|
||||||
|
|
||||||
aState.Clear();
|
aState.Clear();
|
||||||
@ -113,6 +117,70 @@ PrintCycle(const BlockingResourceBase::DDT::ResourceAcquisitionArray* aCycle, ns
|
|||||||
return maybeImminent;
|
return maybeImminent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef MOZ_CALLSTACK_DISABLED
|
||||||
|
class CodeAddressServiceWriter MOZ_FINAL
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit CodeAddressServiceWriter(nsACString& aOut) : mOut(aOut) {}
|
||||||
|
|
||||||
|
void Write(const char* aFmt, ...) const
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, aFmt);
|
||||||
|
|
||||||
|
const size_t kMaxLength = 4096;
|
||||||
|
char buffer[kMaxLength];
|
||||||
|
|
||||||
|
vsnprintf(buffer, kMaxLength, aFmt, ap);
|
||||||
|
mOut += buffer;
|
||||||
|
fprintf(stderr, "%s", buffer);
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsACString& mOut;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CodeAddressServiceLock MOZ_FINAL
|
||||||
|
{
|
||||||
|
static void Unlock() { }
|
||||||
|
static void Lock() { }
|
||||||
|
static bool IsLocked() { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CodeAddressServiceStringAlloc MOZ_FINAL
|
||||||
|
{
|
||||||
|
static char* copy(const char* aString) { return ::strdup(aString); }
|
||||||
|
static void free(char* aString) { ::free(aString); }
|
||||||
|
};
|
||||||
|
|
||||||
|
class CodeAddressServiceStringTable MOZ_FINAL
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CodeAddressServiceStringTable() : mSet(32) {}
|
||||||
|
|
||||||
|
const char* Intern(const char* aString)
|
||||||
|
{
|
||||||
|
nsCharPtrHashKey* e = mSet.PutEntry(aString);
|
||||||
|
return e->GetKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||||
|
{
|
||||||
|
return mSet.SizeOfExcludingThis(aMallocSizeOf);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef nsTHashtable<nsCharPtrHashKey> StringSet;
|
||||||
|
StringSet mSet;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef CodeAddressService<CodeAddressServiceStringTable,
|
||||||
|
CodeAddressServiceStringAlloc,
|
||||||
|
CodeAddressServiceWriter,
|
||||||
|
CodeAddressServiceLock> WalkTheStackCodeAddressService;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BlockingResourceBase::Print(nsACString& aOut) const
|
BlockingResourceBase::Print(nsACString& aOut) const
|
||||||
@ -131,7 +199,18 @@ BlockingResourceBase::Print(nsACString& aOut) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
fputs(" calling context\n", stderr);
|
fputs(" calling context\n", stderr);
|
||||||
|
#ifdef MOZ_CALLSTACK_DISABLED
|
||||||
fputs(" [stack trace unavailable]\n", stderr);
|
fputs(" [stack trace unavailable]\n", stderr);
|
||||||
|
#else
|
||||||
|
const AcquisitionState& state = acquired ? mAcquired : mFirstSeen;
|
||||||
|
|
||||||
|
WalkTheStackCodeAddressService addressService;
|
||||||
|
CodeAddressServiceWriter writer(aOut);
|
||||||
|
for (uint32_t i = 0; i < state.Length(); i++) {
|
||||||
|
addressService.WriteLocation(writer, state[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return acquired;
|
return acquired;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user