< prev index next >

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

Print this page




 334     *     entry that has integer regset for that LWP.
 335     *
 336     *     Linux threads are actually 'clone'd processes. To support core analysis
 337     *     of "multithreaded" process, Linux creates more than one pstatus (called
 338     *     "prstatus") entry in PT_NOTE. Each prstatus entry has integer regset for one
 339     *     "thread". Please refer to Linux kernel src file 'fs/binfmt_elf.c', in particular
 340     *     function "elf_core_dump".
 341     */
 342 
 343     for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
 344       switch (core_php->p_type) {
 345          case PT_NOTE:
 346             if (core_handle_note(ph, core_php) != true) {
 347               goto err;
 348             }
 349             break;
 350 
 351          case PT_LOAD: {
 352             if (core_php->p_filesz != 0) {
 353                if (add_map_info(ph, ph->core->core_fd, core_php->p_offset,
 354                   core_php->p_vaddr, core_php->p_filesz) == NULL) goto err;
 355             }
 356             break;
 357          }
 358       }
 359 
 360       core_php++;
 361    }
 362 
 363    free(phbuf);
 364    return true;
 365 err:
 366    free(phbuf);
 367    return false;
 368 }
 369 
 370 // read segments of a shared object
 371 static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
 372   int i = 0;
 373   ELF_PHDR* phbuf;
 374   ELF_PHDR* lib_php = NULL;
 375 
 376   int page_size = sysconf(_SC_PAGE_SIZE);
 377 
 378   if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) {
 379     return false;
 380   }
 381 
 382   // we want to process only PT_LOAD segments that are not writable.
 383   // i.e., text segments. The read/write/exec (data) segments would
 384   // have been already added from core file segments.
 385   for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
 386     if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
 387 
 388       uintptr_t target_vaddr = lib_php->p_vaddr + lib_base;
 389       map_info *existing_map = core_lookup(ph, target_vaddr);
 390 
 391       if (existing_map == NULL){
 392         if (add_map_info(ph, lib_fd, lib_php->p_offset,
 393                           target_vaddr, lib_php->p_memsz) == NULL) {
 394           goto err;
 395         }





 396       } else {






 397         // Coredump stores value of p_memsz elf field
 398         // rounded up to page boundary.
 399 
 400         if ((existing_map->memsz != page_size) &&
 401             (existing_map->fd != lib_fd) &&
 402             (ROUNDUP(existing_map->memsz, page_size) != ROUNDUP(lib_php->p_memsz, page_size))) {
 403 
 404           print_debug("address conflict @ 0x%lx (existing map size = %ld, size = %ld, flags = %d)\n",
 405                         target_vaddr, existing_map->memsz, lib_php->p_memsz, lib_php->p_flags);
 406           goto err;
 407         }
 408 
 409         /* replace PT_LOAD segment with library segment */
 410         print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n",
 411                      existing_map->memsz, ROUNDUP(lib_php->p_memsz, page_size));
 412 
 413         existing_map->fd = lib_fd;
 414         existing_map->offset = lib_php->p_offset;
 415         existing_map->memsz = ROUNDUP(lib_php->p_memsz, page_size);
 416       }


 443   return true;
 444 }
 445 
 446 // process segments of a a.out
 447 static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
 448   int i = 0;
 449   ELF_PHDR* phbuf = NULL;
 450   ELF_PHDR* exec_php = NULL;
 451 
 452   if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL) {
 453     return false;
 454   }
 455 
 456   for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
 457     switch (exec_php->p_type) {
 458 
 459       // add mappings for PT_LOAD segments
 460     case PT_LOAD: {
 461       // add only non-writable segments of non-zero filesz
 462       if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
 463         if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz) == NULL) goto err;
 464       }
 465       break;
 466     }
 467 
 468     // read the interpreter and it's segments
 469     case PT_INTERP: {
 470       char interp_name[BUF_SIZE + 1];
 471 
 472       // BUF_SIZE is PATH_MAX + NAME_MAX + 1.
 473       if (exec_php->p_filesz > BUF_SIZE) {
 474         goto err;
 475       }
 476       if (pread(ph->core->exec_fd, interp_name,
 477                 exec_php->p_filesz, exec_php->p_offset) != exec_php->p_filesz) {
 478         print_debug("Unable to read in the ELF interpreter\n");
 479         goto err;
 480       }
 481       interp_name[exec_php->p_filesz] = '\0';
 482       print_debug("ELF interpreter %s\n", interp_name);
 483       // read interpreter segments as well




 334     *     entry that has integer regset for that LWP.
 335     *
 336     *     Linux threads are actually 'clone'd processes. To support core analysis
 337     *     of "multithreaded" process, Linux creates more than one pstatus (called
 338     *     "prstatus") entry in PT_NOTE. Each prstatus entry has integer regset for one
 339     *     "thread". Please refer to Linux kernel src file 'fs/binfmt_elf.c', in particular
 340     *     function "elf_core_dump".
 341     */
 342 
 343     for (core_php = phbuf, i = 0; i < core_ehdr->e_phnum; i++) {
 344       switch (core_php->p_type) {
 345          case PT_NOTE:
 346             if (core_handle_note(ph, core_php) != true) {
 347               goto err;
 348             }
 349             break;
 350 
 351          case PT_LOAD: {
 352             if (core_php->p_filesz != 0) {
 353                if (add_map_info(ph, ph->core->core_fd, core_php->p_offset,
 354                   core_php->p_vaddr, core_php->p_filesz, core_php->p_flags) == NULL) goto err;
 355             }
 356             break;
 357          }
 358       }
 359 
 360       core_php++;
 361    }
 362 
 363    free(phbuf);
 364    return true;
 365 err:
 366    free(phbuf);
 367    return false;
 368 }
 369 
 370 // read segments of a shared object
 371 static bool read_lib_segments(struct ps_prochandle* ph, int lib_fd, ELF_EHDR* lib_ehdr, uintptr_t lib_base) {
 372   int i = 0;
 373   ELF_PHDR* phbuf;
 374   ELF_PHDR* lib_php = NULL;
 375 
 376   int page_size = sysconf(_SC_PAGE_SIZE);
 377 
 378   if ((phbuf = read_program_header_table(lib_fd, lib_ehdr)) == NULL) {
 379     return false;
 380   }
 381 
 382   // we want to process only PT_LOAD segments that are not writable.
 383   // i.e., text segments. The read/write/exec (data) segments would
 384   // have been already added from core file segments.
 385   for (lib_php = phbuf, i = 0; i < lib_ehdr->e_phnum; i++) {
 386     if ((lib_php->p_type == PT_LOAD) && !(lib_php->p_flags & PF_W) && (lib_php->p_filesz != 0)) {
 387 
 388       uintptr_t target_vaddr = lib_php->p_vaddr + lib_base;
 389       map_info *existing_map = core_lookup(ph, target_vaddr);
 390 
 391       if (existing_map == NULL){
 392         if (add_map_info(ph, lib_fd, lib_php->p_offset,
 393                          target_vaddr, lib_php->p_memsz, lib_php->p_flags) == NULL) {
 394           goto err;
 395         }
 396       } else if (lib_php->p_flags != existing_map->flags) {
 397         // Access flags for this memory region are different between the library
 398         // and coredump. It might be caused by mprotect() call at runtime.
 399         // We should respect the coredump.
 400         continue;
 401       } else {
 402         // Read only segments in ELF should not be any different from PT_LOAD segments
 403         // in the coredump.
 404         // Also the first page of the ELF header might be included
 405         // in the coredump (See JDK-7133122).
 406         // Thus we need to replace the PT_LOAD segment with the library version.
 407         //
 408         // Coredump stores value of p_memsz elf field
 409         // rounded up to page boundary.
 410 
 411         if ((existing_map->memsz != page_size) &&
 412             (existing_map->fd != lib_fd) &&
 413             (ROUNDUP(existing_map->memsz, page_size) != ROUNDUP(lib_php->p_memsz, page_size))) {
 414 
 415           print_debug("address conflict @ 0x%lx (existing map size = %ld, size = %ld, flags = %d)\n",
 416                         target_vaddr, existing_map->memsz, lib_php->p_memsz, lib_php->p_flags);
 417           goto err;
 418         }
 419 
 420         /* replace PT_LOAD segment with library segment */
 421         print_debug("overwrote with new address mapping (memsz %ld -> %ld)\n",
 422                      existing_map->memsz, ROUNDUP(lib_php->p_memsz, page_size));
 423 
 424         existing_map->fd = lib_fd;
 425         existing_map->offset = lib_php->p_offset;
 426         existing_map->memsz = ROUNDUP(lib_php->p_memsz, page_size);
 427       }


 454   return true;
 455 }
 456 
 457 // process segments of a a.out
 458 static bool read_exec_segments(struct ps_prochandle* ph, ELF_EHDR* exec_ehdr) {
 459   int i = 0;
 460   ELF_PHDR* phbuf = NULL;
 461   ELF_PHDR* exec_php = NULL;
 462 
 463   if ((phbuf = read_program_header_table(ph->core->exec_fd, exec_ehdr)) == NULL) {
 464     return false;
 465   }
 466 
 467   for (exec_php = phbuf, i = 0; i < exec_ehdr->e_phnum; i++) {
 468     switch (exec_php->p_type) {
 469 
 470       // add mappings for PT_LOAD segments
 471     case PT_LOAD: {
 472       // add only non-writable segments of non-zero filesz
 473       if (!(exec_php->p_flags & PF_W) && exec_php->p_filesz != 0) {
 474         if (add_map_info(ph, ph->core->exec_fd, exec_php->p_offset, exec_php->p_vaddr, exec_php->p_filesz, exec_php->p_flags) == NULL) goto err;
 475       }
 476       break;
 477     }
 478 
 479     // read the interpreter and it's segments
 480     case PT_INTERP: {
 481       char interp_name[BUF_SIZE + 1];
 482 
 483       // BUF_SIZE is PATH_MAX + NAME_MAX + 1.
 484       if (exec_php->p_filesz > BUF_SIZE) {
 485         goto err;
 486       }
 487       if (pread(ph->core->exec_fd, interp_name,
 488                 exec_php->p_filesz, exec_php->p_offset) != exec_php->p_filesz) {
 489         print_debug("Unable to read in the ELF interpreter\n");
 490         goto err;
 491       }
 492       interp_name[exec_php->p_filesz] = '\0';
 493       print_debug("ELF interpreter %s\n", interp_name);
 494       // read interpreter segments as well


< prev index next >