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 "salibproc.h"
26 #include "sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal.h"
27 #include <thread_db.h>
28 #include <strings.h>
29 #include <limits.h>
30 #include <demangle.h>
31 #include <stdarg.h>
32 #include <stdlib.h>
33 #include <errno.h>
34
35 #define CHECK_EXCEPTION_(value) if(env->ExceptionOccurred()) { return value; }
36 #define CHECK_EXCEPTION if(env->ExceptionOccurred()) { return;}
37 #define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throwNewDebuggerException(env, str); return value; }
38 #define THROW_NEW_DEBUGGER_EXCEPTION(str) { throwNewDebuggerException(env, str); return;}
39
40 #define SYMBOL_BUF_SIZE 256
41 #define ERR_MSG_SIZE (PATH_MAX + 256)
42
43 // debug modes
44 static int _libsaproc_debug = 0;
45
46 static void print_debug(const char* format,...) {
47 if (_libsaproc_debug) {
48 va_list alist;
49
50 va_start(alist, format);
51 fputs("libsaproc DEBUG: ", stderr);
52 vfprintf(stderr, format, alist);
53 va_end(alist);
54 }
55 }
56
57 struct Debugger {
58 JNIEnv* env;
59 jobject this_obj;
60 };
61
62 struct DebuggerWithObject : Debugger {
63 jobject obj;
64 };
65
66 struct DebuggerWith2Objects : DebuggerWithObject {
67 jobject obj2;
68 };
69
70 /*
71 * Portions of user thread level detail gathering code is from pstack source
72 * code. See pstack.c in Solaris 2.8 user commands source code.
73 */
74
75 static void throwNewDebuggerException(JNIEnv* env, const char* errMsg) {
76 jclass clazz = env->FindClass("sun/jvm/hotspot/debugger/DebuggerException");
77 CHECK_EXCEPTION;
78 env->ThrowNew(clazz, errMsg);
79 }
80
81 // JNI ids for some fields, methods
82
83 // libproc handler pointer
84 static jfieldID p_ps_prochandle_ID = 0;
85
86 // libthread.so dlopen handle, thread agent ptr and function pointers
87 static jfieldID libthread_db_handle_ID = 0;
88 static jfieldID p_td_thragent_t_ID = 0;
89 static jfieldID p_td_init_ID = 0;
156 env->SetLongField(this_obj, p_td_ta_map_id2thr_ID, (jlong)0);
157 env->SetLongField(this_obj, p_td_thr_getgregs_ID, (jlong)0);
158 }
159
160
161 static void detach_internal(JNIEnv* env, jobject this_obj) {
162 // clear libthread_db stuff
163 clear_libthread_db_ptrs(env, this_obj);
164
165 // release ptr to ps_prochandle
166 jlong p_ps_prochandle;
167 p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
168 if (p_ps_prochandle != 0L) {
169 Prelease((struct ps_prochandle*) p_ps_prochandle, PRELEASE_CLEAR);
170 }
171
172 // part of the class sharing workaround
173 int classes_jsa_fd = env->GetIntField(this_obj, classes_jsa_fd_ID);
174 if (classes_jsa_fd != -1) {
175 close(classes_jsa_fd);
176 struct FileMapHeader* pheader = (struct FileMapHeader*) env->GetLongField(this_obj, p_file_map_header_ID);
177 if (pheader != NULL) {
178 free(pheader);
179 }
180 }
181 }
182
183 // Is it okay to ignore libthread_db failure? Set env var to ignore
184 // libthread_db failure. You can still debug, but will miss threads
185 // related functionality.
186 static bool sa_ignore_threaddb = (getenv("SA_IGNORE_THREADDB") != 0);
187
188 #define HANDLE_THREADDB_FAILURE(msg) \
189 if (sa_ignore_threaddb) { \
190 printf("libsaproc WARNING: %s\n", msg); \
191 return; \
192 } else { \
193 THROW_NEW_DEBUGGER_EXCEPTION(msg); \
194 }
195
196 #define HANDLE_THREADDB_FAILURE_(msg, ret) \
467 jlong pc = (jlong) (uintptr_t) regs[pcRegIndex];
468 jlong fp = (jlong) (uintptr_t) regs[fpRegIndex];
469
470 dbgo2->obj2 = env->CallObjectMethod(this_obj, createSenderFrame_ID,
471 curFrame, pc, fp);
472 CHECK_EXCEPTION_(1);
473 if (dbgo2->obj == 0) {
474 dbgo2->obj = dbgo2->obj2;
475 }
476 return 0;
477 }
478
479 // Pstack_iter() proc_stack_f callback in Nevada-B159 or later
480 /*ARGSUSED*/
481 static int
482 wrapper_fill_cframe_list(void *cd, const prgregset_t regs, uint_t argc,
483 const long *argv, int frame_flags, int sig) {
484 return(fill_cframe_list(cd, regs, argc, argv));
485 }
486
487 // part of the class sharing workaround
488
489 // FIXME: !!HACK ALERT!!
490
491 // The format of sharing achive file header is needed to read shared heap
492 // file mappings. For now, I am hard coding portion of FileMapHeader here.
493 // Refer to filemap.hpp.
494
495 // FileMapHeader describes the shared space data in the file to be
496 // mapped. This structure gets written to a file. It is not a class, so
497 // that the compilers don't add any compiler-private data to it.
498
499 const int NUM_SHARED_MAPS = 9;
500
501 // Refer to FileMapInfo::_current_version in filemap.hpp
502 const int CURRENT_ARCHIVE_VERSION = 3;
503
504 typedef unsigned char* address;
505 typedef uintptr_t uintx;
506 typedef intptr_t intx;
507
508 struct FileMapHeader {
509 int _magic; // identify file type.
510 int _crc; // header crc checksum.
511 int _version; // (from enum, above.)
512 size_t _alignment; // how shared archive should be aligned
513 int _obj_alignment; // value of ObjectAlignmentInBytes
514 address _narrow_oop_base; // compressed oop encoding base
515 int _narrow_oop_shift; // compressed oop encoding shift
516 bool _compact_strings; // value of CompactStrings
517 uintx _max_heap_size; // java max heap size during dumping
518 int _narrow_oop_mode; // compressed oop encoding mode
519 int _narrow_klass_shift; // save narrow klass base and shift
520 address _narrow_klass_base;
521 char* _misc_data_patching_start;
522 char* _read_only_tables_start;
523 address _cds_i2i_entry_code_buffers;
524 size_t _cds_i2i_entry_code_buffers_size;
525 size_t _core_spaces_size; // number of bytes allocated by the core spaces
526 // (mc, md, ro, rw and od).
527
528
529 struct space_info {
530 int _crc; // crc checksum of the current space
531 size_t _file_offset; // sizeof(this) rounded to vm page size
532 union {
533 char* _base; // copy-on-write base address
534 intx _offset; // offset from the compressed oop encoding base, only used
535 // by archive heap space
536 } _addr;
537 size_t _used; // for setting space top on read
538 // 4991491 NOTICE These are C++ bool's in filemap.hpp and must match up with
539 // the C type matching the C++ bool type on any given platform.
540 // We assume the corresponding C type is char but licensees
541 // may need to adjust the type of these fields.
542 char _read_only; // read only space?
543 char _allow_exec; // executable code in space?
544 } _space[NUM_SHARED_MAPS];
545
546 // Ignore the rest of the FileMapHeader. We don't need those fields here.
547 };
548
549 static bool
550 read_jboolean(struct ps_prochandle* ph, psaddr_t addr, jboolean* pvalue) {
551 jboolean i;
552 if (ps_pread(ph, addr, &i, sizeof(i)) == PS_OK) {
553 *pvalue = i;
554 return true;
555 } else {
556 return false;
557 }
558 }
559
560 static bool
561 read_pointer(struct ps_prochandle* ph, psaddr_t addr, uintptr_t* pvalue) {
562 uintptr_t uip;
563 if (ps_pread(ph, addr, &uip, sizeof(uip)) == PS_OK) {
564 *pvalue = uip;
565 return true;
566 } else {
567 return false;
645 }
646
647 if (read_string(ph, (psaddr_t)sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
648 print_debug("can't find read 'Arguments::SharedArchivePath' value\n");
649 THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
650 }
651
652 print_debug("looking for %s\n", classes_jsa);
653
654 // open the classes.jsa
655 int fd = libsaproc_open(classes_jsa, O_RDONLY);
656 if (fd < 0) {
657 char errMsg[ERR_MSG_SIZE];
658 sprintf(errMsg, "can't open shared archive file %s", classes_jsa);
659 THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
660 } else {
661 print_debug("opened shared archive file %s\n", classes_jsa);
662 }
663
664 // parse classes.jsa
665 struct FileMapHeader* pheader = (struct FileMapHeader*) malloc(sizeof(struct FileMapHeader));
666 if (pheader == NULL) {
667 close(fd);
668 THROW_NEW_DEBUGGER_EXCEPTION_("can't allocate memory for shared file map header", 1);
669 }
670
671 memset(pheader, 0, sizeof(struct FileMapHeader));
672 // read FileMapHeader
673 size_t n = read(fd, pheader, sizeof(struct FileMapHeader));
674 if (n != sizeof(struct FileMapHeader)) {
675 char errMsg[ERR_MSG_SIZE];
676 sprintf(errMsg, "unable to read shared archive file map header from %s", classes_jsa);
677 close(fd);
678 free(pheader);
679 THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
680 }
681
682 // check file magic
683 if (pheader->_magic != 0xf00baba2) {
684 char errMsg[ERR_MSG_SIZE];
685 sprintf(errMsg, "%s has bad shared archive magic 0x%x, expecting 0xf00baba2",
686 classes_jsa, pheader->_magic);
687 close(fd);
688 free(pheader);
689 THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
690 }
691
692 // check version
693 if (pheader->_version != CURRENT_ARCHIVE_VERSION) {
694 char errMsg[ERR_MSG_SIZE];
695 sprintf(errMsg, "%s has wrong shared archive version %d, expecting %d",
696 classes_jsa, pheader->_version, CURRENT_ARCHIVE_VERSION);
697 close(fd);
698 free(pheader);
699 THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
700 }
701
702 if (_libsaproc_debug) {
703 for (int m = 0; m < NUM_SHARED_MAPS; m++) {
704 print_debug("shared file offset %d mapped at 0x%lx, size = %ld, read only? = %d\n",
705 pheader->_space[m]._file_offset, pheader->_space[m]._addr._base,
706 pheader->_space[m]._used, pheader->_space[m]._read_only);
707 }
708 }
709
710 // FIXME: For now, omitting other checks such as VM version etc.
711
712 // store class archive file fd and map header in debugger object fields
713 dbg->env->SetIntField(this_obj, classes_jsa_fd_ID, fd);
714 dbg->env->SetLongField(this_obj, p_file_map_header_ID, (jlong)(uintptr_t) pheader);
715 return 1;
716 }
717
718 } // extern "C"
719
720 // error messages for proc_arg_grab failure codes. The messages are
721 // modified versions of comments against corresponding #defines in
722 // libproc.h.
723 static const char* proc_arg_grab_errmsgs[] = {
1074 */
1075 JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_readBytesFromProcess0
1076 (JNIEnv *env, jobject this_obj, jlong address, jlong numBytes) {
1077
1078 jbyteArray array = env->NewByteArray(numBytes);
1079 CHECK_EXCEPTION_(0);
1080 jboolean isCopy;
1081 jbyte* bufPtr = env->GetByteArrayElements(array, &isCopy);
1082 CHECK_EXCEPTION_(0);
1083
1084 jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
1085 ps_err_e ret = ps_pread((struct ps_prochandle*) p_ps_prochandle,
1086 (psaddr_t)address, bufPtr, (size_t)numBytes);
1087
1088 if (ret != PS_OK) {
1089 // part of the class sharing workaround. try shared heap area
1090 int classes_jsa_fd = env->GetIntField(this_obj, classes_jsa_fd_ID);
1091 if (classes_jsa_fd != -1 && address != (jlong)0) {
1092 print_debug("read failed at 0x%lx, attempting shared heap area\n", (long) address);
1093
1094 struct FileMapHeader* pheader = (struct FileMapHeader*) env->GetLongField(this_obj, p_file_map_header_ID);
1095 // walk through the shared mappings -- we just have 9 of them.
1096 // so, linear walking is okay.
1097 for (int m = 0; m < NUM_SHARED_MAPS; m++) {
1098
1099 // We can skip the non-read-only maps. These are mapped as MAP_PRIVATE
1100 // and hence will be read by libproc. Besides, the file copy may be
1101 // stale because the process might have modified those pages.
1102 if (pheader->_space[m]._read_only) {
1103 jlong baseAddress = (jlong) (uintptr_t) pheader->_space[m]._addr._base;
1104 size_t usedSize = pheader->_space[m]._used;
1105 if (address >= baseAddress && address < (baseAddress + usedSize)) {
1106 // the given address falls in this shared heap area
1107 print_debug("found shared map at 0x%lx\n", (long) baseAddress);
1108
1109
1110 // If more data is asked than actually mapped from file, we need to zero fill
1111 // till the end-of-page boundary. But, java array new does that for us. we just
1112 // need to read as much as data available.
1113
1114 #define MIN2(x, y) (((x) < (y))? (x) : (y))
1115
1116 jlong diff = address - baseAddress;
1117 jlong bytesToRead = MIN2(numBytes, usedSize - diff);
|
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 "salibproc.h"
26 #include "sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal.h"
27 #include <thread_db.h>
28 #include <strings.h>
29 #include <limits.h>
30 #include <demangle.h>
31 #include <stdarg.h>
32 #include <stdlib.h>
33 #include <errno.h>
34 #include "../../../../hotspot/share/include/cds.h"
35
36 #define CHECK_EXCEPTION_(value) if(env->ExceptionOccurred()) { return value; }
37 #define CHECK_EXCEPTION if(env->ExceptionOccurred()) { return;}
38 #define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throwNewDebuggerException(env, str); return value; }
39 #define THROW_NEW_DEBUGGER_EXCEPTION(str) { throwNewDebuggerException(env, str); return;}
40
41 #define SYMBOL_BUF_SIZE 256
42 #define ERR_MSG_SIZE (PATH_MAX + 256)
43
44 // debug modes
45 static int _libsaproc_debug = 0;
46
47 static void print_debug(const char* format,...) {
48 if (_libsaproc_debug) {
49 va_list alist;
50
51 va_start(alist, format);
52 fputs("libsaproc DEBUG: ", stderr);
53 vfprintf(stderr, format, alist);
54 va_end(alist);
55 }
56 }
57
58 struct Debugger {
59 JNIEnv* env;
60 jobject this_obj;
61 };
62
63 struct DebuggerWithObject : Debugger {
64 jobject obj;
65 };
66
67 struct DebuggerWith2Objects : DebuggerWithObject {
68 jobject obj2;
69 };
70
71 typedef struct CDSFileMapHeaderBase FileMapHeader;
72
73 /*
74 * Portions of user thread level detail gathering code is from pstack source
75 * code. See pstack.c in Solaris 2.8 user commands source code.
76 */
77
78 static void throwNewDebuggerException(JNIEnv* env, const char* errMsg) {
79 jclass clazz = env->FindClass("sun/jvm/hotspot/debugger/DebuggerException");
80 CHECK_EXCEPTION;
81 env->ThrowNew(clazz, errMsg);
82 }
83
84 // JNI ids for some fields, methods
85
86 // libproc handler pointer
87 static jfieldID p_ps_prochandle_ID = 0;
88
89 // libthread.so dlopen handle, thread agent ptr and function pointers
90 static jfieldID libthread_db_handle_ID = 0;
91 static jfieldID p_td_thragent_t_ID = 0;
92 static jfieldID p_td_init_ID = 0;
159 env->SetLongField(this_obj, p_td_ta_map_id2thr_ID, (jlong)0);
160 env->SetLongField(this_obj, p_td_thr_getgregs_ID, (jlong)0);
161 }
162
163
164 static void detach_internal(JNIEnv* env, jobject this_obj) {
165 // clear libthread_db stuff
166 clear_libthread_db_ptrs(env, this_obj);
167
168 // release ptr to ps_prochandle
169 jlong p_ps_prochandle;
170 p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
171 if (p_ps_prochandle != 0L) {
172 Prelease((struct ps_prochandle*) p_ps_prochandle, PRELEASE_CLEAR);
173 }
174
175 // part of the class sharing workaround
176 int classes_jsa_fd = env->GetIntField(this_obj, classes_jsa_fd_ID);
177 if (classes_jsa_fd != -1) {
178 close(classes_jsa_fd);
179 FileMapHeader* pheader = (FileMapHeader*) env->GetLongField(this_obj, p_file_map_header_ID);
180 if (pheader != NULL) {
181 free(pheader);
182 }
183 }
184 }
185
186 // Is it okay to ignore libthread_db failure? Set env var to ignore
187 // libthread_db failure. You can still debug, but will miss threads
188 // related functionality.
189 static bool sa_ignore_threaddb = (getenv("SA_IGNORE_THREADDB") != 0);
190
191 #define HANDLE_THREADDB_FAILURE(msg) \
192 if (sa_ignore_threaddb) { \
193 printf("libsaproc WARNING: %s\n", msg); \
194 return; \
195 } else { \
196 THROW_NEW_DEBUGGER_EXCEPTION(msg); \
197 }
198
199 #define HANDLE_THREADDB_FAILURE_(msg, ret) \
470 jlong pc = (jlong) (uintptr_t) regs[pcRegIndex];
471 jlong fp = (jlong) (uintptr_t) regs[fpRegIndex];
472
473 dbgo2->obj2 = env->CallObjectMethod(this_obj, createSenderFrame_ID,
474 curFrame, pc, fp);
475 CHECK_EXCEPTION_(1);
476 if (dbgo2->obj == 0) {
477 dbgo2->obj = dbgo2->obj2;
478 }
479 return 0;
480 }
481
482 // Pstack_iter() proc_stack_f callback in Nevada-B159 or later
483 /*ARGSUSED*/
484 static int
485 wrapper_fill_cframe_list(void *cd, const prgregset_t regs, uint_t argc,
486 const long *argv, int frame_flags, int sig) {
487 return(fill_cframe_list(cd, regs, argc, argv));
488 }
489
490 //---------------------------------------------------------------
491 // Part of the class sharing workaround:
492 //
493 // With class sharing, pages are mapped from classes.jsa file.
494 // The read-only class sharing pages are mapped as MAP_SHARED,
495 // PROT_READ pages. These pages are not dumped into core dump.
496 // With this workaround, these pages are read from classes.jsa.
497
498 static bool
499 read_jboolean(struct ps_prochandle* ph, psaddr_t addr, jboolean* pvalue) {
500 jboolean i;
501 if (ps_pread(ph, addr, &i, sizeof(i)) == PS_OK) {
502 *pvalue = i;
503 return true;
504 } else {
505 return false;
506 }
507 }
508
509 static bool
510 read_pointer(struct ps_prochandle* ph, psaddr_t addr, uintptr_t* pvalue) {
511 uintptr_t uip;
512 if (ps_pread(ph, addr, &uip, sizeof(uip)) == PS_OK) {
513 *pvalue = uip;
514 return true;
515 } else {
516 return false;
594 }
595
596 if (read_string(ph, (psaddr_t)sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
597 print_debug("can't find read 'Arguments::SharedArchivePath' value\n");
598 THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
599 }
600
601 print_debug("looking for %s\n", classes_jsa);
602
603 // open the classes.jsa
604 int fd = libsaproc_open(classes_jsa, O_RDONLY);
605 if (fd < 0) {
606 char errMsg[ERR_MSG_SIZE];
607 sprintf(errMsg, "can't open shared archive file %s", classes_jsa);
608 THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
609 } else {
610 print_debug("opened shared archive file %s\n", classes_jsa);
611 }
612
613 // parse classes.jsa
614 FileMapHeader* pheader = (FileMapHeader*) malloc(sizeof(FileMapHeader));
615 if (pheader == NULL) {
616 close(fd);
617 THROW_NEW_DEBUGGER_EXCEPTION_("can't allocate memory for shared file map header", 1);
618 }
619
620 memset(pheader, 0, sizeof(FileMapHeader));
621 // read FileMapHeader
622 size_t n = read(fd, pheader, sizeof(FileMapHeader));
623 if (n != sizeof(FileMapHeader)) {
624 char errMsg[ERR_MSG_SIZE];
625 sprintf(errMsg, "unable to read shared archive file map header from %s", classes_jsa);
626 close(fd);
627 free(pheader);
628 THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
629 }
630
631 // check file magic
632 if (pheader->_magic != CDS_ARCHIVE_MAGIC) {
633 char errMsg[ERR_MSG_SIZE];
634 sprintf(errMsg, "%s has bad shared archive magic 0x%x, expecting 0x%x",
635 classes_jsa, pheader->_magic, CDS_ARCHIVE_MAGIC);
636 close(fd);
637 free(pheader);
638 THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
639 }
640
641 // check version
642 if (pheader->_version != CURRENT_CDS_ARCHIVE_VERSION) {
643 char errMsg[ERR_MSG_SIZE];
644 sprintf(errMsg, "%s has wrong shared archive version %d, expecting %d",
645 classes_jsa, pheader->_version, CURRENT_CDS_ARCHIVE_VERSION);
646 close(fd);
647 free(pheader);
648 THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
649 }
650
651 if (_libsaproc_debug) {
652 for (int m = 0; m < NUM_CDS_REGIONS; m++) {
653 print_debug("shared file offset %d mapped at 0x%lx, size = %ld, read only? = %d\n",
654 pheader->_space[m]._file_offset, pheader->_space[m]._addr._base,
655 pheader->_space[m]._used, pheader->_space[m]._read_only);
656 }
657 }
658
659 // FIXME: For now, omitting other checks such as VM version etc.
660
661 // store class archive file fd and map header in debugger object fields
662 dbg->env->SetIntField(this_obj, classes_jsa_fd_ID, fd);
663 dbg->env->SetLongField(this_obj, p_file_map_header_ID, (jlong)(uintptr_t) pheader);
664 return 1;
665 }
666
667 } // extern "C"
668
669 // error messages for proc_arg_grab failure codes. The messages are
670 // modified versions of comments against corresponding #defines in
671 // libproc.h.
672 static const char* proc_arg_grab_errmsgs[] = {
1023 */
1024 JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_readBytesFromProcess0
1025 (JNIEnv *env, jobject this_obj, jlong address, jlong numBytes) {
1026
1027 jbyteArray array = env->NewByteArray(numBytes);
1028 CHECK_EXCEPTION_(0);
1029 jboolean isCopy;
1030 jbyte* bufPtr = env->GetByteArrayElements(array, &isCopy);
1031 CHECK_EXCEPTION_(0);
1032
1033 jlong p_ps_prochandle = env->GetLongField(this_obj, p_ps_prochandle_ID);
1034 ps_err_e ret = ps_pread((struct ps_prochandle*) p_ps_prochandle,
1035 (psaddr_t)address, bufPtr, (size_t)numBytes);
1036
1037 if (ret != PS_OK) {
1038 // part of the class sharing workaround. try shared heap area
1039 int classes_jsa_fd = env->GetIntField(this_obj, classes_jsa_fd_ID);
1040 if (classes_jsa_fd != -1 && address != (jlong)0) {
1041 print_debug("read failed at 0x%lx, attempting shared heap area\n", (long) address);
1042
1043 FileMapHeader* pheader = (FileMapHeader*) env->GetLongField(this_obj, p_file_map_header_ID);
1044 // walk through the shared mappings -- we just have 9 of them.
1045 // so, linear walking is okay.
1046 for (int m = 0; m < NUM_CDS_REGIONS; m++) {
1047
1048 // We can skip the non-read-only maps. These are mapped as MAP_PRIVATE
1049 // and hence will be read by libproc. Besides, the file copy may be
1050 // stale because the process might have modified those pages.
1051 if (pheader->_space[m]._read_only) {
1052 jlong baseAddress = (jlong) (uintptr_t) pheader->_space[m]._addr._base;
1053 size_t usedSize = pheader->_space[m]._used;
1054 if (address >= baseAddress && address < (baseAddress + usedSize)) {
1055 // the given address falls in this shared heap area
1056 print_debug("found shared map at 0x%lx\n", (long) baseAddress);
1057
1058
1059 // If more data is asked than actually mapped from file, we need to zero fill
1060 // till the end-of-page boundary. But, java array new does that for us. we just
1061 // need to read as much as data available.
1062
1063 #define MIN2(x, y) (((x) < (y))? (x) : (y))
1064
1065 jlong diff = address - baseAddress;
1066 jlong bytesToRead = MIN2(numBytes, usedSize - diff);
|