src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 53379 e47074d2d8cc
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
    29 #include <stdlib.h>
    29 #include <stdlib.h>
    30 #include <stddef.h>
    30 #include <stddef.h>
    31 #include <elf.h>
    31 #include <elf.h>
    32 #include <link.h>
    32 #include <link.h>
    33 #include "libproc_impl.h"
    33 #include "libproc_impl.h"
       
    34 #include "ps_core_common.h"
    34 #include "proc_service.h"
    35 #include "proc_service.h"
    35 #include "salibelf.h"
    36 #include "salibelf.h"
    36 #include "cds.h"
       
    37 
    37 
    38 // This file has the libproc implementation to read core files.
    38 // This file has the libproc implementation to read core files.
    39 // For live processes, refer to ps_proc.c. Portions of this is adapted
    39 // For live processes, refer to ps_proc.c. Portions of this is adapted
    40 // /modelled after Solaris libproc.so (in particular Pcore.c)
    40 // /modelled after Solaris libproc.so (in particular Pcore.c)
    41 
       
    42 //----------------------------------------------------------------------
       
    43 // ps_prochandle cleanup helper functions
       
    44 
       
    45 // close all file descriptors
       
    46 static void close_files(struct ps_prochandle* ph) {
       
    47   lib_info* lib = NULL;
       
    48 
       
    49   // close core file descriptor
       
    50   if (ph->core->core_fd >= 0)
       
    51     close(ph->core->core_fd);
       
    52 
       
    53   // close exec file descriptor
       
    54   if (ph->core->exec_fd >= 0)
       
    55     close(ph->core->exec_fd);
       
    56 
       
    57   // close interp file descriptor
       
    58   if (ph->core->interp_fd >= 0)
       
    59     close(ph->core->interp_fd);
       
    60 
       
    61   // close class share archive file
       
    62   if (ph->core->classes_jsa_fd >= 0)
       
    63     close(ph->core->classes_jsa_fd);
       
    64 
       
    65   // close all library file descriptors
       
    66   lib = ph->libs;
       
    67   while (lib) {
       
    68     int fd = lib->fd;
       
    69     if (fd >= 0 && fd != ph->core->exec_fd) {
       
    70       close(fd);
       
    71     }
       
    72     lib = lib->next;
       
    73   }
       
    74 }
       
    75 
       
    76 // clean all map_info stuff
       
    77 static void destroy_map_info(struct ps_prochandle* ph) {
       
    78   map_info* map = ph->core->maps;
       
    79   while (map) {
       
    80     map_info* next = map->next;
       
    81     free(map);
       
    82     map = next;
       
    83   }
       
    84 
       
    85   if (ph->core->map_array) {
       
    86     free(ph->core->map_array);
       
    87   }
       
    88 
       
    89   // Part of the class sharing workaround
       
    90   map = ph->core->class_share_maps;
       
    91   while (map) {
       
    92     map_info* next = map->next;
       
    93     free(map);
       
    94     map = next;
       
    95   }
       
    96 }
       
    97 
       
    98 // ps_prochandle operations
       
    99 static void core_release(struct ps_prochandle* ph) {
       
   100   if (ph->core) {
       
   101     close_files(ph);
       
   102     destroy_map_info(ph);
       
   103     free(ph->core);
       
   104   }
       
   105 }
       
   106 
       
   107 static map_info* allocate_init_map(int fd, off_t offset, uintptr_t vaddr, size_t memsz) {
       
   108   map_info* map;
       
   109   if ( (map = (map_info*) calloc(1, sizeof(map_info))) == NULL) {
       
   110     print_debug("can't allocate memory for map_info\n");
       
   111     return NULL;
       
   112   }
       
   113 
       
   114   // initialize map
       
   115   map->fd     = fd;
       
   116   map->offset = offset;
       
   117   map->vaddr  = vaddr;
       
   118   map->memsz  = memsz;
       
   119   return map;
       
   120 }
       
   121 
       
   122 // add map info with given fd, offset, vaddr and memsz
       
   123 static map_info* add_map_info(struct ps_prochandle* ph, int fd, off_t offset,
       
   124                              uintptr_t vaddr, size_t memsz) {
       
   125   map_info* map;
       
   126   if ((map = allocate_init_map(fd, offset, vaddr, memsz)) == NULL) {
       
   127     return NULL;
       
   128   }
       
   129 
       
   130   // add this to map list
       
   131   map->next  = ph->core->maps;
       
   132   ph->core->maps   = map;
       
   133   ph->core->num_maps++;
       
   134 
       
   135   return map;
       
   136 }
       
   137 
       
   138 // Part of the class sharing workaround
       
   139 static map_info* add_class_share_map_info(struct ps_prochandle* ph, off_t offset,
       
   140                              uintptr_t vaddr, size_t memsz) {
       
   141   map_info* map;
       
   142   if ((map = allocate_init_map(ph->core->classes_jsa_fd,
       
   143                                offset, vaddr, memsz)) == NULL) {
       
   144     return NULL;
       
   145   }
       
   146 
       
   147   map->next = ph->core->class_share_maps;
       
   148   ph->core->class_share_maps = map;
       
   149   return map;
       
   150 }
       
   151 
       
   152 // Return the map_info for the given virtual address.  We keep a sorted
       
   153 // array of pointers in ph->map_array, so we can binary search.
       
   154 static map_info* core_lookup(struct ps_prochandle *ph, uintptr_t addr) {
       
   155   int mid, lo = 0, hi = ph->core->num_maps - 1;
       
   156   map_info *mp;
       
   157 
       
   158   while (hi - lo > 1) {
       
   159     mid = (lo + hi) / 2;
       
   160     if (addr >= ph->core->map_array[mid]->vaddr) {
       
   161       lo = mid;
       
   162     } else {
       
   163       hi = mid;
       
   164     }
       
   165   }
       
   166 
       
   167   if (addr < ph->core->map_array[hi]->vaddr) {
       
   168     mp = ph->core->map_array[lo];
       
   169   } else {
       
   170     mp = ph->core->map_array[hi];
       
   171   }
       
   172 
       
   173   if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
       
   174     return (mp);
       
   175   }
       
   176 
       
   177 
       
   178   // Part of the class sharing workaround
       
   179   // Unfortunately, we have no way of detecting -Xshare state.
       
   180   // Check out the share maps atlast, if we don't find anywhere.
       
   181   // This is done this way so to avoid reading share pages
       
   182   // ahead of other normal maps. For eg. with -Xshare:off we don't
       
   183   // want to prefer class sharing data to data from core.
       
   184   mp = ph->core->class_share_maps;
       
   185   if (mp) {
       
   186     print_debug("can't locate map_info at 0x%lx, trying class share maps\n", addr);
       
   187   }
       
   188   while (mp) {
       
   189     if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
       
   190       print_debug("located map_info at 0x%lx from class share maps\n", addr);
       
   191       return (mp);
       
   192     }
       
   193     mp = mp->next;
       
   194   }
       
   195 
       
   196   print_debug("can't locate map_info at 0x%lx\n", addr);
       
   197   return (NULL);
       
   198 }
       
   199 
       
   200 //---------------------------------------------------------------
       
   201 // Part of the class sharing workaround:
       
   202 //
       
   203 // With class sharing, pages are mapped from classes.jsa file.
       
   204 // The read-only class sharing pages are mapped as MAP_SHARED,
       
   205 // PROT_READ pages. These pages are not dumped into core dump.
       
   206 // With this workaround, these pages are read from classes.jsa.
       
   207 
       
   208 static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
       
   209   jboolean i;
       
   210   if (ps_pdread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
       
   211     *pvalue = i;
       
   212     return true;
       
   213   } else {
       
   214     return false;
       
   215   }
       
   216 }
       
   217 
       
   218 static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
       
   219   uintptr_t uip;
       
   220   if (ps_pdread(ph, (psaddr_t) addr, (char *)&uip, sizeof(uip)) == PS_OK) {
       
   221     *pvalue = uip;
       
   222     return true;
       
   223   } else {
       
   224     return false;
       
   225   }
       
   226 }
       
   227 
       
   228 // used to read strings from debuggee
       
   229 static bool read_string(struct ps_prochandle* ph, uintptr_t addr, char* buf, size_t size) {
       
   230   size_t i = 0;
       
   231   char  c = ' ';
       
   232 
       
   233   while (c != '\0') {
       
   234     if (ps_pdread(ph, (psaddr_t) addr, &c, sizeof(char)) != PS_OK) {
       
   235       return false;
       
   236     }
       
   237     if (i < size - 1) {
       
   238       buf[i] = c;
       
   239     } else {
       
   240       // smaller buffer
       
   241       return false;
       
   242     }
       
   243     i++; addr++;
       
   244   }
       
   245 
       
   246   buf[i] = '\0';
       
   247   return true;
       
   248 }
       
   249 
       
   250 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
       
   251 // mangled name of Arguments::SharedArchivePath
       
   252 #define SHARED_ARCHIVE_PATH_SYM "_ZN9Arguments17SharedArchivePathE"
       
   253 #define LIBJVM_NAME "/libjvm.so"
       
   254 
       
   255 static bool init_classsharing_workaround(struct ps_prochandle* ph) {
       
   256   lib_info* lib = ph->libs;
       
   257   while (lib != NULL) {
       
   258     // we are iterating over shared objects from the core dump. look for
       
   259     // libjvm.so.
       
   260     const char *jvm_name = 0;
       
   261     if ((jvm_name = strstr(lib->name, LIBJVM_NAME)) != 0) {
       
   262       char classes_jsa[PATH_MAX];
       
   263       CDSFileMapHeaderBase header;
       
   264       int fd = -1;
       
   265       int m = 0;
       
   266       size_t n = 0;
       
   267       uintptr_t base = 0, useSharedSpacesAddr = 0;
       
   268       uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
       
   269       jboolean useSharedSpaces = 0;
       
   270       map_info* mi = 0;
       
   271 
       
   272       memset(classes_jsa, 0, sizeof(classes_jsa));
       
   273       jvm_name = lib->name;
       
   274       useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
       
   275       if (useSharedSpacesAddr == 0) {
       
   276         print_debug("can't lookup 'UseSharedSpaces' flag\n");
       
   277         return false;
       
   278       }
       
   279 
       
   280       // Hotspot vm types are not exported to build this library. So
       
   281       // using equivalent type jboolean to read the value of
       
   282       // UseSharedSpaces which is same as hotspot type "bool".
       
   283       if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
       
   284         print_debug("can't read the value of 'UseSharedSpaces' flag\n");
       
   285         return false;
       
   286       }
       
   287 
       
   288       if ((int)useSharedSpaces == 0) {
       
   289         print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
       
   290         return true;
       
   291       }
       
   292 
       
   293       sharedArchivePathAddrAddr = lookup_symbol(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM);
       
   294       if (sharedArchivePathAddrAddr == 0) {
       
   295         print_debug("can't lookup shared archive path symbol\n");
       
   296         return false;
       
   297       }
       
   298 
       
   299       if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
       
   300         print_debug("can't read shared archive path pointer\n");
       
   301         return false;
       
   302       }
       
   303 
       
   304       if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
       
   305         print_debug("can't read shared archive path value\n");
       
   306         return false;
       
   307       }
       
   308 
       
   309       print_debug("looking for %s\n", classes_jsa);
       
   310       // open the class sharing archive file
       
   311       fd = pathmap_open(classes_jsa);
       
   312       if (fd < 0) {
       
   313         print_debug("can't open %s!\n", classes_jsa);
       
   314         ph->core->classes_jsa_fd = -1;
       
   315         return false;
       
   316       } else {
       
   317         print_debug("opened %s\n", classes_jsa);
       
   318       }
       
   319 
       
   320       // read CDSFileMapHeaderBase from the file
       
   321       memset(&header, 0, sizeof(CDSFileMapHeaderBase));
       
   322       if ((n = read(fd, &header, sizeof(CDSFileMapHeaderBase)))
       
   323            != sizeof(CDSFileMapHeaderBase)) {
       
   324         print_debug("can't read shared archive file map header from %s\n", classes_jsa);
       
   325         close(fd);
       
   326         return false;
       
   327       }
       
   328 
       
   329       // check file magic
       
   330       if (header._magic != CDS_ARCHIVE_MAGIC) {
       
   331         print_debug("%s has bad shared archive file magic number 0x%x, expecting 0x%x\n",
       
   332                     classes_jsa, header._magic, CDS_ARCHIVE_MAGIC);
       
   333         close(fd);
       
   334         return false;
       
   335       }
       
   336 
       
   337       // check version
       
   338       if (header._version != CURRENT_CDS_ARCHIVE_VERSION) {
       
   339         print_debug("%s has wrong shared archive file version %d, expecting %d\n",
       
   340                      classes_jsa, header._version, CURRENT_CDS_ARCHIVE_VERSION);
       
   341         close(fd);
       
   342         return false;
       
   343       }
       
   344 
       
   345       ph->core->classes_jsa_fd = fd;
       
   346       // add read-only maps from classes.jsa to the list of maps
       
   347       for (m = 0; m < NUM_CDS_REGIONS; m++) {
       
   348         if (header._space[m]._read_only) {
       
   349           base = (uintptr_t) header._space[m]._addr._base;
       
   350           // no need to worry about the fractional pages at-the-end.
       
   351           // possible fractional pages are handled by core_read_data.
       
   352           add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
       
   353                                    base, (size_t) header._space[m]._used);
       
   354           print_debug("added a share archive map at 0x%lx\n", base);
       
   355         }
       
   356       }
       
   357       return true;
       
   358    }
       
   359    lib = lib->next;
       
   360   }
       
   361   return true;
       
   362 }
       
   363 
    41 
   364 
    42 
   365 //---------------------------------------------------------------------------
    43 //---------------------------------------------------------------------------
   366 // functions to handle map_info
    44 // functions to handle map_info
   367 
    45 
   837 
   515 
   838 #define FIRST_LINK_MAP_OFFSET offsetof(struct r_debug,  r_map)
   516 #define FIRST_LINK_MAP_OFFSET offsetof(struct r_debug,  r_map)
   839 #define LD_BASE_OFFSET        offsetof(struct r_debug,  r_ldbase)
   517 #define LD_BASE_OFFSET        offsetof(struct r_debug,  r_ldbase)
   840 #define LINK_MAP_ADDR_OFFSET  offsetof(struct link_map, l_addr)
   518 #define LINK_MAP_ADDR_OFFSET  offsetof(struct link_map, l_addr)
   841 #define LINK_MAP_NAME_OFFSET  offsetof(struct link_map, l_name)
   519 #define LINK_MAP_NAME_OFFSET  offsetof(struct link_map, l_name)
       
   520 #define LINK_MAP_LD_OFFSET    offsetof(struct link_map, l_ld)
   842 #define LINK_MAP_NEXT_OFFSET  offsetof(struct link_map, l_next)
   521 #define LINK_MAP_NEXT_OFFSET  offsetof(struct link_map, l_next)
       
   522 
       
   523 // Calculate the load address of shared library
       
   524 // on prelink-enabled environment.
       
   525 //
       
   526 // In case of GDB, it would be calculated by offset of link_map.l_ld
       
   527 // and the address of .dynamic section.
       
   528 // See GDB implementation: lm_addr_check @ solib-svr4.c
       
   529 static uintptr_t calc_prelinked_load_address(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* elf_ehdr, uintptr_t link_map_addr) {
       
   530   ELF_PHDR *phbuf;
       
   531   uintptr_t lib_ld;
       
   532   uintptr_t lib_dyn_addr = 0L;
       
   533   uintptr_t load_addr;
       
   534   int i;
       
   535 
       
   536   phbuf = read_program_header_table(lib_fd, elf_ehdr);
       
   537   if (phbuf == NULL) {
       
   538     print_debug("can't read program header of shared object\n");
       
   539     return 0L;
       
   540   }
       
   541 
       
   542   // Get the address of .dynamic section from shared library.
       
   543   for (i = 0; i < elf_ehdr->e_phnum; i++) {
       
   544     if (phbuf[i].p_type == PT_DYNAMIC) {
       
   545       lib_dyn_addr = phbuf[i].p_vaddr;
       
   546       break;
       
   547     }
       
   548   }
       
   549 
       
   550   free(phbuf);
       
   551 
       
   552   if (ps_pdread(ph, (psaddr_t)link_map_addr + LINK_MAP_LD_OFFSET,
       
   553                &lib_ld, sizeof(uintptr_t)) != PS_OK) {
       
   554     print_debug("can't read address of dynamic section in shared object\n");
       
   555     return 0L;
       
   556   }
       
   557 
       
   558   // Return the load address which is calculated by the address of .dynamic
       
   559   // and link_map.l_ld .
       
   560   load_addr = lib_ld - lib_dyn_addr;
       
   561   print_debug("lib_ld = 0x%lx, lib_dyn_addr = 0x%lx -> lib_base_diff = 0x%lx\n", lib_ld, lib_dyn_addr, load_addr);
       
   562   return load_addr;
       
   563 }
   843 
   564 
   844 // read shared library info from runtime linker's data structures.
   565 // read shared library info from runtime linker's data structures.
   845 // This work is done by librtlb_db in Solaris
   566 // This work is done by librtlb_db in Solaris
   846 static bool read_shared_lib_info(struct ps_prochandle* ph) {
   567 static bool read_shared_lib_info(struct ps_prochandle* ph) {
   847   uintptr_t addr = ph->core->dynamic_addr;
   568   uintptr_t addr = ph->core->dynamic_addr;
   940          if (lib_fd < 0) {
   661          if (lib_fd < 0) {
   941             print_debug("can't open shared object %s\n", lib_name);
   662             print_debug("can't open shared object %s\n", lib_name);
   942             // continue with other libraries...
   663             // continue with other libraries...
   943          } else {
   664          } else {
   944             if (read_elf_header(lib_fd, &elf_ehdr)) {
   665             if (read_elf_header(lib_fd, &elf_ehdr)) {
       
   666                if (lib_base_diff == 0x0L) {
       
   667                  lib_base_diff = calc_prelinked_load_address(ph, lib_fd, &elf_ehdr, link_map_addr);
       
   668                  if (lib_base_diff == 0x0L) {
       
   669                    close(lib_fd);
       
   670                    return false;
       
   671                  }
       
   672                }
       
   673 
   945                lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr);
   674                lib_base = lib_base_diff + find_base_address(lib_fd, &elf_ehdr);
   946                print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n",
   675                print_debug("reading library %s @ 0x%lx [ 0x%lx ]\n",
   947                            lib_name, lib_base, lib_base_diff);
   676                            lib_name, lib_base, lib_base_diff);
   948                // while adding library mappings we need to use "base difference".
   677                // while adding library mappings we need to use "base difference".
   949                if (! read_lib_segments(ph, lib_fd, &elf_ehdr, lib_base_diff)) {
   678                if (! read_lib_segments(ph, lib_fd, &elf_ehdr, lib_base_diff)) {