summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2011-10-28 17:18:29 -0700
committerElliott Hughes <enh@google.com>2011-10-28 17:34:47 -0700
commite0918556e7551de638870dcad3f2023f94f85a50 (patch)
treeb866a2b267124354ff2f46815d9870db7e093882 /src
parent6a5bd495ff2f614f1495f652c86f3902d3bde537 (diff)
downloadart-e0918556e7551de638870dcad3f2023f94f85a50.zip
art-e0918556e7551de638870dcad3f2023f94f85a50.tar.gz
art-e0918556e7551de638870dcad3f2023f94f85a50.tar.bz2
Provide a convenience for logging types that don't have an operator<<.
Change-Id: I650b852ded67576dc5ec7c8e57732cfb49f1ecd6
Diffstat (limited to 'src')
-rw-r--r--src/dex_verifier.cc9
-rw-r--r--src/logging.h26
-rw-r--r--src/object.cc2
-rw-r--r--src/runtime.cc29
-rw-r--r--src/thread.cc6
-rw-r--r--src/thread.h2
-rw-r--r--src/thread_list.cc4
7 files changed, 51 insertions, 27 deletions
diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc
index d521e91..79a455e 100644
--- a/src/dex_verifier.cc
+++ b/src/dex_verifier.cc
@@ -890,12 +890,9 @@ void DexVerifier::VerifyMethodAndDump(Method* method) {
DexVerifier verifier(method);
verifier.Verify();
- LogMessage log(__FILE__, __LINE__, INFO, -1);
- log.stream() << "Dump of method " << PrettyMethod(method) << " "
- << verifier.fail_messages_.str();
- log.stream() << std::endl << verifier.info_messages_.str();
-
- verifier.Dump(log.stream());
+ LOG(INFO) << "Dump of method " << PrettyMethod(method) << " "
+ << verifier.fail_messages_.str() << std::endl
+ << verifier.info_messages_.str() << Dumpable<DexVerifier>(verifier);
}
DexVerifier::DexVerifier(Method* method) : java_lang_throwable_(NULL), work_insn_idx_(-1),
diff --git a/src/logging.h b/src/logging.h
index 2e7856e..b653931 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -171,6 +171,32 @@ class LogMessage {
void HexDump(const void* address, size_t byte_count, bool show_actual_address = false);
+// A convenience to allow any class with a "Dump(std::ostream& os)" member function
+// but without an operator<< to be used as if it had an operator<<. Use like this:
+//
+// os << Dumpable<MyType>(my_type_instance);
+//
+template<typename T>
+class Dumpable {
+ public:
+ explicit Dumpable(T& value) : value_(value) {
+ }
+
+ void Dump(std::ostream& os) const {
+ value_.Dump(os);
+ }
+
+ private:
+ T& value_;
+ DISALLOW_COPY_AND_ASSIGN(Dumpable);
+};
+
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const Dumpable<T>& rhs) {
+ rhs.Dump(os);
+ return os;
+}
+
} // namespace art
#endif // ART_SRC_LOGGING_H_
diff --git a/src/object.cc b/src/object.cc
index 343f643..e59e79a 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -782,7 +782,7 @@ void Class::DumpClass(std::ostream& os, int flags) const {
if ((flags & kDumpClassInitialized) != 0) {
os << ' ' << GetStatus();
}
- os << std::endl;
+ os << "\n";
return;
}
diff --git a/src/runtime.cc b/src/runtime.cc
index 9c923fb..54d7ec6 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -76,27 +76,26 @@ Runtime::~Runtime() {
instance_ = NULL;
}
+struct AbortState {
+ void Dump(std::ostream& os) {
+ os << "Runtime aborting...\n";
+ Thread* self = Thread::Current();
+ if (self == NULL) {
+ os << "(Aborting thread was not attached to runtime!)\n";
+ } else {
+ self->Dump(os, true);
+ }
+ }
+};
+
void Runtime::Abort(const char* file, int line) {
// Get any pending output out of the way.
fflush(NULL);
// Many people have difficulty distinguish aborts from crashes,
// so be explicit.
- {
- LogMessage log(file, line, ERROR, -1);
- log.stream() << "Runtime aborting..." << std::endl;
- // Add Java stack trace if possible
- Thread* thread = Thread::Current();
- if (thread != NULL) {
- log.stream() << "Java stack trace of aborting thread:" << std::endl;
- thread->DumpStack(log.stream());
- if (thread->IsExceptionPending()) {
- Throwable* e = thread->GetException();
- log.stream() << "Pending exception on thread: " << PrettyTypeOf(e) << std::endl;
- log.stream() << e->Dump();
- }
- }
- }
+ AbortState state;
+ LOG(ERROR) << Dumpable<AbortState>(state);
// Perform any platform-specific pre-abort actions.
PlatformAbort(file, line);
diff --git a/src/thread.cc b/src/thread.cc
index 54d2e6c..841ea9b 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -344,9 +344,13 @@ void Thread::InitStackHwm() {
CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attributes), __FUNCTION__);
}
-void Thread::Dump(std::ostream& os) const {
+void Thread::Dump(std::ostream& os, bool dump_pending_exception) const {
DumpState(os);
DumpStack(os);
+ if (dump_pending_exception && IsExceptionPending()) {
+ os << "Pending " << PrettyTypeOf(GetException()) << " on thread:\n";
+ os << GetException()->Dump();
+ }
}
std::string GetSchedulerGroup(pid_t tid) {
diff --git a/src/thread.h b/src/thread.h
index 975edfc..ac97ebe 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -180,7 +180,7 @@ class PACKED Thread {
static Thread* FromManagedThread(JNIEnv* env, jobject thread);
static uint32_t LockOwnerFromThreadLock(Object* thread_lock);
- void Dump(std::ostream& os) const;
+ void Dump(std::ostream& os, bool dump_pending_exception = false) const;
State GetState() const {
return state_;
diff --git a/src/thread_list.cc b/src/thread_list.cc
index a77b8f6..6da5e68 100644
--- a/src/thread_list.cc
+++ b/src/thread_list.cc
@@ -371,9 +371,7 @@ void ThreadList::Register() {
Thread* self = Thread::Current();
if (verbose_) {
- LogMessage log(__FILE__, __LINE__, INFO, -1);
- log.stream() << "ThreadList::Register() " << *self << "\n";
- self->Dump(log.stream());
+ LOG(INFO) << "ThreadList::Register() " << *self << "\n" << Dumpable<Thread>(*self);
}
ThreadListLocker locker(this);