1476 if (detailed_message != NULL) { 1477 return java_lang_String::as_symbol(detailed_message, THREAD); 1478 } 1479 return NULL; 1480 } 1481 1482 void java_lang_Throwable::set_message(oop throwable, oop value) { 1483 throwable->obj_field_put(detailMessage_offset, value); 1484 } 1485 1486 1487 void java_lang_Throwable::set_stacktrace(oop throwable, oop st_element_array) { 1488 throwable->obj_field_put(stackTrace_offset, st_element_array); 1489 } 1490 1491 void java_lang_Throwable::clear_stacktrace(oop throwable) { 1492 set_stacktrace(throwable, NULL); 1493 } 1494 1495 1496 void java_lang_Throwable::print(oop throwable, outputStream* st) { 1497 ResourceMark rm; 1498 Klass* k = throwable->klass(); 1499 assert(k != NULL, "just checking"); 1500 st->print("%s", k->external_name()); 1501 oop msg = message(throwable); 1502 if (msg != NULL) { 1503 st->print(": %s", java_lang_String::as_utf8_string(msg)); 1504 } 1505 } 1506 1507 1508 void java_lang_Throwable::print(Handle throwable, outputStream* st) { 1509 ResourceMark rm; 1510 Klass* k = throwable->klass(); 1511 assert(k != NULL, "just checking"); 1512 st->print("%s", k->external_name()); 1513 oop msg = message(throwable); 1514 if (msg != NULL) { 1515 st->print(": %s", java_lang_String::as_utf8_string(msg)); 1516 } 1517 } 1518 1519 // After this many redefines, the stack trace is unreliable. 1520 const int MAX_VERSION = USHRT_MAX; 1521 1522 static inline bool version_matches(Method* method, int version) { 1523 assert(version < MAX_VERSION, "version is too big"); 1524 return method != NULL && (method->constants()->version() == version); 1525 } 1526 1527 // This class provides a simple wrapper over the internal structure of 1716 void java_lang_Throwable::print_stack_element(outputStream *st, Handle mirror, 1717 int method_id, int version, int bci, int cpref) { 1718 ResourceMark rm; 1719 char* buf = print_stack_element_to_buffer(mirror, method_id, version, bci, cpref); 1720 st->print_cr("%s", buf); 1721 } 1722 1723 void java_lang_Throwable::print_stack_element(outputStream *st, const methodHandle& method, int bci) { 1724 Handle mirror = method->method_holder()->java_mirror(); 1725 int method_id = method->orig_method_idnum(); 1726 int version = method->constants()->version(); 1727 int cpref = method->name_index(); 1728 print_stack_element(st, mirror, method_id, version, bci, cpref); 1729 } 1730 1731 const char* java_lang_Throwable::no_stack_trace_message() { 1732 return "\t<<no stack trace available>>"; 1733 } 1734 1735 1736 // Currently used only for exceptions occurring during startup 1737 void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) { 1738 Thread *THREAD = Thread::current(); 1739 Handle h_throwable(THREAD, throwable); 1740 while (h_throwable.not_null()) { 1741 objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable()))); 1742 if (result.is_null()) { 1743 st->print_raw_cr(no_stack_trace_message()); 1744 return; 1745 } 1746 1747 while (result.not_null()) { 1748 1749 // Get method id, bci, version and mirror from chunk 1750 typeArrayHandle methods (THREAD, BacktraceBuilder::get_methods(result)); 1751 typeArrayHandle bcis (THREAD, BacktraceBuilder::get_bcis(result)); 1752 objArrayHandle mirrors (THREAD, BacktraceBuilder::get_mirrors(result)); 1753 typeArrayHandle cprefs (THREAD, BacktraceBuilder::get_cprefs(result)); 1754 1755 int length = methods()->length(); 1756 for (int index = 0; index < length; index++) { 1757 Handle mirror(THREAD, mirrors->obj_at(index)); 1758 // NULL mirror means end of stack trace 1759 if (mirror.is_null()) goto handle_cause; 1760 int method = methods->short_at(index); 1761 int version = Backtrace::version_at(bcis->int_at(index)); 1762 int bci = Backtrace::bci_at(bcis->int_at(index)); 1763 int cpref = cprefs->short_at(index); 1764 print_stack_element(st, mirror, method, version, bci, cpref); 1765 } 1766 result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset))); 1767 } 1768 handle_cause: 1769 { 1770 EXCEPTION_MARK; 1771 JavaValue cause(T_OBJECT); 1772 JavaCalls::call_virtual(&cause, 1773 h_throwable, 1774 KlassHandle(THREAD, h_throwable->klass()), 1775 vmSymbols::getCause_name(), 1776 vmSymbols::void_throwable_signature(), 1777 THREAD); 1778 // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. 1779 if (HAS_PENDING_EXCEPTION) { 1780 CLEAR_PENDING_EXCEPTION; 1781 h_throwable = Handle(); 1782 } else { 1783 h_throwable = Handle(THREAD, (oop) cause.get_jobject()); 1784 if (h_throwable.not_null()) { 1785 st->print("Caused by: "); 1786 print(h_throwable, st); 1787 st->cr(); 1788 } 1789 } 1790 } 1791 } 1792 } 1793 1794 void java_lang_Throwable::fill_in_stack_trace(Handle throwable, const methodHandle& method, TRAPS) { 1795 if (!StackTraceInThrowable) return; 1796 ResourceMark rm(THREAD); 1797 1798 // Start out by clearing the backtrace for this object, in case the VM 1799 // runs out of memory while allocating the stack trace 1800 set_backtrace(throwable(), NULL); 1801 // Clear lazily constructed Java level stacktrace if refilling occurs 1802 // This is unnecessary in 1.7+ but harmless 1803 clear_stacktrace(throwable()); 1804 1805 int max_depth = MaxJavaStackTraceDepth; 1806 JavaThread* thread = (JavaThread*)THREAD; | 1476 if (detailed_message != NULL) { 1477 return java_lang_String::as_symbol(detailed_message, THREAD); 1478 } 1479 return NULL; 1480 } 1481 1482 void java_lang_Throwable::set_message(oop throwable, oop value) { 1483 throwable->obj_field_put(detailMessage_offset, value); 1484 } 1485 1486 1487 void java_lang_Throwable::set_stacktrace(oop throwable, oop st_element_array) { 1488 throwable->obj_field_put(stackTrace_offset, st_element_array); 1489 } 1490 1491 void java_lang_Throwable::clear_stacktrace(oop throwable) { 1492 set_stacktrace(throwable, NULL); 1493 } 1494 1495 1496 void java_lang_Throwable::print(Handle throwable, outputStream* st) { 1497 ResourceMark rm; 1498 Klass* k = throwable->klass(); 1499 assert(k != NULL, "just checking"); 1500 st->print("%s", k->external_name()); 1501 oop msg = message(throwable); 1502 if (msg != NULL) { 1503 st->print(": %s", java_lang_String::as_utf8_string(msg)); 1504 } 1505 } 1506 1507 // After this many redefines, the stack trace is unreliable. 1508 const int MAX_VERSION = USHRT_MAX; 1509 1510 static inline bool version_matches(Method* method, int version) { 1511 assert(version < MAX_VERSION, "version is too big"); 1512 return method != NULL && (method->constants()->version() == version); 1513 } 1514 1515 // This class provides a simple wrapper over the internal structure of 1704 void java_lang_Throwable::print_stack_element(outputStream *st, Handle mirror, 1705 int method_id, int version, int bci, int cpref) { 1706 ResourceMark rm; 1707 char* buf = print_stack_element_to_buffer(mirror, method_id, version, bci, cpref); 1708 st->print_cr("%s", buf); 1709 } 1710 1711 void java_lang_Throwable::print_stack_element(outputStream *st, const methodHandle& method, int bci) { 1712 Handle mirror = method->method_holder()->java_mirror(); 1713 int method_id = method->orig_method_idnum(); 1714 int version = method->constants()->version(); 1715 int cpref = method->name_index(); 1716 print_stack_element(st, mirror, method_id, version, bci, cpref); 1717 } 1718 1719 const char* java_lang_Throwable::no_stack_trace_message() { 1720 return "\t<<no stack trace available>>"; 1721 } 1722 1723 1724 void java_lang_Throwable::print_stack_trace(Handle throwable, outputStream* st) { 1725 // First, print the message. 1726 print(throwable, st); 1727 st->cr(); 1728 1729 // Now print the stack trace. 1730 Thread* THREAD = Thread::current(); 1731 while (throwable.not_null()) { 1732 objArrayHandle result (THREAD, objArrayOop(backtrace(throwable()))); 1733 if (result.is_null()) { 1734 st->print_raw_cr(no_stack_trace_message()); 1735 return; 1736 } 1737 1738 while (result.not_null()) { 1739 1740 // Get method id, bci, version and mirror from chunk 1741 typeArrayHandle methods (THREAD, BacktraceBuilder::get_methods(result)); 1742 typeArrayHandle bcis (THREAD, BacktraceBuilder::get_bcis(result)); 1743 objArrayHandle mirrors (THREAD, BacktraceBuilder::get_mirrors(result)); 1744 typeArrayHandle cprefs (THREAD, BacktraceBuilder::get_cprefs(result)); 1745 1746 int length = methods()->length(); 1747 for (int index = 0; index < length; index++) { 1748 Handle mirror(THREAD, mirrors->obj_at(index)); 1749 // NULL mirror means end of stack trace 1750 if (mirror.is_null()) goto handle_cause; 1751 int method = methods->short_at(index); 1752 int version = Backtrace::version_at(bcis->int_at(index)); 1753 int bci = Backtrace::bci_at(bcis->int_at(index)); 1754 int cpref = cprefs->short_at(index); 1755 print_stack_element(st, mirror, method, version, bci, cpref); 1756 } 1757 result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset))); 1758 } 1759 handle_cause: 1760 { 1761 EXCEPTION_MARK; 1762 JavaValue cause(T_OBJECT); 1763 JavaCalls::call_virtual(&cause, 1764 throwable, 1765 KlassHandle(THREAD, throwable->klass()), 1766 vmSymbols::getCause_name(), 1767 vmSymbols::void_throwable_signature(), 1768 THREAD); 1769 // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM. 1770 if (HAS_PENDING_EXCEPTION) { 1771 CLEAR_PENDING_EXCEPTION; 1772 throwable = Handle(); 1773 } else { 1774 throwable = Handle(THREAD, (oop) cause.get_jobject()); 1775 if (throwable.not_null()) { 1776 st->print("Caused by: "); 1777 print(throwable, st); 1778 st->cr(); 1779 } 1780 } 1781 } 1782 } 1783 } 1784 1785 void java_lang_Throwable::fill_in_stack_trace(Handle throwable, const methodHandle& method, TRAPS) { 1786 if (!StackTraceInThrowable) return; 1787 ResourceMark rm(THREAD); 1788 1789 // Start out by clearing the backtrace for this object, in case the VM 1790 // runs out of memory while allocating the stack trace 1791 set_backtrace(throwable(), NULL); 1792 // Clear lazily constructed Java level stacktrace if refilling occurs 1793 // This is unnecessary in 1.7+ but harmless 1794 clear_stacktrace(throwable()); 1795 1796 int max_depth = MaxJavaStackTraceDepth; 1797 JavaThread* thread = (JavaThread*)THREAD; |