< prev index next >

src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c

Print this page


  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include <jni.h>
  26 #include <unistd.h>
  27 #include <fcntl.h>
  28 #include <string.h>
  29 #include <stdlib.h>
  30 #include <stddef.h>
  31 #include "libproc_impl.h"

  32 
  33 #ifdef __APPLE__
  34 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
  35 #endif
  36 
  37 // This file has the libproc implementation to read core files.
  38 // For live processes, refer to ps_proc.c. Portions of this is adapted
  39 // /modelled after Solaris libproc.so (in particular Pcore.c)
  40 
  41 //----------------------------------------------------------------------
  42 // ps_prochandle cleanup helper functions
  43 
  44 // close all file descriptors
  45 static void close_files(struct ps_prochandle* ph) {
  46   lib_info* lib = NULL;
  47 
  48   // close core file descriptor
  49   if (ph->core->core_fd >= 0)
  50     close(ph->core->core_fd);
  51 


 187   while (mp) {
 188     if (addr >= mp->vaddr && addr < mp->vaddr + mp->memsz) {
 189       print_debug("located map_info at 0x%lx from class share maps\n", addr);
 190       return (mp);
 191     }
 192     mp = mp->next;
 193   }
 194 
 195   print_debug("can't locate map_info at 0x%lx\n", addr);
 196   return (NULL);
 197 }
 198 
 199 //---------------------------------------------------------------
 200 // Part of the class sharing workaround:
 201 //
 202 // With class sharing, pages are mapped from classes.jsa file.
 203 // The read-only class sharing pages are mapped as MAP_SHARED,
 204 // PROT_READ pages. These pages are not dumped into core dump.
 205 // With this workaround, these pages are read from classes.jsa.
 206 
 207 // FIXME: !HACK ALERT!
 208 // The format of sharing achive file header is needed to read shared heap
 209 // file mappings. For now, I am hard coding portion of FileMapHeader here.
 210 // Refer to filemap.hpp.
 211 
 212 // FileMapHeader describes the shared space data in the file to be
 213 // mapped.  This structure gets written to a file.  It is not a class,
 214 // so that the compilers don't add any compiler-private data to it.
 215 
 216 #define NUM_SHARED_MAPS 9
 217 
 218 // Refer to FileMapInfo::_current_version in filemap.hpp
 219 #define CURRENT_ARCHIVE_VERSION 3
 220 
 221 typedef unsigned char* address;
 222 typedef uintptr_t      uintx;
 223 typedef intptr_t       intx;
 224 
 225 
 226 struct FileMapHeader {
 227   int     _magic;                   // identify file type.
 228   int     _crc;                     // header crc checksum.
 229   int     _version;                 // (from enum, above.)
 230   size_t  _alignment;               // how shared archive should be aligned
 231   int     _obj_alignment;           // value of ObjectAlignmentInBytes
 232   address _narrow_oop_base;         // compressed oop encoding base
 233   int     _narrow_oop_shift;        // compressed oop encoding shift
 234   bool    _compact_strings;         // value of CompactStrings
 235   uintx   _max_heap_size;           // java max heap size during dumping
 236   int     _narrow_oop_mode;         // compressed oop encoding mode
 237   int     _narrow_klass_shift;      // save narrow klass base and shift
 238   address _narrow_klass_base;
 239   char*   _misc_data_patching_start;
 240   char*   _read_only_tables_start;
 241   address _cds_i2i_entry_code_buffers;
 242   size_t  _cds_i2i_entry_code_buffers_size;
 243   size_t  _core_spaces_size;        // number of bytes allocated by the core spaces
 244                                     // (mc, md, ro, rw and od).
 245 
 246 
 247   struct space_info {
 248     int     _crc;          // crc checksum of the current space
 249     size_t  _file_offset;  // sizeof(this) rounded to vm page size
 250     union {
 251       char*  _base;        // copy-on-write base address
 252       intx   _offset;      // offset from the compressed oop encoding base, only used
 253                            // by archive heap space
 254     } _addr;
 255     size_t _used;          // for setting space top on read
 256     // 4991491 NOTICE These are C++ bool's in filemap.hpp and must match up with
 257     // the C type matching the C++ bool type on any given platform.
 258     // We assume the corresponding C type is char but licensees
 259     // may need to adjust the type of these fields.
 260     char   _read_only;     // read only space?
 261     char   _allow_exec;    // executable code in space?
 262   } _space[NUM_SHARED_MAPS];
 263 
 264   // Ignore the rest of the FileMapHeader. We don't need those fields here.
 265 };
 266 
 267 static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
 268   jboolean i;
 269   if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
 270     *pvalue = i;
 271     return true;
 272   } else {
 273     return false;
 274   }
 275 }
 276 
 277 static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
 278   uintptr_t uip;
 279   if (ps_pread(ph, (psaddr_t) addr, (char *)&uip, sizeof(uip)) == PS_OK) {
 280     *pvalue = uip;
 281     return true;
 282   } else {
 283     return false;
 284   }
 285 }


 309 #define SHARED_ARCHIVE_PATH_SYM "__ZN9Arguments17SharedArchivePathE"
 310 
 311 #ifdef __APPLE__
 312 #define USE_SHARED_SPACES_SYM "_UseSharedSpaces"
 313 #define LIBJVM_NAME "/libjvm.dylib"
 314 #else
 315 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
 316 #define LIBJVM_NAME "/libjvm.so"
 317 #endif // __APPLE_
 318 
 319 static bool init_classsharing_workaround(struct ps_prochandle* ph) {
 320   int m;
 321   size_t n;
 322   lib_info* lib = ph->libs;
 323   while (lib != NULL) {
 324     // we are iterating over shared objects from the core dump. look for
 325     // libjvm.so.
 326     const char *jvm_name = 0;
 327     if ((jvm_name = strstr(lib->name, LIBJVM_NAME)) != 0) {
 328       char classes_jsa[PATH_MAX];
 329       struct FileMapHeader header;
 330       int fd = -1;
 331       uintptr_t base = 0, useSharedSpacesAddr = 0;
 332       uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
 333       jboolean useSharedSpaces = 0;
 334 
 335       memset(classes_jsa, 0, sizeof(classes_jsa));
 336       jvm_name = lib->name;
 337       useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
 338       if (useSharedSpacesAddr == 0) {
 339         print_debug("can't lookup 'UseSharedSpaces' flag\n");
 340         return false;
 341       }
 342 
 343       // Hotspot vm types are not exported to build this library. So
 344       // using equivalent type jboolean to read the value of
 345       // UseSharedSpaces which is same as hotspot type "bool".
 346       if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
 347         print_debug("can't read the value of 'UseSharedSpaces' flag\n");
 348         return false;
 349       }


 364         return false;
 365       }
 366 
 367       if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
 368         print_debug("can't read shared archive path value\n");
 369         return false;
 370       }
 371 
 372       print_debug("looking for %s\n", classes_jsa);
 373       // open the class sharing archive file
 374       fd = pathmap_open(classes_jsa);
 375       if (fd < 0) {
 376         print_debug("can't open %s!\n", classes_jsa);
 377         ph->core->classes_jsa_fd = -1;
 378         return false;
 379       } else {
 380         print_debug("opened %s\n", classes_jsa);
 381       }
 382 
 383       // read FileMapHeader from the file
 384       memset(&header, 0, sizeof(struct FileMapHeader));
 385       if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
 386            != sizeof(struct FileMapHeader)) {
 387         print_debug("can't read shared archive file map header from %s\n", classes_jsa);
 388         close(fd);
 389         return false;
 390       }
 391 
 392       // check file magic
 393       if (header._magic != 0xf00baba2) {
 394         print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
 395                      classes_jsa, header._magic);
 396         close(fd);
 397         return false;
 398       }
 399 
 400       // check version
 401       if (header._version != CURRENT_ARCHIVE_VERSION) {
 402         print_debug("%s has wrong shared archive file version %d, expecting %d\n",
 403                      classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
 404         close(fd);
 405         return false;
 406       }
 407 
 408       ph->core->classes_jsa_fd = fd;
 409       // add read-only maps from classes.jsa to the list of maps
 410       for (m = 0; m < NUM_SHARED_MAPS; m++) {
 411         if (header._space[m]._read_only) {
 412           base = (uintptr_t) header._space[m]._addr._base;
 413           // no need to worry about the fractional pages at-the-end.
 414           // possible fractional pages are handled by core_read_data.
 415           add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
 416                                    base, (size_t) header._space[m]._used);
 417           print_debug("added a share archive map at 0x%lx\n", base);
 418         }
 419       }
 420       return true;
 421    }
 422    lib = lib->next;
 423   }
 424   return true;
 425 }
 426 
 427 //---------------------------------------------------------------------------
 428 // functions to handle map_info
 429 
 430 // Order mappings based on virtual address.  We use this function as the




  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include <jni.h>
  26 #include <unistd.h>
  27 #include <fcntl.h>
  28 #include <string.h>
  29 #include <stdlib.h>
  30 #include <stddef.h>
  31 #include "libproc_impl.h"
  32 #include "../../../../hotspot/share/include/cds.h"
  33 
  34 #ifdef __APPLE__
  35 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
  36 #endif
  37 
  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
  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 


 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 typedef struct CDSFileMapHeaderBase FileMapHeader;


























































 209 
 210 static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
 211   jboolean i;
 212   if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
 213     *pvalue = i;
 214     return true;
 215   } else {
 216     return false;
 217   }
 218 }
 219 
 220 static bool read_pointer(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* pvalue) {
 221   uintptr_t uip;
 222   if (ps_pread(ph, (psaddr_t) addr, (char *)&uip, sizeof(uip)) == PS_OK) {
 223     *pvalue = uip;
 224     return true;
 225   } else {
 226     return false;
 227   }
 228 }


 252 #define SHARED_ARCHIVE_PATH_SYM "__ZN9Arguments17SharedArchivePathE"
 253 
 254 #ifdef __APPLE__
 255 #define USE_SHARED_SPACES_SYM "_UseSharedSpaces"
 256 #define LIBJVM_NAME "/libjvm.dylib"
 257 #else
 258 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
 259 #define LIBJVM_NAME "/libjvm.so"
 260 #endif // __APPLE_
 261 
 262 static bool init_classsharing_workaround(struct ps_prochandle* ph) {
 263   int m;
 264   size_t n;
 265   lib_info* lib = ph->libs;
 266   while (lib != NULL) {
 267     // we are iterating over shared objects from the core dump. look for
 268     // libjvm.so.
 269     const char *jvm_name = 0;
 270     if ((jvm_name = strstr(lib->name, LIBJVM_NAME)) != 0) {
 271       char classes_jsa[PATH_MAX];
 272       FileMapHeader header;
 273       int fd = -1;
 274       uintptr_t base = 0, useSharedSpacesAddr = 0;
 275       uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
 276       jboolean useSharedSpaces = 0;
 277 
 278       memset(classes_jsa, 0, sizeof(classes_jsa));
 279       jvm_name = lib->name;
 280       useSharedSpacesAddr = lookup_symbol(ph, jvm_name, USE_SHARED_SPACES_SYM);
 281       if (useSharedSpacesAddr == 0) {
 282         print_debug("can't lookup 'UseSharedSpaces' flag\n");
 283         return false;
 284       }
 285 
 286       // Hotspot vm types are not exported to build this library. So
 287       // using equivalent type jboolean to read the value of
 288       // UseSharedSpaces which is same as hotspot type "bool".
 289       if (read_jboolean(ph, useSharedSpacesAddr, &useSharedSpaces) != true) {
 290         print_debug("can't read the value of 'UseSharedSpaces' flag\n");
 291         return false;
 292       }


 307         return false;
 308       }
 309 
 310       if (read_string(ph, sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
 311         print_debug("can't read shared archive path value\n");
 312         return false;
 313       }
 314 
 315       print_debug("looking for %s\n", classes_jsa);
 316       // open the class sharing archive file
 317       fd = pathmap_open(classes_jsa);
 318       if (fd < 0) {
 319         print_debug("can't open %s!\n", classes_jsa);
 320         ph->core->classes_jsa_fd = -1;
 321         return false;
 322       } else {
 323         print_debug("opened %s\n", classes_jsa);
 324       }
 325 
 326       // read FileMapHeader from the file
 327       memset(&header, 0, sizeof(FileMapHeader));
 328       if ((n = read(fd, &header, sizeof(FileMapHeader)))
 329            != sizeof(FileMapHeader)) {
 330         print_debug("can't read shared archive file map header from %s\n", classes_jsa);
 331         close(fd);
 332         return false;
 333       }
 334 
 335       // check file magic
 336       if (header._magic != CDS_ARCHIVE_MAGIC) {
 337         print_debug("%s has bad shared archive file magic number 0x%x, expecing 0x%x\n",
 338                     classes_jsa, header._magic, CDS_ARCHIVE_MAGIC);
 339         close(fd);
 340         return false;
 341       }
 342 
 343       // check version
 344       if (header._version != CURRENT_CDS_ARCHIVE_VERSION) {
 345         print_debug("%s has wrong shared archive file version %d, expecting %d\n",
 346                      classes_jsa, header._version, CURRENT_CDS_ARCHIVE_VERSION);
 347         close(fd);
 348         return false;
 349       }
 350 
 351       ph->core->classes_jsa_fd = fd;
 352       // add read-only maps from classes.jsa to the list of maps
 353       for (m = 0; m < NUM_CDS_REGIONS; m++) {
 354         if (header._space[m]._read_only) {
 355           base = (uintptr_t) header._space[m]._addr._base;
 356           // no need to worry about the fractional pages at-the-end.
 357           // possible fractional pages are handled by core_read_data.
 358           add_class_share_map_info(ph, (off_t) header._space[m]._file_offset,
 359                                    base, (size_t) header._space[m]._used);
 360           print_debug("added a share archive map at 0x%lx\n", base);
 361         }
 362       }
 363       return true;
 364    }
 365    lib = lib->next;
 366   }
 367   return true;
 368 }
 369 
 370 //---------------------------------------------------------------------------
 371 // functions to handle map_info
 372 
 373 // Order mappings based on virtual address.  We use this function as the


< prev index next >