comparison src/os/linux/vm/os_linux.cpp @ 11173:6b0fd0964b87

Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author Doug Simon <doug.simon@oracle.com>
date Wed, 31 Jul 2013 11:00:54 +0200
parents 836a62f43af9 59b052799158
children cefad50507d8
comparison
equal deleted inserted replaced
10912:4ea54634f03e 11173:6b0fd0964b87
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
2610 ::close(fd); 2628 ::close(fd);
2611 unlink(buf); 2629 unlink(buf);
2612 } 2630 }
2613 } 2631 }
2614 2632
2633 static bool recoverable_mmap_error(int err) {
2634 // See if the error is one we can let the caller handle. This
2635 // list of errno values comes from JBS-6843484. I can't find a
2636 // Linux man page that documents this specific set of errno
2637 // values so while this list currently matches Solaris, it may
2638 // change as we gain experience with this failure mode.
2639 switch (err) {
2640 case EBADF:
2641 case EINVAL:
2642 case ENOTSUP:
2643 // let the caller deal with these errors
2644 return true;
2645
2646 default:
2647 // Any remaining errors on this OS can cause our reserved mapping
2648 // to be lost. That can cause confusion where different data
2649 // structures think they have the same memory mapped. The worst
2650 // scenario is if both the VM and a library think they have the
2651 // same memory mapped.
2652 return false;
2653 }
2654 }
2655
2656 static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
2657 int err) {
2658 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
2659 ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
2660 strerror(err), err);
2661 }
2662
2663 static void warn_fail_commit_memory(char* addr, size_t size,
2664 size_t alignment_hint, bool exec,
2665 int err) {
2666 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
2667 ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, size,
2668 alignment_hint, exec, strerror(err), err);
2669 }
2670
2615 // NOTE: Linux kernel does not really reserve the pages for us. 2671 // NOTE: Linux kernel does not really reserve the pages for us.
2616 // All it does is to check if there are enough free pages 2672 // All it does is to check if there are enough free pages
2617 // left at the time of mmap(). This could be a potential 2673 // left at the time of mmap(). This could be a potential
2618 // problem. 2674 // problem.
2619 bool os::pd_commit_memory(char* addr, size_t size, bool exec) { 2675 int os::Linux::commit_memory_impl(char* addr, size_t size, bool exec) {
2620 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; 2676 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
2621 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, 2677 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
2622 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); 2678 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
2623 if (res != (uintptr_t) MAP_FAILED) { 2679 if (res != (uintptr_t) MAP_FAILED) {
2624 if (UseNUMAInterleaving) { 2680 if (UseNUMAInterleaving) {
2625 numa_make_global(addr, size); 2681 numa_make_global(addr, size);
2626 } 2682 }
2627 return true; 2683 return 0;
2628 } 2684 }
2629 return false; 2685
2686 int err = errno; // save errno from mmap() call above
2687
2688 if (!recoverable_mmap_error(err)) {
2689 warn_fail_commit_memory(addr, size, exec, err);
2690 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "committing reserved memory.");
2691 }
2692
2693 return err;
2694 }
2695
2696 bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
2697 return os::Linux::commit_memory_impl(addr, size, exec) == 0;
2698 }
2699
2700 void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
2701 const char* mesg) {
2702 assert(mesg != NULL, "mesg must be specified");
2703 int err = os::Linux::commit_memory_impl(addr, size, exec);
2704 if (err != 0) {
2705 // the caller wants all commit errors to exit with the specified mesg:
2706 warn_fail_commit_memory(addr, size, exec, err);
2707 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
2708 }
2630 } 2709 }
2631 2710
2632 // Define MAP_HUGETLB here so we can build HotSpot on old systems. 2711 // Define MAP_HUGETLB here so we can build HotSpot on old systems.
2633 #ifndef MAP_HUGETLB 2712 #ifndef MAP_HUGETLB
2634 #define MAP_HUGETLB 0x40000 2713 #define MAP_HUGETLB 0x40000
2637 // Define MADV_HUGEPAGE here so we can build HotSpot on old systems. 2716 // Define MADV_HUGEPAGE here so we can build HotSpot on old systems.
2638 #ifndef MADV_HUGEPAGE 2717 #ifndef MADV_HUGEPAGE
2639 #define MADV_HUGEPAGE 14 2718 #define MADV_HUGEPAGE 14
2640 #endif 2719 #endif
2641 2720
2642 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, 2721 int os::Linux::commit_memory_impl(char* addr, size_t size,
2643 bool exec) { 2722 size_t alignment_hint, bool exec) {
2723 int err;
2644 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { 2724 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
2645 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; 2725 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
2646 uintptr_t res = 2726 uintptr_t res =
2647 (uintptr_t) ::mmap(addr, size, prot, 2727 (uintptr_t) ::mmap(addr, size, prot,
2648 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB, 2728 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB,
2649 -1, 0); 2729 -1, 0);
2650 if (res != (uintptr_t) MAP_FAILED) { 2730 if (res != (uintptr_t) MAP_FAILED) {
2651 if (UseNUMAInterleaving) { 2731 if (UseNUMAInterleaving) {
2652 numa_make_global(addr, size); 2732 numa_make_global(addr, size);
2653 } 2733 }
2654 return true; 2734 return 0;
2735 }
2736
2737 err = errno; // save errno from mmap() call above
2738
2739 if (!recoverable_mmap_error(err)) {
2740 // However, it is not clear that this loss of our reserved mapping
2741 // happens with large pages on Linux or that we cannot recover
2742 // from the loss. For now, we just issue a warning and we don't
2743 // call vm_exit_out_of_memory(). This issue is being tracked by
2744 // JBS-8007074.
2745 warn_fail_commit_memory(addr, size, alignment_hint, exec, err);
2746 // vm_exit_out_of_memory(size, OOM_MMAP_ERROR,
2747 // "committing reserved memory.");
2655 } 2748 }
2656 // Fall through and try to use small pages 2749 // Fall through and try to use small pages
2657 } 2750 }
2658 2751
2659 if (commit_memory(addr, size, exec)) { 2752 err = os::Linux::commit_memory_impl(addr, size, exec);
2753 if (err == 0) {
2660 realign_memory(addr, size, alignment_hint); 2754 realign_memory(addr, size, alignment_hint);
2661 return true; 2755 }
2662 } 2756 return err;
2663 return false; 2757 }
2758
2759 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
2760 bool exec) {
2761 return os::Linux::commit_memory_impl(addr, size, alignment_hint, exec) == 0;
2762 }
2763
2764 void os::pd_commit_memory_or_exit(char* addr, size_t size,
2765 size_t alignment_hint, bool exec,
2766 const char* mesg) {
2767 assert(mesg != NULL, "mesg must be specified");
2768 int err = os::Linux::commit_memory_impl(addr, size, alignment_hint, exec);
2769 if (err != 0) {
2770 // the caller wants all commit errors to exit with the specified mesg:
2771 warn_fail_commit_memory(addr, size, alignment_hint, exec, err);
2772 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
2773 }
2664 } 2774 }
2665 2775
2666 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { 2776 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
2667 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { 2777 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
2668 // We don't check the return value: madvise(MADV_HUGEPAGE) may not 2778 // We don't check the return value: madvise(MADV_HUGEPAGE) may not
2676 // the existing pages. However it won't work for SHM-based large pages that cannot be 2786 // the existing pages. However it won't work for SHM-based large pages that cannot be
2677 // uncommitted at all. We don't do anything in this case to avoid creating a segment with 2787 // uncommitted at all. We don't do anything in this case to avoid creating a segment with
2678 // small pages on top of the SHM segment. This method always works for small pages, so we 2788 // small pages on top of the SHM segment. This method always works for small pages, so we
2679 // allow that in any case. 2789 // allow that in any case.
2680 if (alignment_hint <= (size_t)os::vm_page_size() || !UseSHM) { 2790 if (alignment_hint <= (size_t)os::vm_page_size() || !UseSHM) {
2681 commit_memory(addr, bytes, alignment_hint, false); 2791 commit_memory(addr, bytes, alignment_hint, !ExecMem);
2682 } 2792 }
2683 } 2793 }
2684 2794
2685 void os::numa_make_global(char *addr, size_t bytes) { 2795 void os::numa_make_global(char *addr, size_t bytes) {
2686 Linux::numa_interleave_memory(addr, bytes); 2796 Linux::numa_interleave_memory(addr, bytes);
2929 "growable stack in non-initial thread"); 3039 "growable stack in non-initial thread");
2930 if (stack_extent < (uintptr_t)addr) 3040 if (stack_extent < (uintptr_t)addr)
2931 ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent); 3041 ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent);
2932 } 3042 }
2933 3043
2934 return os::commit_memory(addr, size); 3044 return os::commit_memory(addr, size, !ExecMem);
2935 } 3045 }
2936 3046
2937 // If this is a growable mapping, remove the guard pages entirely by 3047 // If this is a growable mapping, remove the guard pages entirely by
2938 // munmap()ping them. If not, just call uncommit_memory(). This only 3048 // munmap()ping them. If not, just call uncommit_memory(). This only
2939 // affects the main/initial thread, but guard against future OS changes 3049 // affects the main/initial thread, but guard against future OS changes
3051 bool result = false; 3161 bool result = false;
3052 void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE, 3162 void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE,
3053 MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB, 3163 MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
3054 -1, 0); 3164 -1, 0);
3055 3165
3056 if (p != (void *) -1) { 3166 if (p != MAP_FAILED) {
3057 // We don't know if this really is a huge page or not. 3167 // We don't know if this really is a huge page or not.
3058 FILE *fp = fopen("/proc/self/maps", "r"); 3168 FILE *fp = fopen("/proc/self/maps", "r");
3059 if (fp) { 3169 if (fp) {
3060 while (!feof(fp)) { 3170 while (!feof(fp)) {
3061 char chars[257]; 3171 char chars[257];
3269 if ((addr != NULL) && UseNUMAInterleaving) { 3379 if ((addr != NULL) && UseNUMAInterleaving) {
3270 numa_make_global(addr, bytes); 3380 numa_make_global(addr, bytes);
3271 } 3381 }
3272 3382
3273 // The memory is committed 3383 // The memory is committed
3274 address pc = CALLER_PC; 3384 MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, mtNone, CALLER_PC);
3275 MemTracker::record_virtual_memory_reserve((address)addr, bytes, pc);
3276 MemTracker::record_virtual_memory_commit((address)addr, bytes, pc);
3277 3385
3278 return addr; 3386 return addr;
3279 } 3387 }
3280 3388
3281 bool os::release_memory_special(char* base, size_t bytes) { 3389 bool os::release_memory_special(char* base, size_t bytes) {
3390 MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
3282 // detaching the SHM segment will also delete it, see reserve_memory_special() 3391 // detaching the SHM segment will also delete it, see reserve_memory_special()
3283 int rslt = shmdt(base); 3392 int rslt = shmdt(base);
3284 if (rslt == 0) { 3393 if (rslt == 0) {
3285 MemTracker::record_virtual_memory_uncommit((address)base, bytes); 3394 tkr.record((address)base, bytes);
3286 MemTracker::record_virtual_memory_release((address)base, bytes);
3287 return true; 3395 return true;
3288 } else { 3396 } else {
3289 return false; 3397 tkr.discard();
3398 return false;
3290 } 3399 }
3291 } 3400 }
3292 3401
3293 size_t os::large_page_size() { 3402 size_t os::large_page_size() {
3294 return _large_page_size; 3403 return _large_page_size;
4391 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page); 4500 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);
4392 #endif 4501 #endif
4393 4502
4394 if (!UseMembar) { 4503 if (!UseMembar) {
4395 address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 4504 address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
4396 guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page"); 4505 guarantee( mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
4397 os::set_memory_serialize_page( mem_serialize_page ); 4506 os::set_memory_serialize_page( mem_serialize_page );
4398 4507
4399 #ifndef PRODUCT 4508 #ifndef PRODUCT
4400 if(Verbose && PrintMiscellaneous) 4509 if(Verbose && PrintMiscellaneous)
4401 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); 4510 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
4637 // debug support 4746 // debug support
4638 4747
4639 bool os::find(address addr, outputStream* st) { 4748 bool os::find(address addr, outputStream* st) {
4640 Dl_info dlinfo; 4749 Dl_info dlinfo;
4641 memset(&dlinfo, 0, sizeof(dlinfo)); 4750 memset(&dlinfo, 0, sizeof(dlinfo));
4642 if (dladdr(addr, &dlinfo)) { 4751 if (dladdr(addr, &dlinfo) != 0) {
4643 st->print(PTR_FORMAT ": ", addr); 4752 st->print(PTR_FORMAT ": ", addr);
4644 if (dlinfo.dli_sname != NULL) { 4753 if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {
4645 st->print("%s+%#x", dlinfo.dli_sname, 4754 st->print("%s+%#x", dlinfo.dli_sname,
4646 addr - (intptr_t)dlinfo.dli_saddr); 4755 addr - (intptr_t)dlinfo.dli_saddr);
4647 } else if (dlinfo.dli_fname) { 4756 } else if (dlinfo.dli_fbase != NULL) {
4648 st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase); 4757 st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase);
4649 } else { 4758 } else {
4650 st->print("<absolute address>"); 4759 st->print("<absolute address>");
4651 } 4760 }
4652 if (dlinfo.dli_fname) { 4761 if (dlinfo.dli_fname != NULL) {
4653 st->print(" in %s", dlinfo.dli_fname); 4762 st->print(" in %s", dlinfo.dli_fname);
4654 } 4763 }
4655 if (dlinfo.dli_fbase) { 4764 if (dlinfo.dli_fbase != NULL) {
4656 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase); 4765 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
4657 } 4766 }
4658 st->cr(); 4767 st->cr();
4659 4768
4660 if (Verbose) { 4769 if (Verbose) {
4663 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());
4664 address lowest = (address) dlinfo.dli_sname; 4773 address lowest = (address) dlinfo.dli_sname;
4665 if (!lowest) lowest = (address) dlinfo.dli_fbase; 4774 if (!lowest) lowest = (address) dlinfo.dli_fbase;
4666 if (begin < lowest) begin = lowest; 4775 if (begin < lowest) begin = lowest;
4667 Dl_info dlinfo2; 4776 Dl_info dlinfo2;
4668 if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr 4777 if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr
4669 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) 4778 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
4670 end = (address) dlinfo2.dli_saddr; 4779 end = (address) dlinfo2.dli_saddr;
4671 Disassembler::decode(begin, end, st); 4780 Disassembler::decode(begin, end, st);
4672 } 4781 }
4673 return true; 4782 return true;