Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c49bd655 authored by Christopher Ferris's avatar Christopher Ferris Committed by Android Git Automerger
Browse files

am 5d2ec87b: am b18f93ea: Merge "Move CallStack to libbacktrace."

* commit '5d2ec87b':
  Move CallStack to libbacktrace.
parents 3794c96f 5d2ec87b
Loading
Loading
Loading
Loading
+8 −31
Original line number Original line Diff line number Diff line
@@ -18,8 +18,9 @@
#define ANDROID_CALLSTACK_H
#define ANDROID_CALLSTACK_H


#include <android/log.h>
#include <android/log.h>
#include <backtrace/backtrace.h>
#include <utils/String8.h>
#include <utils/String8.h>
#include <corkscrew/backtrace.h>
#include <utils/Vector.h>


#include <stdint.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/types.h>
@@ -31,42 +32,19 @@ class Printer;
// Collect/print the call stack (function, file, line) traces for a single thread.
// Collect/print the call stack (function, file, line) traces for a single thread.
class CallStack {
class CallStack {
public:
public:
    enum {
        // Prune the lowest-most stack frames until we have at most MAX_DEPTH.
        MAX_DEPTH = 31,
        // Placeholder for specifying the current thread when updating the stack.
        CURRENT_THREAD = -1,
    };

    // Create an empty call stack. No-op.
    // Create an empty call stack. No-op.
    CallStack();
    CallStack();
    // Create a callstack with the current thread's stack trace.
    // Create a callstack with the current thread's stack trace.
    // Immediately dump it to logcat using the given logtag.
    // Immediately dump it to logcat using the given logtag.
    CallStack(const char* logtag, int32_t ignoreDepth=1,
    CallStack(const char* logtag, int32_t ignoreDepth=1);
            int32_t maxDepth=MAX_DEPTH);
    // Copy the existing callstack (no other side effects).
    CallStack(const CallStack& rhs);
    ~CallStack();
    ~CallStack();


    // Copy the existing callstack (no other side effects).
    CallStack& operator = (const CallStack& rhs);

    // Compare call stacks by their backtrace frame memory.
    bool operator == (const CallStack& rhs) const;
    bool operator != (const CallStack& rhs) const;
    bool operator < (const CallStack& rhs) const;
    bool operator >= (const CallStack& rhs) const;
    bool operator > (const CallStack& rhs) const;
    bool operator <= (const CallStack& rhs) const;

    // Get the PC address for the stack frame specified by index.
    const void* operator [] (int index) const;

    // Reset the stack frames (same as creating an empty call stack).
    // Reset the stack frames (same as creating an empty call stack).
    void clear();
    void clear() { mFrameLines.clear(); }


    // Immediately collect the stack traces for the specified thread.
    // Immediately collect the stack traces for the specified thread.
    void update(int32_t ignoreDepth=1, int32_t maxDepth=MAX_DEPTH, pid_t tid=CURRENT_THREAD);
    // The default is to dump the stack of the current call.
    void update(int32_t ignoreDepth=1, pid_t tid=BACKTRACE_NO_TID);


    // Dump a stack trace to the log using the supplied logtag.
    // Dump a stack trace to the log using the supplied logtag.
    void log(const char* logtag,
    void log(const char* logtag,
@@ -83,11 +61,10 @@ public:
    void print(Printer& printer) const;
    void print(Printer& printer) const;


    // Get the count of stack frames that are in this call stack.
    // Get the count of stack frames that are in this call stack.
    size_t size() const { return mCount; }
    size_t size() const { return mFrameLines.size(); }


private:
private:
    size_t mCount;
    Vector<String8> mFrameLines;
    backtrace_frame_t mStack[MAX_DEPTH];
};
};


}; // namespace android
}; // namespace android
+1 −1
Original line number Original line Diff line number Diff line
@@ -39,7 +39,7 @@ public:
    ~ProcessCallStack();
    ~ProcessCallStack();


    // Immediately collect the stack traces for all threads.
    // Immediately collect the stack traces for all threads.
    void update(int32_t maxDepth = CallStack::MAX_DEPTH);
    void update();


    // Print all stack traces to the log using the supplied logtag.
    // Print all stack traces to the log using the supplied logtag.
    void log(const char* logtag, android_LogPriority priority = ANDROID_LOG_DEBUG,
    void log(const char* logtag, android_LogPriority priority = ANDROID_LOG_DEBUG,
+7 −3
Original line number Original line Diff line number Diff line
@@ -116,10 +116,12 @@ LOCAL_STATIC_LIBRARIES := \
	libcutils
	libcutils


LOCAL_SHARED_LIBRARIES := \
LOCAL_SHARED_LIBRARIES := \
        libcorkscrew \
        libbacktrace \
        liblog \
        liblog \
        libdl
        libdl


include external/stlport/libstlport.mk

LOCAL_MODULE:= libutils
LOCAL_MODULE:= libutils
include $(BUILD_STATIC_LIBRARY)
include $(BUILD_STATIC_LIBRARY)


@@ -129,10 +131,12 @@ include $(CLEAR_VARS)
LOCAL_MODULE:= libutils
LOCAL_MODULE:= libutils
LOCAL_WHOLE_STATIC_LIBRARIES := libutils
LOCAL_WHOLE_STATIC_LIBRARIES := libutils
LOCAL_SHARED_LIBRARIES := \
LOCAL_SHARED_LIBRARIES := \
        liblog \
        libbacktrace \
        libcutils \
        libcutils \
        libdl \
        libdl \
        libcorkscrew
        liblog \

include external/stlport/libstlport.mk


include $(BUILD_SHARED_LIBRARY)
include $(BUILD_SHARED_LIBRARY)


+15 −82
Original line number Original line Diff line number Diff line
@@ -20,93 +20,33 @@
#include <utils/Printer.h>
#include <utils/Printer.h>
#include <utils/Errors.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/Log.h>
#include <corkscrew/backtrace.h>
#include <UniquePtr.h>

#include <backtrace/Backtrace.h>


namespace android {
namespace android {


CallStack::CallStack() :
CallStack::CallStack() {
        mCount(0) {
}
}


CallStack::CallStack(const char* logtag, int32_t ignoreDepth, int32_t maxDepth) {
CallStack::CallStack(const char* logtag, int32_t ignoreDepth) {
    this->update(ignoreDepth+1, maxDepth, CURRENT_THREAD);
    this->update(ignoreDepth+1);
    this->log(logtag);
    this->log(logtag);
}
}


CallStack::CallStack(const CallStack& rhs) :
        mCount(rhs.mCount) {
    if (mCount) {
        memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
    }
}

CallStack::~CallStack() {
CallStack::~CallStack() {
}
}


CallStack& CallStack::operator = (const CallStack& rhs) {
void CallStack::update(int32_t ignoreDepth, pid_t tid) {
    mCount = rhs.mCount;
    mFrameLines.clear();
    if (mCount) {
        memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
    }
    return *this;
}

bool CallStack::operator == (const CallStack& rhs) const {
    if (mCount != rhs.mCount)
        return false;
    return !mCount || memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) == 0;
}

bool CallStack::operator != (const CallStack& rhs) const {
    return !operator == (rhs);
}


bool CallStack::operator < (const CallStack& rhs) const {
    UniquePtr<Backtrace> backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, tid));
    if (mCount != rhs.mCount)
    if (!backtrace->Unwind(ignoreDepth)) {
        return mCount < rhs.mCount;
        ALOGW("%s: Failed to unwind callstack.", __FUNCTION__);
    return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) < 0;
    }
    }

    for (size_t i = 0; i < backtrace->NumFrames(); i++) {
bool CallStack::operator >= (const CallStack& rhs) const {
      mFrameLines.push_back(String8(backtrace->FormatFrameData(i).c_str()));
    return !operator < (rhs);
    }
    }

bool CallStack::operator > (const CallStack& rhs) const {
    if (mCount != rhs.mCount)
        return mCount > rhs.mCount;
    return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) > 0;
}

bool CallStack::operator <= (const CallStack& rhs) const {
    return !operator > (rhs);
}

const void* CallStack::operator [] (int index) const {
    if (index >= int(mCount))
        return 0;
    return reinterpret_cast<const void*>(mStack[index].absolute_pc);
}

void CallStack::clear() {
    mCount = 0;
}

void CallStack::update(int32_t ignoreDepth, int32_t maxDepth, pid_t tid) {
    if (maxDepth > MAX_DEPTH) {
        maxDepth = MAX_DEPTH;
    }
    ssize_t count;

    if (tid >= 0) {
        count = unwind_backtrace_thread(tid, mStack, ignoreDepth + 1, maxDepth);
    } else if (tid == CURRENT_THREAD) {
        count = unwind_backtrace(mStack, ignoreDepth + 1, maxDepth);
    } else {
        ALOGE("%s: Invalid tid specified (%d)", __FUNCTION__, tid);
        count = 0;
    }

    mCount = count > 0 ? count : 0;
}
}


void CallStack::log(const char* logtag, android_LogPriority priority, const char* prefix) const {
void CallStack::log(const char* logtag, android_LogPriority priority, const char* prefix) const {
@@ -129,16 +69,9 @@ String8 CallStack::toString(const char* prefix) const {
}
}


void CallStack::print(Printer& printer) const {
void CallStack::print(Printer& printer) const {
    backtrace_symbol_t symbols[mCount];
    for (size_t i = 0; i < mFrameLines.size(); i++) {

        printer.printLine(mFrameLines[i]);
    get_backtrace_symbols(mStack, mCount, symbols);
    for (size_t i = 0; i < mCount; i++) {
        char line[MAX_BACKTRACE_LINE_LENGTH];
        format_backtrace_line(i, &mStack[i], &symbols[i],
                line, MAX_BACKTRACE_LINE_LENGTH);
        printer.printLine(line);
    }
    }
    free_backtrace_symbols(symbols, mCount);
}
}


}; // namespace android
}; // namespace android
+1 −0
Original line number Original line Diff line number Diff line
@@ -145,6 +145,7 @@ void String8Printer::printLine(const char* string) {
        return;
        return;
    }
    }


    mTarget->append(mPrefix);
    mTarget->append(string);
    mTarget->append(string);
    mTarget->append("\n");
    mTarget->append("\n");
}
}
Loading