mmlr + bonefish:

* Move struct tracing_stack_trace to tracing.h header.
* Add tracing_find_caller_in_stack_trace(). Helper function to get the
  first return address of a stack trace that is not in one of the given
  address ranges.
* Add AbstractTracingEntryWithStackTrace::StackTrace() getter.
* Add tracing_is_entry_valid(). Checks, based on the additionally given
  time, whether a tracing entry is (probably) still in the tracing
  buffer.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@43070 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2011-11-01 17:16:29 +00:00
parent 506a6eb522
commit 69d7ad7dc5
2 changed files with 62 additions and 7 deletions

View File

@ -21,7 +21,11 @@ struct trace_entry {
uint32 flags : 6;
};
struct tracing_stack_trace;
struct tracing_stack_trace {
int32 depth;
addr_t return_addresses[0];
};
#ifdef __cplusplus
@ -134,6 +138,11 @@ public:
virtual void DumpStackTrace(TraceOutput& out);
tracing_stack_trace* StackTrace() const
{
return fStackTrace;
}
protected:
typedef AbstractTraceEntryWithStackTrace TraceEntryBase;
@ -244,8 +253,11 @@ private:
int dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter);
bool tracing_is_entry_valid(TraceEntry* entry, bigtime_t entryTime);
#endif // __cplusplus
#ifdef __cplusplus
extern "C" {
#endif
@ -254,8 +266,13 @@ uint8* alloc_tracing_buffer(size_t size);
uint8* alloc_tracing_buffer_memcpy(const void* source, size_t size, bool user);
char* alloc_tracing_buffer_strcpy(const char* source, size_t maxSize,
bool user);
struct tracing_stack_trace* capture_tracing_stack_trace(int32 maxCount,
int32 skipFrames, bool kernelOnly);
addr_t tracing_find_caller_in_stack_trace(
struct tracing_stack_trace* stackTrace, const addr_t excludeRanges[],
uint32 excludeRangeCount);
void lock_tracing_buffer();
void unlock_tracing_buffer();
status_t tracing_init(void);

View File

@ -23,12 +23,6 @@
#include <vm/vm.h>
struct tracing_stack_trace {
int32 depth;
addr_t return_addresses[0];
};
#if ENABLE_TRACING
//#define TRACE_TRACING
@ -1616,6 +1610,30 @@ capture_tracing_stack_trace(int32 maxCount, int32 skipFrames, bool kernelOnly)
}
addr_t
tracing_find_caller_in_stack_trace(struct tracing_stack_trace* stackTrace,
const addr_t excludeRanges[], uint32 excludeRangeCount)
{
for (int32 i = 0; i < stackTrace->depth; i++) {
addr_t returnAddress = stackTrace->return_addresses[i];
bool inRange = false;
for (uint32 j = 0; j < excludeRangeCount; j++) {
if (returnAddress >= excludeRanges[j * 2 + 0]
&& returnAddress < excludeRanges[j * 2 + 1]) {
inRange = true;
break;
}
}
if (!inRange)
return returnAddress;
}
return 0;
}
int
dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter)
{
@ -1627,6 +1645,26 @@ dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter)
}
bool
tracing_is_entry_valid(TraceEntry* candidate, bigtime_t entryTime)
{
#if ENABLE_TRACING
TraceEntryIterator iterator;
while (TraceEntry* entry = iterator.Next()) {
AbstractTraceEntry* abstract = dynamic_cast<AbstractTraceEntry*>(entry);
if (abstract == NULL)
continue;
// TODO: This could be better by additionally checking if the
// candidate entry address falls within the valid entry range.
return abstract == candidate || abstract->Time() < entryTime;
}
#endif
return false;
}
void
lock_tracing_buffer()
{