< prev index next >

src/jdk.hotspot.agent/solaris/native/libsaproc/saproc.cpp

Print this page


 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);


< prev index next >