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

Commit d32ecf18 authored by Andy Hung's avatar Andy Hung Committed by Android (Google) Code Review
Browse files

Merge "TimeCheck: Dump stack of blocked tids" into tm-dev

parents c46982d7 10ac7112
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ cc_library {
        "libcutils",
        "liblog",
        "libutils",
        "libutilscallstack",
        "libhidlbase",
        "libpermission",
        "android.hardware.graphics.bufferqueue@1.0",
+18 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <optional>

#include <android-base/logging.h>
#include <audio_utils/clock.h>
#include <mediautils/EventLog.h>
#include <mediautils/MethodStatistics.h>
@@ -199,8 +200,23 @@ void TimeCheck::TimeCheckHandler::onTimeout() const
    }

    LOG_EVENT_STRING(LOGTAG_AUDIO_BINDER_TIMEOUT, tag.c_str());
    LOG_ALWAYS_FATAL("TimeCheck timeout for %s scheduled %s on thread %d\n%s",
            tag.c_str(), formatTime(startTime).c_str(), tid, summary.c_str());

    // Create abort message string - caution: this can be very large.
    const std::string abortMessage = std::string("TimeCheck timeout for ")
            .append(tag)
            .append(" scheduled ").append(formatTime(startTime))
            .append(" on thread ").append(std::to_string(tid)).append("\n")
            .append(summary);

    // Note: LOG_ALWAYS_FATAL limits the size of the string - per log/log.h:
    // Log message text may be truncated to less than an
    // implementation-specific limit (1023 bytes).
    //
    // Here, we send the string through android-base/logging.h LOG()
    // to avoid the size limitation. LOG(FATAL) does an abort whereas
    // LOG(FATAL_WITHOUT_ABORT) does not abort.

    LOG(FATAL) << abortMessage;
}

// Automatically create a TimeCheck class for a class and method.
+24 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <vector>

#include <mediautils/TimerThread.h>
#include <utils/CallStack.h>
#include <utils/ThreadDefs.h>

namespace android::mediautils {
@@ -68,6 +69,19 @@ std::string TimerThread::toString(size_t retiredCount) const {
    if (!analysis.summary.empty()) {
        analysisSummary = std::string("\nanalysis [ ").append(analysis.summary).append(" ]");
    }
    std::string timeoutStack;
    if (analysis.timeoutTid != -1) {
        timeoutStack = std::string("\ntimeout(")
                .append(std::to_string(analysis.timeoutTid)).append(") callstack [\n")
                .append(tidCallStackString(analysis.timeoutTid)).append("]");
    }
    std::string blockedStack;
    if (analysis.HALBlockedTid != -1) {
        blockedStack = std::string("\nblocked(")
                .append(std::to_string(analysis.HALBlockedTid)).append(")  callstack [\n")
                .append(tidCallStackString(analysis.HALBlockedTid)).append("]");
    }

    return std::string("now ")
            .append(formatTime(std::chrono::system_clock::now()))
            .append(analysisSummary)
@@ -77,7 +91,9 @@ std::string TimerThread::toString(size_t retiredCount) const {
            .append(requestsToString(pendingRequests))
            .append(" ]\nretired [ ")
            .append(requestsToString(retiredRequests))
            .append(" ]");
            .append(" ]")
            .append(timeoutStack)
            .append(blockedStack);
}

// A HAL method is where the substring "Hidl" is in the class name.
@@ -197,6 +213,13 @@ std::string TimerThread::timeoutToString(size_t n) const {
    return requestsToString(timeoutRequests);
}

/* static */
std::string TimerThread::tidCallStackString(pid_t tid) {
    CallStack cs{};
    cs.update(0 /* ignoreDepth */, tid);
    return cs.toString().c_str();
}

std::string TimerThread::Request::toString() const {
    const auto scheduledString = formatTime(scheduled);
    const auto deadlineString = formatTime(deadline);
+5 −0
Original line number Diff line number Diff line
@@ -125,6 +125,11 @@ class TimerThread {
        return s;
    }

    /**
     * Returns callstack of tid as a string.
     */
    static std::string tidCallStackString(pid_t tid);

  private:
    // To minimize movement of data, we pass around shared_ptrs to Requests.
    // These are allocated and deallocated outside of the lock.