src/os/solaris/vm/os_solaris.cpp

changeset 5365
59b052799158
parent 5272
1f4355cee9a2
child 5385
ec173c8f3739
     1.1 --- a/src/os/solaris/vm/os_solaris.cpp	Thu Jul 04 04:03:28 2013 -0700
     1.2 +++ b/src/os/solaris/vm/os_solaris.cpp	Thu Jul 04 21:10:17 2013 -0700
     1.3 @@ -1924,12 +1924,13 @@
     1.4    Dl_info dlinfo;
     1.5  
     1.6    if (libjvm_base_addr == NULL) {
     1.7 -    dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo);
     1.8 -    libjvm_base_addr = (address)dlinfo.dli_fbase;
     1.9 +    if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) {
    1.10 +      libjvm_base_addr = (address)dlinfo.dli_fbase;
    1.11 +    }
    1.12      assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
    1.13    }
    1.14  
    1.15 -  if (dladdr((void *)addr, &dlinfo)) {
    1.16 +  if (dladdr((void *)addr, &dlinfo) != 0) {
    1.17      if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
    1.18    }
    1.19  
    1.20 @@ -1941,114 +1942,133 @@
    1.21  
    1.22  bool os::dll_address_to_function_name(address addr, char *buf,
    1.23                                        int buflen, int * offset) {
    1.24 +  // buf is not optional, but offset is optional
    1.25 +  assert(buf != NULL, "sanity check");
    1.26 +
    1.27    Dl_info dlinfo;
    1.28  
    1.29    // dladdr1_func was initialized in os::init()
    1.30 -  if (dladdr1_func){
    1.31 -      // yes, we have dladdr1
    1.32 -
    1.33 -      // Support for dladdr1 is checked at runtime; it may be
    1.34 -      // available even if the vm is built on a machine that does
    1.35 -      // not have dladdr1 support.  Make sure there is a value for
    1.36 -      // RTLD_DL_SYMENT.
    1.37 -      #ifndef RTLD_DL_SYMENT
    1.38 -      #define RTLD_DL_SYMENT 1
    1.39 -      #endif
    1.40 +  if (dladdr1_func != NULL) {
    1.41 +    // yes, we have dladdr1
    1.42 +
    1.43 +    // Support for dladdr1 is checked at runtime; it may be
    1.44 +    // available even if the vm is built on a machine that does
    1.45 +    // not have dladdr1 support.  Make sure there is a value for
    1.46 +    // RTLD_DL_SYMENT.
    1.47 +    #ifndef RTLD_DL_SYMENT
    1.48 +    #define RTLD_DL_SYMENT 1
    1.49 +    #endif
    1.50  #ifdef _LP64
    1.51 -      Elf64_Sym * info;
    1.52 +    Elf64_Sym * info;
    1.53  #else
    1.54 -      Elf32_Sym * info;
    1.55 +    Elf32_Sym * info;
    1.56  #endif
    1.57 -      if (dladdr1_func((void *)addr, &dlinfo, (void **)&info,
    1.58 -                       RTLD_DL_SYMENT)) {
    1.59 -        if ((char *)dlinfo.dli_saddr + info->st_size > (char *)addr) {
    1.60 -          if (buf != NULL) {
    1.61 -            if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen))
    1.62 -              jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
    1.63 -            }
    1.64 -            if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
    1.65 -            return true;
    1.66 -        }
    1.67 -      }
    1.68 -      if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
    1.69 -        if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
    1.70 -           buf, buflen, offset, dlinfo.dli_fname)) {
    1.71 +    if (dladdr1_func((void *)addr, &dlinfo, (void **)&info,
    1.72 +                     RTLD_DL_SYMENT) != 0) {
    1.73 +      // see if we have a matching symbol that covers our address
    1.74 +      if (dlinfo.dli_saddr != NULL &&
    1.75 +          (char *)dlinfo.dli_saddr + info->st_size > (char *)addr) {
    1.76 +        if (dlinfo.dli_sname != NULL) {
    1.77 +          if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
    1.78 +            jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
    1.79 +          }
    1.80 +          if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
    1.81            return true;
    1.82          }
    1.83        }
    1.84 -      if (buf != NULL) buf[0] = '\0';
    1.85 -      if (offset != NULL) *offset  = -1;
    1.86 -      return false;
    1.87 -  } else {
    1.88 -      // no, only dladdr is available
    1.89 -      if (dladdr((void *)addr, &dlinfo)) {
    1.90 -        if (buf != NULL) {
    1.91 -          if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen))
    1.92 -            jio_snprintf(buf, buflen, dlinfo.dli_sname);
    1.93 -        }
    1.94 -        if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
    1.95 -        return true;
    1.96 -      } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
    1.97 +      // no matching symbol so try for just file info
    1.98 +      if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
    1.99          if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
   1.100 -          buf, buflen, offset, dlinfo.dli_fname)) {
   1.101 +                            buf, buflen, offset, dlinfo.dli_fname)) {
   1.102            return true;
   1.103          }
   1.104        }
   1.105 -      if (buf != NULL) buf[0] = '\0';
   1.106 -      if (offset != NULL) *offset  = -1;
   1.107 -      return false;
   1.108 -  }
   1.109 +    }
   1.110 +    buf[0] = '\0';
   1.111 +    if (offset != NULL) *offset  = -1;
   1.112 +    return false;
   1.113 +  }
   1.114 +
   1.115 +  // no, only dladdr is available
   1.116 +  if (dladdr((void *)addr, &dlinfo) != 0) {
   1.117 +    // see if we have a matching symbol
   1.118 +    if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {
   1.119 +      if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
   1.120 +        jio_snprintf(buf, buflen, dlinfo.dli_sname);
   1.121 +      }
   1.122 +      if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
   1.123 +      return true;
   1.124 +    }
   1.125 +    // no matching symbol so try for just file info
   1.126 +    if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
   1.127 +      if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
   1.128 +                          buf, buflen, offset, dlinfo.dli_fname)) {
   1.129 +        return true;
   1.130 +      }
   1.131 +    }
   1.132 +  }
   1.133 +  buf[0] = '\0';
   1.134 +  if (offset != NULL) *offset  = -1;
   1.135 +  return false;
   1.136  }
   1.137  
   1.138  bool os::dll_address_to_library_name(address addr, char* buf,
   1.139                                       int buflen, int* offset) {
   1.140 +  // buf is not optional, but offset is optional
   1.141 +  assert(buf != NULL, "sanity check");
   1.142 +
   1.143    Dl_info dlinfo;
   1.144  
   1.145 -  if (dladdr((void*)addr, &dlinfo)){
   1.146 -     if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
   1.147 -     if (offset) *offset = addr - (address)dlinfo.dli_fbase;
   1.148 -     return true;
   1.149 -  } else {
   1.150 -     if (buf) buf[0] = '\0';
   1.151 -     if (offset) *offset = -1;
   1.152 -     return false;
   1.153 -  }
   1.154 +  if (dladdr((void*)addr, &dlinfo) != 0) {
   1.155 +    if (dlinfo.dli_fname != NULL) {
   1.156 +      jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
   1.157 +    }
   1.158 +    if (dlinfo.dli_fbase != NULL && offset != NULL) {
   1.159 +      *offset = addr - (address)dlinfo.dli_fbase;
   1.160 +    }
   1.161 +    return true;
   1.162 +  }
   1.163 +
   1.164 +  buf[0] = '\0';
   1.165 +  if (offset) *offset = -1;
   1.166 +  return false;
   1.167  }
   1.168  
   1.169  // Prints the names and full paths of all opened dynamic libraries
   1.170  // for current process
   1.171  void os::print_dll_info(outputStream * st) {
   1.172 -    Dl_info dli;
   1.173 -    void *handle;
   1.174 -    Link_map *map;
   1.175 -    Link_map *p;
   1.176 -
   1.177 -    st->print_cr("Dynamic libraries:"); st->flush();
   1.178 -
   1.179 -    if (!dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli)) {
   1.180 -        st->print_cr("Error: Cannot print dynamic libraries.");
   1.181 -        return;
   1.182 -    }
   1.183 -    handle = dlopen(dli.dli_fname, RTLD_LAZY);
   1.184 -    if (handle == NULL) {
   1.185 -        st->print_cr("Error: Cannot print dynamic libraries.");
   1.186 -        return;
   1.187 -    }
   1.188 -    dlinfo(handle, RTLD_DI_LINKMAP, &map);
   1.189 -    if (map == NULL) {
   1.190 -        st->print_cr("Error: Cannot print dynamic libraries.");
   1.191 -        return;
   1.192 -    }
   1.193 -
   1.194 -    while (map->l_prev != NULL)
   1.195 -        map = map->l_prev;
   1.196 -
   1.197 -    while (map != NULL) {
   1.198 -        st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name);
   1.199 -        map = map->l_next;
   1.200 -    }
   1.201 -
   1.202 -    dlclose(handle);
   1.203 +  Dl_info dli;
   1.204 +  void *handle;
   1.205 +  Link_map *map;
   1.206 +  Link_map *p;
   1.207 +
   1.208 +  st->print_cr("Dynamic libraries:"); st->flush();
   1.209 +
   1.210 +  if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 ||
   1.211 +      dli.dli_fname == NULL) {
   1.212 +    st->print_cr("Error: Cannot print dynamic libraries.");
   1.213 +    return;
   1.214 +  }
   1.215 +  handle = dlopen(dli.dli_fname, RTLD_LAZY);
   1.216 +  if (handle == NULL) {
   1.217 +    st->print_cr("Error: Cannot print dynamic libraries.");
   1.218 +    return;
   1.219 +  }
   1.220 +  dlinfo(handle, RTLD_DI_LINKMAP, &map);
   1.221 +  if (map == NULL) {
   1.222 +    st->print_cr("Error: Cannot print dynamic libraries.");
   1.223 +    return;
   1.224 +  }
   1.225 +
   1.226 +  while (map->l_prev != NULL)
   1.227 +    map = map->l_prev;
   1.228 +
   1.229 +  while (map != NULL) {
   1.230 +    st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name);
   1.231 +    map = map->l_next;
   1.232 +  }
   1.233 +
   1.234 +  dlclose(handle);
   1.235  }
   1.236  
   1.237    // Loads .dll/.so and
   1.238 @@ -2475,7 +2495,12 @@
   1.239    Dl_info dlinfo;
   1.240    int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo);
   1.241    assert(ret != 0, "cannot locate libjvm");
   1.242 -  realpath((char *)dlinfo.dli_fname, buf);
   1.243 +  if (ret != 0 && dlinfo.dli_fname != NULL) {
   1.244 +    realpath((char *)dlinfo.dli_fname, buf);
   1.245 +  } else {
   1.246 +    buf[0] = '\0';
   1.247 +    return;
   1.248 +  }
   1.249  
   1.250    if (Arguments::created_by_gamma_launcher()) {
   1.251      // Support for the gamma launcher.  Typical value for buf is
   1.252 @@ -6077,24 +6102,20 @@
   1.253  bool os::find(address addr, outputStream* st) {
   1.254    Dl_info dlinfo;
   1.255    memset(&dlinfo, 0, sizeof(dlinfo));
   1.256 -  if (dladdr(addr, &dlinfo)) {
   1.257 -#ifdef _LP64
   1.258 -    st->print("0x%016lx: ", addr);
   1.259 -#else
   1.260 -    st->print("0x%08x: ", addr);
   1.261 -#endif
   1.262 -    if (dlinfo.dli_sname != NULL)
   1.263 +  if (dladdr(addr, &dlinfo) != 0) {
   1.264 +    st->print(PTR_FORMAT ": ", addr);
   1.265 +    if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {
   1.266        st->print("%s+%#lx", dlinfo.dli_sname, addr-(intptr_t)dlinfo.dli_saddr);
   1.267 -    else if (dlinfo.dli_fname)
   1.268 +    } else if (dlinfo.dli_fbase != NULL)
   1.269        st->print("<offset %#lx>", addr-(intptr_t)dlinfo.dli_fbase);
   1.270      else
   1.271        st->print("<absolute address>");
   1.272 -    if (dlinfo.dli_fname)  st->print(" in %s", dlinfo.dli_fname);
   1.273 -#ifdef _LP64
   1.274 -    if (dlinfo.dli_fbase)  st->print(" at 0x%016lx", dlinfo.dli_fbase);
   1.275 -#else
   1.276 -    if (dlinfo.dli_fbase)  st->print(" at 0x%08x", dlinfo.dli_fbase);
   1.277 -#endif
   1.278 +    if (dlinfo.dli_fname != NULL) {
   1.279 +      st->print(" in %s", dlinfo.dli_fname);
   1.280 +    }
   1.281 +    if (dlinfo.dli_fbase != NULL) {
   1.282 +      st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
   1.283 +    }
   1.284      st->cr();
   1.285  
   1.286      if (Verbose) {
   1.287 @@ -6105,7 +6126,7 @@
   1.288        if (!lowest)  lowest = (address) dlinfo.dli_fbase;
   1.289        if (begin < lowest)  begin = lowest;
   1.290        Dl_info dlinfo2;
   1.291 -      if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr
   1.292 +      if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr
   1.293            && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
   1.294          end = (address) dlinfo2.dli_saddr;
   1.295        Disassembler::decode(begin, end, st);

mercurial