comparison src/os/linux/vm/os_linux.cpp @ 11092:59b052799158

8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace Summary: Dl_info struct should only be used if dladdr() has returned non-zero (no errors) and always check the dladdr() return value; Dl_info.dli_sname and Dl_info.dli_saddr fields should only be used if non-NULL; update/improve runtime/6888954/vmerrors.sh test Reviewed-by: dsamersoff, zgu, hseigel, coleenp
author dcubed
date Thu, 04 Jul 2013 21:10:17 -0700
parents 1f4355cee9a2
children 6b0fd0964b87 4c84d351cca9 88c255656030 438e13354adf
comparison
equal deleted inserted replaced
11091:a55aa67bce1a 11092:59b052799158
1680 bool os::address_is_in_vm(address addr) { 1680 bool os::address_is_in_vm(address addr) {
1681 static address libjvm_base_addr; 1681 static address libjvm_base_addr;
1682 Dl_info dlinfo; 1682 Dl_info dlinfo;
1683 1683
1684 if (libjvm_base_addr == NULL) { 1684 if (libjvm_base_addr == NULL) {
1685 dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo); 1685 if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) {
1686 libjvm_base_addr = (address)dlinfo.dli_fbase; 1686 libjvm_base_addr = (address)dlinfo.dli_fbase;
1687 }
1687 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm"); 1688 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
1688 } 1689 }
1689 1690
1690 if (dladdr((void *)addr, &dlinfo)) { 1691 if (dladdr((void *)addr, &dlinfo) != 0) {
1691 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true; 1692 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
1692 } 1693 }
1693 1694
1694 return false; 1695 return false;
1695 } 1696 }
1696 1697
1697 bool os::dll_address_to_function_name(address addr, char *buf, 1698 bool os::dll_address_to_function_name(address addr, char *buf,
1698 int buflen, int *offset) { 1699 int buflen, int *offset) {
1700 // buf is not optional, but offset is optional
1701 assert(buf != NULL, "sanity check");
1702
1699 Dl_info dlinfo; 1703 Dl_info dlinfo;
1700 1704
1701 if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) { 1705 if (dladdr((void*)addr, &dlinfo) != 0) {
1702 if (buf != NULL) { 1706 // see if we have a matching symbol
1703 if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { 1707 if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {
1708 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
1704 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); 1709 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
1705 } 1710 }
1706 } 1711 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
1707 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; 1712 return true;
1708 return true; 1713 }
1709 } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) { 1714 // no matching symbol so try for just file info
1710 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), 1715 if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
1711 buf, buflen, offset, dlinfo.dli_fname)) { 1716 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
1712 return true; 1717 buf, buflen, offset, dlinfo.dli_fname)) {
1713 } 1718 return true;
1714 } 1719 }
1715 1720 }
1716 if (buf != NULL) buf[0] = '\0'; 1721 }
1722
1723 buf[0] = '\0';
1717 if (offset != NULL) *offset = -1; 1724 if (offset != NULL) *offset = -1;
1718 return false; 1725 return false;
1719 } 1726 }
1720 1727
1721 struct _address_to_library_name { 1728 struct _address_to_library_name {
1762 return 0; 1769 return 0;
1763 } 1770 }
1764 1771
1765 bool os::dll_address_to_library_name(address addr, char* buf, 1772 bool os::dll_address_to_library_name(address addr, char* buf,
1766 int buflen, int* offset) { 1773 int buflen, int* offset) {
1774 // buf is not optional, but offset is optional
1775 assert(buf != NULL, "sanity check");
1776
1767 Dl_info dlinfo; 1777 Dl_info dlinfo;
1768 struct _address_to_library_name data; 1778 struct _address_to_library_name data;
1769 1779
1770 // There is a bug in old glibc dladdr() implementation that it could resolve 1780 // There is a bug in old glibc dladdr() implementation that it could resolve
1771 // to wrong library name if the .so file has a base address != NULL. Here 1781 // to wrong library name if the .so file has a base address != NULL. Here
1780 1790
1781 if (rslt) { 1791 if (rslt) {
1782 // buf already contains library name 1792 // buf already contains library name
1783 if (offset) *offset = addr - data.base; 1793 if (offset) *offset = addr - data.base;
1784 return true; 1794 return true;
1785 } else if (dladdr((void*)addr, &dlinfo)){ 1795 }
1786 if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); 1796 if (dladdr((void*)addr, &dlinfo) != 0) {
1787 if (offset) *offset = addr - (address)dlinfo.dli_fbase; 1797 if (dlinfo.dli_fname != NULL) {
1788 return true; 1798 jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
1789 } else { 1799 }
1790 if (buf) buf[0] = '\0'; 1800 if (dlinfo.dli_fbase != NULL && offset != NULL) {
1791 if (offset) *offset = -1; 1801 *offset = addr - (address)dlinfo.dli_fbase;
1792 return false; 1802 }
1793 } 1803 return true;
1804 }
1805
1806 buf[0] = '\0';
1807 if (offset) *offset = -1;
1808 return false;
1794 } 1809 }
1795 1810
1796 // Loads .dll/.so and 1811 // Loads .dll/.so and
1797 // in case of error it checks if .dll/.so was built for the 1812 // in case of error it checks if .dll/.so was built for the
1798 // same architecture as Hotspot is running on 1813 // same architecture as Hotspot is running on
2315 2330
2316 char dli_fname[MAXPATHLEN]; 2331 char dli_fname[MAXPATHLEN];
2317 bool ret = dll_address_to_library_name( 2332 bool ret = dll_address_to_library_name(
2318 CAST_FROM_FN_PTR(address, os::jvm_path), 2333 CAST_FROM_FN_PTR(address, os::jvm_path),
2319 dli_fname, sizeof(dli_fname), NULL); 2334 dli_fname, sizeof(dli_fname), NULL);
2320 assert(ret != 0, "cannot locate libjvm"); 2335 assert(ret, "cannot locate libjvm");
2321 char *rp = realpath(dli_fname, buf); 2336 char *rp = NULL;
2337 if (ret && dli_fname[0] != '\0') {
2338 rp = realpath(dli_fname, buf);
2339 }
2322 if (rp == NULL) 2340 if (rp == NULL)
2323 return; 2341 return;
2324 2342
2325 if (Arguments::created_by_gamma_launcher()) { 2343 if (Arguments::created_by_gamma_launcher()) {
2326 // Support for the gamma launcher. Typical value for buf is 2344 // Support for the gamma launcher. Typical value for buf is
4728 // debug support 4746 // debug support
4729 4747
4730 bool os::find(address addr, outputStream* st) { 4748 bool os::find(address addr, outputStream* st) {
4731 Dl_info dlinfo; 4749 Dl_info dlinfo;
4732 memset(&dlinfo, 0, sizeof(dlinfo)); 4750 memset(&dlinfo, 0, sizeof(dlinfo));
4733 if (dladdr(addr, &dlinfo)) { 4751 if (dladdr(addr, &dlinfo) != 0) {
4734 st->print(PTR_FORMAT ": ", addr); 4752 st->print(PTR_FORMAT ": ", addr);
4735 if (dlinfo.dli_sname != NULL) { 4753 if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {
4736 st->print("%s+%#x", dlinfo.dli_sname, 4754 st->print("%s+%#x", dlinfo.dli_sname,
4737 addr - (intptr_t)dlinfo.dli_saddr); 4755 addr - (intptr_t)dlinfo.dli_saddr);
4738 } else if (dlinfo.dli_fname) { 4756 } else if (dlinfo.dli_fbase != NULL) {
4739 st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase); 4757 st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase);
4740 } else { 4758 } else {
4741 st->print("<absolute address>"); 4759 st->print("<absolute address>");
4742 } 4760 }
4743 if (dlinfo.dli_fname) { 4761 if (dlinfo.dli_fname != NULL) {
4744 st->print(" in %s", dlinfo.dli_fname); 4762 st->print(" in %s", dlinfo.dli_fname);
4745 } 4763 }
4746 if (dlinfo.dli_fbase) { 4764 if (dlinfo.dli_fbase != NULL) {
4747 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase); 4765 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
4748 } 4766 }
4749 st->cr(); 4767 st->cr();
4750 4768
4751 if (Verbose) { 4769 if (Verbose) {
4754 address end = clamp_address_in_page(addr+40, addr, os::vm_page_size()); 4772 address end = clamp_address_in_page(addr+40, addr, os::vm_page_size());
4755 address lowest = (address) dlinfo.dli_sname; 4773 address lowest = (address) dlinfo.dli_sname;
4756 if (!lowest) lowest = (address) dlinfo.dli_fbase; 4774 if (!lowest) lowest = (address) dlinfo.dli_fbase;
4757 if (begin < lowest) begin = lowest; 4775 if (begin < lowest) begin = lowest;
4758 Dl_info dlinfo2; 4776 Dl_info dlinfo2;
4759 if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr 4777 if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr
4760 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) 4778 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
4761 end = (address) dlinfo2.dli_saddr; 4779 end = (address) dlinfo2.dli_saddr;
4762 Disassembler::decode(begin, end, st); 4780 Disassembler::decode(begin, end, st);
4763 } 4781 }
4764 return true; 4782 return true;