summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/runtime.cc4
-rw-r--r--runtime/runtime.h4
-rw-r--r--runtime/signal_catcher.cc3
-rw-r--r--runtime/signal_catcher.h4
-rw-r--r--runtime/thread.cc7
5 files changed, 22 insertions, 0 deletions
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 97db5fb0fd..01aea2873a 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -2404,6 +2404,10 @@ void Runtime::DumpDeoptimizations(std::ostream& os) {
}
}
+std::optional<uint64_t> Runtime::SiqQuitNanoTime() const {
+ return signal_catcher_ != nullptr ? signal_catcher_->SiqQuitNanoTime() : std::nullopt;
+}
+
void Runtime::DumpForSigQuit(std::ostream& os) {
// Print backtraces first since they are important do diagnose ANRs,
// and ANRs can often be trimmed to limit upload size.
diff --git a/runtime/runtime.h b/runtime/runtime.h
index feb9cb3b7f..628109978c 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -23,6 +23,7 @@
#include <forward_list>
#include <iosfwd>
#include <memory>
+#include <optional>
#include <set>
#include <string>
#include <utility>
@@ -311,6 +312,9 @@ class Runtime {
// Detaches the current native thread from the runtime.
void DetachCurrentThread(bool should_run_callbacks = true) REQUIRES(!Locks::mutator_lock_);
+ // If we are handling SIQQUIT return the time when we received it.
+ std::optional<uint64_t> SiqQuitNanoTime() const;
+
void DumpDeoptimizations(std::ostream& os);
void DumpForSigQuit(std::ostream& os);
void DumpLockHolders(std::ostream& os);
diff --git a/runtime/signal_catcher.cc b/runtime/signal_catcher.cc
index 70cebafe4b..ba1b4efdd7 100644
--- a/runtime/signal_catcher.cc
+++ b/runtime/signal_catcher.cc
@@ -25,6 +25,7 @@
#include <sys/types.h>
#include <unistd.h>
+#include <optional>
#include <sstream>
#include <android-base/file.h>
@@ -115,6 +116,7 @@ void SignalCatcher::Output(const std::string& s) {
}
void SignalCatcher::HandleSigQuit() {
+ sigquit_nanotime_ = NanoTime();
Runtime* runtime = Runtime::Current();
std::ostringstream os;
os << "\n"
@@ -140,6 +142,7 @@ void SignalCatcher::HandleSigQuit() {
}
os << "----- end " << getpid() << " -----\n";
Output(os.str());
+ sigquit_nanotime_ = std::nullopt;
}
void SignalCatcher::HandleSigUsr1() {
diff --git a/runtime/signal_catcher.h b/runtime/signal_catcher.h
index 46eae7e50e..50b001d2ca 100644
--- a/runtime/signal_catcher.h
+++ b/runtime/signal_catcher.h
@@ -17,6 +17,8 @@
#ifndef ART_RUNTIME_SIGNAL_CATCHER_H_
#define ART_RUNTIME_SIGNAL_CATCHER_H_
+#include <optional>
+
#include "android-base/unique_fd.h"
#include "base/mutex.h"
@@ -39,6 +41,7 @@ class SignalCatcher {
void HandleSigQuit() REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_,
!Locks::thread_suspend_count_lock_);
+ std::optional<uint64_t> SiqQuitNanoTime() const { return sigquit_nanotime_; }
private:
// NO_THREAD_SAFETY_ANALYSIS for static function calling into member function with excludes lock.
@@ -55,6 +58,7 @@ class SignalCatcher {
bool halt_ GUARDED_BY(lock_);
pthread_t pthread_ GUARDED_BY(lock_);
Thread* thread_ GUARDED_BY(lock_);
+ std::optional<uint64_t> sigquit_nanotime_;
};
} // namespace art
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 9824e0a923..59d3da9395 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -29,6 +29,7 @@
#include <cerrno>
#include <iostream>
#include <list>
+#include <optional>
#include <sstream>
#include "android-base/file.h"
@@ -2362,6 +2363,7 @@ Thread::DumpOrder Thread::DumpStack(std::ostream& os,
}
DumpOrder dump_order = DumpOrder::kDefault;
if (safe_to_dump || force_dump_stack) {
+ uint64_t nanotime = NanoTime();
// If we're currently in native code, dump that stack before dumping the managed stack.
if (dump_native_stack && (dump_for_abort || force_dump_stack || ShouldShowNativeStack(this))) {
ArtMethod* method =
@@ -2373,6 +2375,11 @@ Thread::DumpOrder Thread::DumpStack(std::ostream& os,
dump_order = DumpJavaStack(os,
/*check_suspended=*/ !force_dump_stack,
/*dump_locks=*/ !force_dump_stack);
+ Runtime* runtime = Runtime::Current();
+ std::optional<uint64_t> start = runtime != nullptr ? runtime->SiqQuitNanoTime() : std::nullopt;
+ if (start.has_value()) {
+ os << "DumpLatencyMs: " << static_cast<float>(nanotime - start.value()) / 1000000.0 << "\n";
+ }
} else {
os << "Not able to dump stack of thread that isn't suspended";
}