521 size_t i = 0;
522
523 while (ch != '\0') {
524 if (ps_pread(ph, addr, &ch, sizeof(ch)) != PS_OK)
525 return false;
526
527 if (i < size - 1) {
528 buf[i] = ch;
529 } else { // smaller buffer
530 return false;
531 }
532
533 i++; addr++;
534 }
535
536 buf[i] = '\0';
537 return true;
538 }
539
540 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
541 // mangled symbol name for Arguments::SharedArchivePath
542 #define SHARED_ARCHIVE_PATH_SYM "__1cJArgumentsRSharedArchivePath_"
543
544 static int
545 init_classsharing_workaround(void *cd, const prmap_t* pmap, const char* obj_name) {
546 Debugger* dbg = (Debugger*) cd;
547 JNIEnv* env = dbg->env;
548 jobject this_obj = dbg->this_obj;
549 const char* jvm_name = 0;
550 if ((jvm_name = strstr(obj_name, "libjvm.so")) != NULL) {
551 jvm_name = obj_name;
552 } else {
553 return 0;
554 }
555
556 struct ps_prochandle* ph = (struct ps_prochandle*) env->GetLongField(this_obj, p_ps_prochandle_ID);
557
558 // initialize classes.jsa file descriptor field.
559 dbg->env->SetIntField(this_obj, classes_jsa_fd_ID, -1);
560
561 // check whether class sharing is on by reading variable "UseSharedSpaces"
562 psaddr_t useSharedSpacesAddr = 0;
563 ps_pglobal_lookup(ph, jvm_name, USE_SHARED_SPACES_SYM, &useSharedSpacesAddr);
564 if (useSharedSpacesAddr == 0) {
565 THROW_NEW_DEBUGGER_EXCEPTION_("can't find 'UseSharedSpaces' flag\n", 1);
566 }
567
568 // read the value of the flag "UseSharedSpaces"
569 // Since hotspot types are not available to build this library. So
570 // equivalent type "jboolean" is used to read the value of "UseSharedSpaces"
571 // which is same as hotspot type "bool".
572 jboolean value = 0;
573 if (read_jboolean(ph, useSharedSpacesAddr, &value) != true) {
574 THROW_NEW_DEBUGGER_EXCEPTION_("can't read 'UseSharedSpaces' flag", 1);
575 } else if ((int)value == 0) {
576 print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
577 return 1;
578 }
579
580 char classes_jsa[PATH_MAX];
581 psaddr_t sharedArchivePathAddrAddr = 0;
582 ps_pglobal_lookup(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM, &sharedArchivePathAddrAddr);
583 if (sharedArchivePathAddrAddr == 0) {
584 print_debug("can't find symbol 'Arguments::SharedArchivePath'\n");
585 THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
586 }
587
588 uintptr_t sharedArchivePathAddr = 0;
589 if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
590 print_debug("can't find read pointer 'Arguments::SharedArchivePath'\n");
591 THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
592 }
593
594 if (read_string(ph, (psaddr_t)sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
595 print_debug("can't find read 'Arguments::SharedArchivePath' value\n");
596 THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
597 }
598
599 print_debug("looking for %s\n", classes_jsa);
631 char errMsg[ERR_MSG_SIZE];
632 sprintf(errMsg, "%s has bad shared archive magic 0x%x, expecting 0x%x",
633 classes_jsa, pheader->_magic, CDS_ARCHIVE_MAGIC);
634 close(fd);
635 free(pheader);
636 THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
637 }
638
639 // check version
640 if (pheader->_version != CURRENT_CDS_ARCHIVE_VERSION) {
641 char errMsg[ERR_MSG_SIZE];
642 sprintf(errMsg, "%s has wrong shared archive version %d, expecting %d",
643 classes_jsa, pheader->_version, CURRENT_CDS_ARCHIVE_VERSION);
644 close(fd);
645 free(pheader);
646 THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
647 }
648
649 if (_libsaproc_debug) {
650 for (int m = 0; m < NUM_CDS_REGIONS; m++) {
651 print_debug("shared file offset %d mapped at 0x%lx, size = %ld, read only? = %d\n",
652 pheader->_space[m]._file_offset, pheader->_space[m]._addr._base,
653 pheader->_space[m]._used, pheader->_space[m]._read_only);
654 }
655 }
656
657 // FIXME: For now, omitting other checks such as VM version etc.
658
659 // store class archive file fd and map header in debugger object fields
660 dbg->env->SetIntField(this_obj, classes_jsa_fd_ID, fd);
661 dbg->env->SetLongField(this_obj, p_file_map_header_ID, (jlong)(uintptr_t) pheader);
662 return 1;
663 }
664
665 } // extern "C"
666
667 // error messages for proc_arg_grab failure codes. The messages are
668 // modified versions of comments against corresponding #defines in
669 // libproc.h.
670 static const char* proc_arg_grab_errmsgs[] = {
671 "",
672 /* G_NOPROC */ "No such process",
1036
1037 jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
1038 ps_err_e ret = ps_pread((struct ps_prochandle*) p_ps_prochandle,
1039 (psaddr_t)address, bufPtr, (size_t)numBytes);
1040
1041 if (ret != PS_OK) {
1042 // part of the class sharing workaround. try shared heap area
1043 int classes_jsa_fd = env->GetIntField(this_obj, classes_jsa_fd_ID);
1044 if (classes_jsa_fd != -1 && address != (jlong)0) {
1045 print_debug("read failed at 0x%lx, attempting shared heap area\n", (long) address);
1046
1047 CDSFileMapHeaderBase* pheader = (CDSFileMapHeaderBase*) env->GetLongField(this_obj, p_file_map_header_ID);
1048 // walk through the shared mappings -- we just have 9 of them.
1049 // so, linear walking is okay.
1050 for (int m = 0; m < NUM_CDS_REGIONS; m++) {
1051
1052 // We can skip the non-read-only maps. These are mapped as MAP_PRIVATE
1053 // and hence will be read by libproc. Besides, the file copy may be
1054 // stale because the process might have modified those pages.
1055 if (pheader->_space[m]._read_only) {
1056 jlong baseAddress = (jlong) (uintptr_t) pheader->_space[m]._addr._base;
1057 size_t usedSize = pheader->_space[m]._used;
1058 if (address >= baseAddress && address < (baseAddress + usedSize)) {
1059 // the given address falls in this shared heap area
1060 print_debug("found shared map at 0x%lx\n", (long) baseAddress);
1061
1062
1063 // If more data is asked than actually mapped from file, we need to zero fill
1064 // till the end-of-page boundary. But, java array new does that for us. we just
1065 // need to read as much as data available.
1066
1067 #define MIN2(x, y) (((x) < (y))? (x) : (y))
1068
1069 jlong diff = address - baseAddress;
1070 jlong bytesToRead = MIN2(numBytes, usedSize - diff);
1071 off_t offset = pheader->_space[m]._file_offset + off_t(diff);
1072 ssize_t bytesRead = pread(classes_jsa_fd, bufPtr, bytesToRead, offset);
1073 if (bytesRead != bytesToRead) {
1074 env->ReleaseByteArrayElements(array, bufPtr, JNI_ABORT);
1075 print_debug("shared map read failed\n");
1076 return jbyteArray(0);
1077 } else {
1078 print_debug("shared map read succeeded\n");
1079 env->ReleaseByteArrayElements(array, bufPtr, 0);
|
521 size_t i = 0;
522
523 while (ch != '\0') {
524 if (ps_pread(ph, addr, &ch, sizeof(ch)) != PS_OK)
525 return false;
526
527 if (i < size - 1) {
528 buf[i] = ch;
529 } else { // smaller buffer
530 return false;
531 }
532
533 i++; addr++;
534 }
535
536 buf[i] = '\0';
537 return true;
538 }
539
540 #define USE_SHARED_SPACES_SYM "UseSharedSpaces"
541 #define SHARED_BASE_ADDRESS_SYM "SharedBaseAddress"
542 // mangled symbol name for Arguments::SharedArchivePath
543 #define SHARED_ARCHIVE_PATH_SYM "__1cJArgumentsRSharedArchivePath_"
544
545 static uintptr_t sharedBaseAddress = 0;
546 static int
547 init_classsharing_workaround(void *cd, const prmap_t* pmap, const char* obj_name) {
548 Debugger* dbg = (Debugger*) cd;
549 JNIEnv* env = dbg->env;
550 jobject this_obj = dbg->this_obj;
551 const char* jvm_name = 0;
552 if ((jvm_name = strstr(obj_name, "libjvm.so")) != NULL) {
553 jvm_name = obj_name;
554 } else {
555 return 0;
556 }
557
558 struct ps_prochandle* ph = (struct ps_prochandle*) env->GetLongField(this_obj, p_ps_prochandle_ID);
559
560 // initialize classes.jsa file descriptor field.
561 dbg->env->SetIntField(this_obj, classes_jsa_fd_ID, -1);
562
563 // check whether class sharing is on by reading variable "UseSharedSpaces"
564 psaddr_t useSharedSpacesAddr = 0;
565 ps_pglobal_lookup(ph, jvm_name, USE_SHARED_SPACES_SYM, &useSharedSpacesAddr);
566 if (useSharedSpacesAddr == 0) {
567 THROW_NEW_DEBUGGER_EXCEPTION_("can't find 'UseSharedSpaces' flag\n", 1);
568 }
569
570 // read the value of the flag "UseSharedSpaces"
571 // Since hotspot types are not available to build this library. So
572 // equivalent type "jboolean" is used to read the value of "UseSharedSpaces"
573 // which is same as hotspot type "bool".
574 jboolean value = 0;
575 if (read_jboolean(ph, useSharedSpacesAddr, &value) != true) {
576 THROW_NEW_DEBUGGER_EXCEPTION_("can't read 'UseSharedSpaces' flag", 1);
577 } else if ((int)value == 0) {
578 print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
579 return 1;
580 }
581
582 psaddr_t sharedBaseAddressAddr = 0;
583 ps_pglobal_lookup(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM, &sharedBaseAddressAddr);
584 if (sharedBaseAddressAddr == 0) {
585 print_debug("can't find symbol 'SharedBaseAddress'\n");
586 THROW_NEW_DEBUGGER_EXCEPTION_("can't find 'SharedBaseAddress' flag\n", 1);
587 }
588
589 sharedBaseAddress = 0;
590 if (read_pointer(ph, sharedBaseAddressAddr, &sharedBaseAddress) != true) {
591 print_debug("can't read the value of 'SharedBaseAddress' flag\n");
592 THROW_NEW_DEBUGGER_EXCEPTION_("can't get SharedBaseAddress from debuggee", 1);
593 }
594
595 char classes_jsa[PATH_MAX];
596 psaddr_t sharedArchivePathAddrAddr = 0;
597 ps_pglobal_lookup(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM, &sharedArchivePathAddrAddr);
598 if (sharedArchivePathAddrAddr == 0) {
599 print_debug("can't find symbol 'Arguments::SharedArchivePath'\n");
600 THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
601 }
602
603 uintptr_t sharedArchivePathAddr = 0;
604 if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
605 print_debug("can't find read pointer 'Arguments::SharedArchivePath'\n");
606 THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
607 }
608
609 if (read_string(ph, (psaddr_t)sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
610 print_debug("can't find read 'Arguments::SharedArchivePath' value\n");
611 THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
612 }
613
614 print_debug("looking for %s\n", classes_jsa);
646 char errMsg[ERR_MSG_SIZE];
647 sprintf(errMsg, "%s has bad shared archive magic 0x%x, expecting 0x%x",
648 classes_jsa, pheader->_magic, CDS_ARCHIVE_MAGIC);
649 close(fd);
650 free(pheader);
651 THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
652 }
653
654 // check version
655 if (pheader->_version != CURRENT_CDS_ARCHIVE_VERSION) {
656 char errMsg[ERR_MSG_SIZE];
657 sprintf(errMsg, "%s has wrong shared archive version %d, expecting %d",
658 classes_jsa, pheader->_version, CURRENT_CDS_ARCHIVE_VERSION);
659 close(fd);
660 free(pheader);
661 THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
662 }
663
664 if (_libsaproc_debug) {
665 for (int m = 0; m < NUM_CDS_REGIONS; m++) {
666 jlong mapping_offset = pheader->_space[m]._mapping_offset;
667 jlong baseAddress = (mapping_offset == 0) ? 0 : (mapping_offset + (jlong)sharedBaseAddress);
668 print_debug("shared file offset %d mapped at 0x%lx, size = %ld, read only? = %d\n",
669 pheader->_space[m]._file_offset, baseAddress,
670 pheader->_space[m]._used, pheader->_space[m]._read_only);
671 }
672 }
673
674 // FIXME: For now, omitting other checks such as VM version etc.
675
676 // store class archive file fd and map header in debugger object fields
677 dbg->env->SetIntField(this_obj, classes_jsa_fd_ID, fd);
678 dbg->env->SetLongField(this_obj, p_file_map_header_ID, (jlong)(uintptr_t) pheader);
679 return 1;
680 }
681
682 } // extern "C"
683
684 // error messages for proc_arg_grab failure codes. The messages are
685 // modified versions of comments against corresponding #defines in
686 // libproc.h.
687 static const char* proc_arg_grab_errmsgs[] = {
688 "",
689 /* G_NOPROC */ "No such process",
1053
1054 jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
1055 ps_err_e ret = ps_pread((struct ps_prochandle*) p_ps_prochandle,
1056 (psaddr_t)address, bufPtr, (size_t)numBytes);
1057
1058 if (ret != PS_OK) {
1059 // part of the class sharing workaround. try shared heap area
1060 int classes_jsa_fd = env->GetIntField(this_obj, classes_jsa_fd_ID);
1061 if (classes_jsa_fd != -1 && address != (jlong)0) {
1062 print_debug("read failed at 0x%lx, attempting shared heap area\n", (long) address);
1063
1064 CDSFileMapHeaderBase* pheader = (CDSFileMapHeaderBase*) env->GetLongField(this_obj, p_file_map_header_ID);
1065 // walk through the shared mappings -- we just have 9 of them.
1066 // so, linear walking is okay.
1067 for (int m = 0; m < NUM_CDS_REGIONS; m++) {
1068
1069 // We can skip the non-read-only maps. These are mapped as MAP_PRIVATE
1070 // and hence will be read by libproc. Besides, the file copy may be
1071 // stale because the process might have modified those pages.
1072 if (pheader->_space[m]._read_only) {
1073 jlong mapping_offset = (jlong) (uintptr_t) pheader->_space[m]._mapping_offset;
1074 jlong baseAddress = mapping_offset + (jlong)sharedBaseAddress;
1075 size_t usedSize = pheader->_space[m]._used;
1076 if (mapping_offset != 0 && address >= baseAddress && address < (baseAddress + usedSize)) {
1077 // the given address falls in this shared metadata area
1078 print_debug("found shared map at 0x%lx\n", (long) baseAddress);
1079
1080
1081 // If more data is asked than actually mapped from file, we need to zero fill
1082 // till the end-of-page boundary. But, java array new does that for us. we just
1083 // need to read as much as data available.
1084
1085 #define MIN2(x, y) (((x) < (y))? (x) : (y))
1086
1087 jlong diff = address - baseAddress;
1088 jlong bytesToRead = MIN2(numBytes, usedSize - diff);
1089 off_t offset = pheader->_space[m]._file_offset + off_t(diff);
1090 ssize_t bytesRead = pread(classes_jsa_fd, bufPtr, bytesToRead, offset);
1091 if (bytesRead != bytesToRead) {
1092 env->ReleaseByteArrayElements(array, bufPtr, JNI_ABORT);
1093 print_debug("shared map read failed\n");
1094 return jbyteArray(0);
1095 } else {
1096 print_debug("shared map read succeeded\n");
1097 env->ReleaseByteArrayElements(array, bufPtr, 0);
|