Implement -Xstacktracefile.
Change-Id: Ib6c73ddc6f0eaf8f8b731d450b87bda55589f857
diff --git a/src/runtime.cc b/src/runtime.cc
index be9c8fa..6148ae7 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -306,6 +306,8 @@
parsed->jni_globals_max_ = ParseIntegerOrDie(option);
} else if (option.starts_with("-Xlockprofthreshold:")) {
parsed->lock_profiling_threshold_ = ParseIntegerOrDie(option);
+ } else if (option.starts_with("-Xstacktracefile:")) {
+ parsed->stack_trace_file_ = option.substr(strlen("-Xstacktracefile:")).data();
} else if (option == "sensitiveThread") {
parsed->hook_is_sensitive_thread_ = reinterpret_cast<bool (*)()>(options[i].second);
} else if (option == "vfprintf") {
@@ -411,7 +413,7 @@
void Runtime::StartSignalCatcher() {
if (!is_zygote_) {
- signal_catcher_ = new SignalCatcher;
+ signal_catcher_ = new SignalCatcher(stack_trace_file_);
}
}
@@ -469,6 +471,7 @@
abort_ = options->hook_abort_;
default_stack_size_ = options->stack_size_;
+ stack_trace_file_ = options->stack_trace_file_;
monitor_list_ = new MonitorList;
thread_list_ = new ThreadList(options->IsVerbose("thread"));
diff --git a/src/runtime.h b/src/runtime.h
index b29523e..44dfacf 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -58,6 +58,7 @@
size_t stack_size_;
size_t jni_globals_max_;
size_t lock_profiling_threshold_;
+ std::string stack_trace_file_;
bool (*hook_is_sensitive_thread_)();
jint (*hook_vfprintf_)(FILE* stream, const char* format, va_list ap);
void (*hook_exit_)(jint status);
@@ -254,6 +255,7 @@
ClassLinker* class_linker_;
SignalCatcher* signal_catcher_;
+ std::string stack_trace_file_;
JavaVMExt* java_vm_;
diff --git a/src/signal_catcher.cc b/src/signal_catcher.cc
index a3e7bb1..851aab7 100644
--- a/src/signal_catcher.cc
+++ b/src/signal_catcher.cc
@@ -16,14 +16,19 @@
#include "signal_catcher.h"
+#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
+#include <sys/stat.h>
#include <sys/time.h>
+#include <sys/types.h>
#include <unistd.h>
#include "class_linker.h"
+#include "file.h"
#include "heap.h"
+#include "os.h"
#include "runtime.h"
#include "thread.h"
#include "thread_list.h"
@@ -31,8 +36,11 @@
namespace art {
-SignalCatcher::SignalCatcher()
- : lock_("SignalCatcher lock"), cond_("SignalCatcher::cond_"), thread_(NULL) {
+SignalCatcher::SignalCatcher(const std::string& stack_trace_file)
+ : stack_trace_file_(stack_trace_file),
+ lock_("SignalCatcher lock"),
+ cond_("SignalCatcher::cond_"),
+ thread_(NULL) {
SetHaltFlag(false);
// Create a raw pthread; its start routine will attach to the runtime.
@@ -62,6 +70,27 @@
return halt_;
}
+void SignalCatcher::Output(const std::string& s) {
+ if (stack_trace_file_.empty()) {
+ LOG(INFO) << s;
+ return;
+ }
+
+ ScopedThreadStateChange tsc(Thread::Current(), Thread::kVmWait);
+ int fd = open(stack_trace_file_.c_str(), O_APPEND | O_CREAT | O_WRONLY, 0666);
+ if (fd == -1) {
+ PLOG(ERROR) << "Unable to open stack trace file '" << stack_trace_file_ << "'";
+ return;
+ }
+ UniquePtr<File> file(OS::FileFromFd(stack_trace_file_.c_str(), fd));
+ if (!file->WriteFully(s.data(), s.size())) {
+ PLOG(ERROR) << "Failed to write stack traces to '" << stack_trace_file_ << "'";
+ } else {
+ LOG(INFO) << "Wrote stack traces to '" << stack_trace_file_ << "'";
+ }
+ close(fd);
+}
+
void SignalCatcher::HandleSigQuit() {
Runtime* runtime = Runtime::Current();
ThreadList* thread_list = runtime->GetThreadList();
@@ -92,11 +121,11 @@
os << "/proc/self/maps:\n" << maps;
}
- os << "----- end " << getpid() << " -----";
+ os << "----- end " << getpid() << " -----\n";
thread_list->ResumeAll();
- LOG(INFO) << os.str();
+ Output(os.str());
}
void SignalCatcher::HandleSigUsr1() {
@@ -151,10 +180,10 @@
LOG(INFO) << *signal_catcher->thread_ << ": reacting to signal " << signal_number;
switch (signal_number) {
case SIGQUIT:
- HandleSigQuit();
+ signal_catcher->HandleSigQuit();
break;
case SIGUSR1:
- HandleSigUsr1();
+ signal_catcher->HandleSigUsr1();
break;
default:
LOG(ERROR) << "Unexpected signal %d" << signal_number;
diff --git a/src/signal_catcher.h b/src/signal_catcher.h
index 123b38f..5178b1a 100644
--- a/src/signal_catcher.h
+++ b/src/signal_catcher.h
@@ -31,18 +31,20 @@
*/
class SignalCatcher {
public:
- SignalCatcher();
+ SignalCatcher(const std::string& stack_trace_file);
~SignalCatcher();
- static void HandleSigQuit();
+ void HandleSigQuit();
private:
static void* Run(void* arg);
- static void HandleSigUsr1();
+ void HandleSigUsr1();
+ void Output(const std::string& s);
void SetHaltFlag(bool new_value);
bool ShouldHalt();
+ std::string stack_trace_file_;
mutable Mutex lock_;
bool halt_;
ConditionVariable cond_;