comparison src/os/bsd/vm/os_bsd.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 c6ec0a97b30a 438e13354adf
comparison
equal deleted inserted replaced
11091:a55aa67bce1a 11092:59b052799158
1232 bool os::address_is_in_vm(address addr) { 1232 bool os::address_is_in_vm(address addr) {
1233 static address libjvm_base_addr; 1233 static address libjvm_base_addr;
1234 Dl_info dlinfo; 1234 Dl_info dlinfo;
1235 1235
1236 if (libjvm_base_addr == NULL) { 1236 if (libjvm_base_addr == NULL) {
1237 dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo); 1237 if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) {
1238 libjvm_base_addr = (address)dlinfo.dli_fbase; 1238 libjvm_base_addr = (address)dlinfo.dli_fbase;
1239 }
1239 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm"); 1240 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
1240 } 1241 }
1241 1242
1242 if (dladdr((void *)addr, &dlinfo)) { 1243 if (dladdr((void *)addr, &dlinfo) != 0) {
1243 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true; 1244 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
1244 } 1245 }
1245 1246
1246 return false; 1247 return false;
1247 } 1248 }
1249 1250
1250 #define MACH_MAXSYMLEN 256 1251 #define MACH_MAXSYMLEN 256
1251 1252
1252 bool os::dll_address_to_function_name(address addr, char *buf, 1253 bool os::dll_address_to_function_name(address addr, char *buf,
1253 int buflen, int *offset) { 1254 int buflen, int *offset) {
1255 // buf is not optional, but offset is optional
1256 assert(buf != NULL, "sanity check");
1257
1254 Dl_info dlinfo; 1258 Dl_info dlinfo;
1255 char localbuf[MACH_MAXSYMLEN]; 1259 char localbuf[MACH_MAXSYMLEN];
1256 1260
1257 // dladdr will find names of dynamic functions only, but does 1261 if (dladdr((void*)addr, &dlinfo) != 0) {
1258 // it set dli_fbase with mach_header address when it "fails" ? 1262 // see if we have a matching symbol
1259 if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) { 1263 if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {
1260 if (buf != NULL) { 1264 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
1261 if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
1262 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); 1265 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
1263 } 1266 }
1264 } 1267 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
1265 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; 1268 return true;
1266 return true; 1269 }
1267 } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) { 1270 // no matching symbol so try for just file info
1268 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), 1271 if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
1269 buf, buflen, offset, dlinfo.dli_fname)) { 1272 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
1270 return true; 1273 buf, buflen, offset, dlinfo.dli_fname)) {
1271 } 1274 return true;
1272 } 1275 }
1273 1276 }
1274 // Handle non-dymanic manually: 1277
1275 if (dlinfo.dli_fbase != NULL && 1278 // Handle non-dynamic manually:
1276 Decoder::decode(addr, localbuf, MACH_MAXSYMLEN, offset, dlinfo.dli_fbase)) { 1279 if (dlinfo.dli_fbase != NULL &&
1277 if(!Decoder::demangle(localbuf, buf, buflen)) { 1280 Decoder::decode(addr, localbuf, MACH_MAXSYMLEN, offset,
1278 jio_snprintf(buf, buflen, "%s", localbuf); 1281 dlinfo.dli_fbase)) {
1279 } 1282 if (!Decoder::demangle(localbuf, buf, buflen)) {
1280 return true; 1283 jio_snprintf(buf, buflen, "%s", localbuf);
1281 } 1284 }
1282 if (buf != NULL) buf[0] = '\0'; 1285 return true;
1286 }
1287 }
1288 buf[0] = '\0';
1283 if (offset != NULL) *offset = -1; 1289 if (offset != NULL) *offset = -1;
1284 return false; 1290 return false;
1285 } 1291 }
1286 1292
1287 // ported from solaris version 1293 // ported from solaris version
1288 bool os::dll_address_to_library_name(address addr, char* buf, 1294 bool os::dll_address_to_library_name(address addr, char* buf,
1289 int buflen, int* offset) { 1295 int buflen, int* offset) {
1296 // buf is not optional, but offset is optional
1297 assert(buf != NULL, "sanity check");
1298
1290 Dl_info dlinfo; 1299 Dl_info dlinfo;
1291 1300
1292 if (dladdr((void*)addr, &dlinfo)){ 1301 if (dladdr((void*)addr, &dlinfo) != 0) {
1293 if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); 1302 if (dlinfo.dli_fname != NULL) {
1294 if (offset) *offset = addr - (address)dlinfo.dli_fbase; 1303 jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
1295 return true; 1304 }
1296 } else { 1305 if (dlinfo.dli_fbase != NULL && offset != NULL) {
1297 if (buf) buf[0] = '\0'; 1306 *offset = addr - (address)dlinfo.dli_fbase;
1298 if (offset) *offset = -1; 1307 }
1299 return false; 1308 return true;
1300 } 1309 }
1310
1311 buf[0] = '\0';
1312 if (offset) *offset = -1;
1313 return false;
1301 } 1314 }
1302 1315
1303 // Loads .dll/.so and 1316 // Loads .dll/.so and
1304 // in case of error it checks if .dll/.so was built for the 1317 // in case of error it checks if .dll/.so was built for the
1305 // same architecture as Hotspot is running on 1318 // same architecture as Hotspot is running on
1518 1531
1519 return true; 1532 return true;
1520 } 1533 }
1521 1534
1522 void os::print_dll_info(outputStream *st) { 1535 void os::print_dll_info(outputStream *st) {
1523 st->print_cr("Dynamic libraries:"); 1536 st->print_cr("Dynamic libraries:");
1524 #ifdef RTLD_DI_LINKMAP 1537 #ifdef RTLD_DI_LINKMAP
1525 Dl_info dli; 1538 Dl_info dli;
1526 void *handle; 1539 void *handle;
1527 Link_map *map; 1540 Link_map *map;
1528 Link_map *p; 1541 Link_map *p;
1529 1542
1530 if (!dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli)) { 1543 if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 ||
1531 st->print_cr("Error: Cannot print dynamic libraries."); 1544 dli.dli_fname == NULL) {
1532 return; 1545 st->print_cr("Error: Cannot print dynamic libraries.");
1533 } 1546 return;
1534 handle = dlopen(dli.dli_fname, RTLD_LAZY); 1547 }
1535 if (handle == NULL) { 1548 handle = dlopen(dli.dli_fname, RTLD_LAZY);
1536 st->print_cr("Error: Cannot print dynamic libraries."); 1549 if (handle == NULL) {
1537 return; 1550 st->print_cr("Error: Cannot print dynamic libraries.");
1538 } 1551 return;
1539 dlinfo(handle, RTLD_DI_LINKMAP, &map); 1552 }
1540 if (map == NULL) { 1553 dlinfo(handle, RTLD_DI_LINKMAP, &map);
1541 st->print_cr("Error: Cannot print dynamic libraries."); 1554 if (map == NULL) {
1542 return; 1555 st->print_cr("Error: Cannot print dynamic libraries.");
1543 } 1556 return;
1544 1557 }
1545 while (map->l_prev != NULL) 1558
1546 map = map->l_prev; 1559 while (map->l_prev != NULL)
1547 1560 map = map->l_prev;
1548 while (map != NULL) { 1561
1549 st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name); 1562 while (map != NULL) {
1550 map = map->l_next; 1563 st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name);
1551 } 1564 map = map->l_next;
1552 1565 }
1553 dlclose(handle); 1566
1567 dlclose(handle);
1554 #elif defined(__APPLE__) 1568 #elif defined(__APPLE__)
1555 uint32_t count; 1569 uint32_t count;
1556 uint32_t i; 1570 uint32_t i;
1557 1571
1558 count = _dyld_image_count(); 1572 count = _dyld_image_count();
1559 for (i = 1; i < count; i++) { 1573 for (i = 1; i < count; i++) {
1560 const char *name = _dyld_get_image_name(i); 1574 const char *name = _dyld_get_image_name(i);
1561 intptr_t slide = _dyld_get_image_vmaddr_slide(i); 1575 intptr_t slide = _dyld_get_image_vmaddr_slide(i);
1562 st->print_cr(PTR_FORMAT " \t%s", slide, name); 1576 st->print_cr(PTR_FORMAT " \t%s", slide, name);
1563 } 1577 }
1564 #else 1578 #else
1565 st->print_cr("Error: Cannot print dynamic libraries."); 1579 st->print_cr("Error: Cannot print dynamic libraries.");
1566 #endif 1580 #endif
1567 } 1581 }
1568 1582
1569 void os::print_os_info_brief(outputStream* st) { 1583 void os::print_os_info_brief(outputStream* st) {
1570 st->print("Bsd"); 1584 st->print("Bsd");
1705 1719
1706 char dli_fname[MAXPATHLEN]; 1720 char dli_fname[MAXPATHLEN];
1707 bool ret = dll_address_to_library_name( 1721 bool ret = dll_address_to_library_name(
1708 CAST_FROM_FN_PTR(address, os::jvm_path), 1722 CAST_FROM_FN_PTR(address, os::jvm_path),
1709 dli_fname, sizeof(dli_fname), NULL); 1723 dli_fname, sizeof(dli_fname), NULL);
1710 assert(ret != 0, "cannot locate libjvm"); 1724 assert(ret, "cannot locate libjvm");
1711 char *rp = realpath(dli_fname, buf); 1725 char *rp = NULL;
1726 if (ret && dli_fname[0] != '\0') {
1727 rp = realpath(dli_fname, buf);
1728 }
1712 if (rp == NULL) 1729 if (rp == NULL)
1713 return; 1730 return;
1714 1731
1715 if (Arguments::created_by_gamma_launcher()) { 1732 if (Arguments::created_by_gamma_launcher()) {
1716 // Support for the gamma launcher. Typical value for buf is 1733 // Support for the gamma launcher. Typical value for buf is
3745 // debug support 3762 // debug support
3746 3763
3747 bool os::find(address addr, outputStream* st) { 3764 bool os::find(address addr, outputStream* st) {
3748 Dl_info dlinfo; 3765 Dl_info dlinfo;
3749 memset(&dlinfo, 0, sizeof(dlinfo)); 3766 memset(&dlinfo, 0, sizeof(dlinfo));
3750 if (dladdr(addr, &dlinfo)) { 3767 if (dladdr(addr, &dlinfo) != 0) {
3751 st->print(PTR_FORMAT ": ", addr); 3768 st->print(PTR_FORMAT ": ", addr);
3752 if (dlinfo.dli_sname != NULL) { 3769 if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {
3753 st->print("%s+%#x", dlinfo.dli_sname, 3770 st->print("%s+%#x", dlinfo.dli_sname,
3754 addr - (intptr_t)dlinfo.dli_saddr); 3771 addr - (intptr_t)dlinfo.dli_saddr);
3755 } else if (dlinfo.dli_fname) { 3772 } else if (dlinfo.dli_fbase != NULL) {
3756 st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase); 3773 st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase);
3757 } else { 3774 } else {
3758 st->print("<absolute address>"); 3775 st->print("<absolute address>");
3759 } 3776 }
3760 if (dlinfo.dli_fname) { 3777 if (dlinfo.dli_fname != NULL) {
3761 st->print(" in %s", dlinfo.dli_fname); 3778 st->print(" in %s", dlinfo.dli_fname);
3762 } 3779 }
3763 if (dlinfo.dli_fbase) { 3780 if (dlinfo.dli_fbase != NULL) {
3764 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase); 3781 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
3765 } 3782 }
3766 st->cr(); 3783 st->cr();
3767 3784
3768 if (Verbose) { 3785 if (Verbose) {
3771 address end = clamp_address_in_page(addr+40, addr, os::vm_page_size()); 3788 address end = clamp_address_in_page(addr+40, addr, os::vm_page_size());
3772 address lowest = (address) dlinfo.dli_sname; 3789 address lowest = (address) dlinfo.dli_sname;
3773 if (!lowest) lowest = (address) dlinfo.dli_fbase; 3790 if (!lowest) lowest = (address) dlinfo.dli_fbase;
3774 if (begin < lowest) begin = lowest; 3791 if (begin < lowest) begin = lowest;
3775 Dl_info dlinfo2; 3792 Dl_info dlinfo2;
3776 if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr 3793 if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr
3777 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) 3794 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
3778 end = (address) dlinfo2.dli_saddr; 3795 end = (address) dlinfo2.dli_saddr;
3779 Disassembler::decode(begin, end, st); 3796 Disassembler::decode(begin, end, st);
3780 } 3797 }
3781 return true; 3798 return true;