Mercurial > hg > truffle
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; |