comparison src/os/solaris/vm/os_solaris.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 ec173c8f3739
comparison
equal deleted inserted replaced
11091:a55aa67bce1a 11092:59b052799158
1922 bool os::address_is_in_vm(address addr) { 1922 bool os::address_is_in_vm(address addr) {
1923 static address libjvm_base_addr; 1923 static address libjvm_base_addr;
1924 Dl_info dlinfo; 1924 Dl_info dlinfo;
1925 1925
1926 if (libjvm_base_addr == NULL) { 1926 if (libjvm_base_addr == NULL) {
1927 dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo); 1927 if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) {
1928 libjvm_base_addr = (address)dlinfo.dli_fbase; 1928 libjvm_base_addr = (address)dlinfo.dli_fbase;
1929 }
1929 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm"); 1930 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
1930 } 1931 }
1931 1932
1932 if (dladdr((void *)addr, &dlinfo)) { 1933 if (dladdr((void *)addr, &dlinfo) != 0) {
1933 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true; 1934 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
1934 } 1935 }
1935 1936
1936 return false; 1937 return false;
1937 } 1938 }
1939 typedef int (*dladdr1_func_type) (void *, Dl_info *, void **, int); 1940 typedef int (*dladdr1_func_type) (void *, Dl_info *, void **, int);
1940 static dladdr1_func_type dladdr1_func = NULL; 1941 static dladdr1_func_type dladdr1_func = NULL;
1941 1942
1942 bool os::dll_address_to_function_name(address addr, char *buf, 1943 bool os::dll_address_to_function_name(address addr, char *buf,
1943 int buflen, int * offset) { 1944 int buflen, int * offset) {
1945 // buf is not optional, but offset is optional
1946 assert(buf != NULL, "sanity check");
1947
1944 Dl_info dlinfo; 1948 Dl_info dlinfo;
1945 1949
1946 // dladdr1_func was initialized in os::init() 1950 // dladdr1_func was initialized in os::init()
1947 if (dladdr1_func){ 1951 if (dladdr1_func != NULL) {
1948 // yes, we have dladdr1 1952 // yes, we have dladdr1
1949 1953
1950 // Support for dladdr1 is checked at runtime; it may be 1954 // Support for dladdr1 is checked at runtime; it may be
1951 // available even if the vm is built on a machine that does 1955 // available even if the vm is built on a machine that does
1952 // not have dladdr1 support. Make sure there is a value for 1956 // not have dladdr1 support. Make sure there is a value for
1953 // RTLD_DL_SYMENT. 1957 // RTLD_DL_SYMENT.
1954 #ifndef RTLD_DL_SYMENT 1958 #ifndef RTLD_DL_SYMENT
1955 #define RTLD_DL_SYMENT 1 1959 #define RTLD_DL_SYMENT 1
1956 #endif 1960 #endif
1957 #ifdef _LP64 1961 #ifdef _LP64
1958 Elf64_Sym * info; 1962 Elf64_Sym * info;
1959 #else 1963 #else
1960 Elf32_Sym * info; 1964 Elf32_Sym * info;
1961 #endif 1965 #endif
1962 if (dladdr1_func((void *)addr, &dlinfo, (void **)&info, 1966 if (dladdr1_func((void *)addr, &dlinfo, (void **)&info,
1963 RTLD_DL_SYMENT)) { 1967 RTLD_DL_SYMENT) != 0) {
1964 if ((char *)dlinfo.dli_saddr + info->st_size > (char *)addr) { 1968 // see if we have a matching symbol that covers our address
1965 if (buf != NULL) { 1969 if (dlinfo.dli_saddr != NULL &&
1966 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) 1970 (char *)dlinfo.dli_saddr + info->st_size > (char *)addr) {
1967 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); 1971 if (dlinfo.dli_sname != NULL) {
1968 } 1972 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
1969 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; 1973 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
1970 return true; 1974 }
1971 } 1975 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
1972 }
1973 if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
1974 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
1975 buf, buflen, offset, dlinfo.dli_fname)) {
1976 return true; 1976 return true;
1977 } 1977 }
1978 } 1978 }
1979 if (buf != NULL) buf[0] = '\0'; 1979 // no matching symbol so try for just file info
1980 if (offset != NULL) *offset = -1; 1980 if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
1981 return false;
1982 } else {
1983 // no, only dladdr is available
1984 if (dladdr((void *)addr, &dlinfo)) {
1985 if (buf != NULL) {
1986 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen))
1987 jio_snprintf(buf, buflen, dlinfo.dli_sname);
1988 }
1989 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
1990 return true;
1991 } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
1992 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), 1981 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
1993 buf, buflen, offset, dlinfo.dli_fname)) { 1982 buf, buflen, offset, dlinfo.dli_fname)) {
1994 return true; 1983 return true;
1995 } 1984 }
1996 } 1985 }
1997 if (buf != NULL) buf[0] = '\0'; 1986 }
1998 if (offset != NULL) *offset = -1; 1987 buf[0] = '\0';
1999 return false; 1988 if (offset != NULL) *offset = -1;
2000 } 1989 return false;
1990 }
1991
1992 // no, only dladdr is available
1993 if (dladdr((void *)addr, &dlinfo) != 0) {
1994 // see if we have a matching symbol
1995 if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {
1996 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
1997 jio_snprintf(buf, buflen, dlinfo.dli_sname);
1998 }
1999 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
2000 return true;
2001 }
2002 // no matching symbol so try for just file info
2003 if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
2004 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
2005 buf, buflen, offset, dlinfo.dli_fname)) {
2006 return true;
2007 }
2008 }
2009 }
2010 buf[0] = '\0';
2011 if (offset != NULL) *offset = -1;
2012 return false;
2001 } 2013 }
2002 2014
2003 bool os::dll_address_to_library_name(address addr, char* buf, 2015 bool os::dll_address_to_library_name(address addr, char* buf,
2004 int buflen, int* offset) { 2016 int buflen, int* offset) {
2017 // buf is not optional, but offset is optional
2018 assert(buf != NULL, "sanity check");
2019
2005 Dl_info dlinfo; 2020 Dl_info dlinfo;
2006 2021
2007 if (dladdr((void*)addr, &dlinfo)){ 2022 if (dladdr((void*)addr, &dlinfo) != 0) {
2008 if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); 2023 if (dlinfo.dli_fname != NULL) {
2009 if (offset) *offset = addr - (address)dlinfo.dli_fbase; 2024 jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
2010 return true; 2025 }
2011 } else { 2026 if (dlinfo.dli_fbase != NULL && offset != NULL) {
2012 if (buf) buf[0] = '\0'; 2027 *offset = addr - (address)dlinfo.dli_fbase;
2013 if (offset) *offset = -1; 2028 }
2014 return false; 2029 return true;
2015 } 2030 }
2031
2032 buf[0] = '\0';
2033 if (offset) *offset = -1;
2034 return false;
2016 } 2035 }
2017 2036
2018 // Prints the names and full paths of all opened dynamic libraries 2037 // Prints the names and full paths of all opened dynamic libraries
2019 // for current process 2038 // for current process
2020 void os::print_dll_info(outputStream * st) { 2039 void os::print_dll_info(outputStream * st) {
2021 Dl_info dli; 2040 Dl_info dli;
2022 void *handle; 2041 void *handle;
2023 Link_map *map; 2042 Link_map *map;
2024 Link_map *p; 2043 Link_map *p;
2025 2044
2026 st->print_cr("Dynamic libraries:"); st->flush(); 2045 st->print_cr("Dynamic libraries:"); st->flush();
2027 2046
2028 if (!dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli)) { 2047 if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 ||
2029 st->print_cr("Error: Cannot print dynamic libraries."); 2048 dli.dli_fname == NULL) {
2030 return; 2049 st->print_cr("Error: Cannot print dynamic libraries.");
2031 } 2050 return;
2032 handle = dlopen(dli.dli_fname, RTLD_LAZY); 2051 }
2033 if (handle == NULL) { 2052 handle = dlopen(dli.dli_fname, RTLD_LAZY);
2034 st->print_cr("Error: Cannot print dynamic libraries."); 2053 if (handle == NULL) {
2035 return; 2054 st->print_cr("Error: Cannot print dynamic libraries.");
2036 } 2055 return;
2037 dlinfo(handle, RTLD_DI_LINKMAP, &map); 2056 }
2038 if (map == NULL) { 2057 dlinfo(handle, RTLD_DI_LINKMAP, &map);
2039 st->print_cr("Error: Cannot print dynamic libraries."); 2058 if (map == NULL) {
2040 return; 2059 st->print_cr("Error: Cannot print dynamic libraries.");
2041 } 2060 return;
2042 2061 }
2043 while (map->l_prev != NULL) 2062
2044 map = map->l_prev; 2063 while (map->l_prev != NULL)
2045 2064 map = map->l_prev;
2046 while (map != NULL) { 2065
2047 st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name); 2066 while (map != NULL) {
2048 map = map->l_next; 2067 st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name);
2049 } 2068 map = map->l_next;
2050 2069 }
2051 dlclose(handle); 2070
2071 dlclose(handle);
2052 } 2072 }
2053 2073
2054 // Loads .dll/.so and 2074 // Loads .dll/.so and
2055 // in case of error it checks if .dll/.so was built for the 2075 // in case of error it checks if .dll/.so was built for the
2056 // same architecture as Hotspot is running on 2076 // same architecture as Hotspot is running on
2473 } 2493 }
2474 2494
2475 Dl_info dlinfo; 2495 Dl_info dlinfo;
2476 int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo); 2496 int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo);
2477 assert(ret != 0, "cannot locate libjvm"); 2497 assert(ret != 0, "cannot locate libjvm");
2478 realpath((char *)dlinfo.dli_fname, buf); 2498 if (ret != 0 && dlinfo.dli_fname != NULL) {
2499 realpath((char *)dlinfo.dli_fname, buf);
2500 } else {
2501 buf[0] = '\0';
2502 return;
2503 }
2479 2504
2480 if (Arguments::created_by_gamma_launcher()) { 2505 if (Arguments::created_by_gamma_launcher()) {
2481 // Support for the gamma launcher. Typical value for buf is 2506 // Support for the gamma launcher. Typical value for buf is
2482 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at 2507 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at
2483 // the right place in the string, then assume we are installed in a JDK and 2508 // the right place in the string, then assume we are installed in a JDK and
6075 //--------------------------------------------------------------------------------- 6100 //---------------------------------------------------------------------------------
6076 6101
6077 bool os::find(address addr, outputStream* st) { 6102 bool os::find(address addr, outputStream* st) {
6078 Dl_info dlinfo; 6103 Dl_info dlinfo;
6079 memset(&dlinfo, 0, sizeof(dlinfo)); 6104 memset(&dlinfo, 0, sizeof(dlinfo));
6080 if (dladdr(addr, &dlinfo)) { 6105 if (dladdr(addr, &dlinfo) != 0) {
6081 #ifdef _LP64 6106 st->print(PTR_FORMAT ": ", addr);
6082 st->print("0x%016lx: ", addr); 6107 if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {
6083 #else
6084 st->print("0x%08x: ", addr);
6085 #endif
6086 if (dlinfo.dli_sname != NULL)
6087 st->print("%s+%#lx", dlinfo.dli_sname, addr-(intptr_t)dlinfo.dli_saddr); 6108 st->print("%s+%#lx", dlinfo.dli_sname, addr-(intptr_t)dlinfo.dli_saddr);
6088 else if (dlinfo.dli_fname) 6109 } else if (dlinfo.dli_fbase != NULL)
6089 st->print("<offset %#lx>", addr-(intptr_t)dlinfo.dli_fbase); 6110 st->print("<offset %#lx>", addr-(intptr_t)dlinfo.dli_fbase);
6090 else 6111 else
6091 st->print("<absolute address>"); 6112 st->print("<absolute address>");
6092 if (dlinfo.dli_fname) st->print(" in %s", dlinfo.dli_fname); 6113 if (dlinfo.dli_fname != NULL) {
6093 #ifdef _LP64 6114 st->print(" in %s", dlinfo.dli_fname);
6094 if (dlinfo.dli_fbase) st->print(" at 0x%016lx", dlinfo.dli_fbase); 6115 }
6095 #else 6116 if (dlinfo.dli_fbase != NULL) {
6096 if (dlinfo.dli_fbase) st->print(" at 0x%08x", dlinfo.dli_fbase); 6117 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
6097 #endif 6118 }
6098 st->cr(); 6119 st->cr();
6099 6120
6100 if (Verbose) { 6121 if (Verbose) {
6101 // decode some bytes around the PC 6122 // decode some bytes around the PC
6102 address begin = clamp_address_in_page(addr-40, addr, os::vm_page_size()); 6123 address begin = clamp_address_in_page(addr-40, addr, os::vm_page_size());
6103 address end = clamp_address_in_page(addr+40, addr, os::vm_page_size()); 6124 address end = clamp_address_in_page(addr+40, addr, os::vm_page_size());
6104 address lowest = (address) dlinfo.dli_sname; 6125 address lowest = (address) dlinfo.dli_sname;
6105 if (!lowest) lowest = (address) dlinfo.dli_fbase; 6126 if (!lowest) lowest = (address) dlinfo.dli_fbase;
6106 if (begin < lowest) begin = lowest; 6127 if (begin < lowest) begin = lowest;
6107 Dl_info dlinfo2; 6128 Dl_info dlinfo2;
6108 if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr 6129 if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr
6109 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) 6130 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
6110 end = (address) dlinfo2.dli_saddr; 6131 end = (address) dlinfo2.dli_saddr;
6111 Disassembler::decode(begin, end, st); 6132 Disassembler::decode(begin, end, st);
6112 } 6133 }
6113 return true; 6134 return true;