38 #include "memory/filemap.hpp"
39 #include "memory/heapShared.inline.hpp"
40 #include "memory/iterator.inline.hpp"
41 #include "memory/metadataFactory.hpp"
42 #include "memory/metaspaceClosure.hpp"
43 #include "memory/metaspaceShared.hpp"
44 #include "memory/oopFactory.hpp"
45 #include "memory/universe.hpp"
46 #include "oops/compressedOops.hpp"
47 #include "oops/compressedOops.inline.hpp"
48 #include "oops/objArrayOop.hpp"
49 #include "oops/oop.inline.hpp"
50 #include "prims/jvmtiExport.hpp"
51 #include "runtime/arguments.hpp"
52 #include "runtime/java.hpp"
53 #include "runtime/mutexLocker.hpp"
54 #include "runtime/os.inline.hpp"
55 #include "runtime/vm_version.hpp"
56 #include "services/memTracker.hpp"
57 #include "utilities/align.hpp"
58 #include "utilities/defaultStream.hpp"
59 #if INCLUDE_G1GC
60 #include "gc/g1/g1CollectedHeap.hpp"
61 #include "gc/g1/heapRegion.hpp"
62 #endif
63
64 # include <sys/stat.h>
65 # include <errno.h>
66
67 #ifndef O_BINARY // if defined (Win32) use binary files.
68 #define O_BINARY 0 // otherwise do nothing.
69 #endif
70
71 extern address JVM_FunctionAtStart();
72 extern address JVM_FunctionAtEnd();
73
74 // Complain and stop. All error conditions occurring during the writing of
75 // an archive file should stop the process. Unrecoverable errors during
76 // the reading of the archive file should stop the process.
77
582 int FileMapInfo::num_paths(const char* path) {
583 if (path == NULL) {
584 return 0;
585 }
586 int npaths = 1;
587 char* p = (char*)path;
588 while (p != NULL) {
589 char* prev = p;
590 p = strstr((char*)p, os::path_separator());
591 if (p != NULL) {
592 p++;
593 // don't count empty path
594 if ((p - prev) > 1) {
595 npaths++;
596 }
597 }
598 }
599 return npaths;
600 }
601
602 GrowableArray<char*>* FileMapInfo::create_path_array(const char* path) {
603 GrowableArray<char*>* path_array = new(ResourceObj::RESOURCE_AREA, mtInternal)
604 GrowableArray<char*>(10);
605 char* begin_ptr = (char*)path;
606 char* end_ptr = strchr((char*)path, os::path_separator()[0]);
607 if (end_ptr == NULL) {
608 end_ptr = strchr((char*)path, '\0');
609 }
610 while (end_ptr != NULL) {
611 if ((end_ptr - begin_ptr) > 1) {
612 struct stat st;
613 char* temp_name = NEW_RESOURCE_ARRAY(char, (size_t)(end_ptr - begin_ptr + 1));
614 strncpy(temp_name, begin_ptr, end_ptr - begin_ptr);
615 temp_name[end_ptr - begin_ptr] = '\0';
616 if (os::stat(temp_name, &st) == 0) {
617 path_array->append(temp_name);
618 }
619 }
620 if (end_ptr < (path + strlen(path))) {
621 begin_ptr = ++end_ptr;
622 end_ptr = strchr(begin_ptr, os::path_separator()[0]);
623 if (end_ptr == NULL) {
624 end_ptr = strchr(begin_ptr, '\0');
625 }
626 } else {
627 break;
628 }
629 }
630 return path_array;
631 }
632
633 bool FileMapInfo::fail(const char* msg, const char* name) {
634 ClassLoader::trace_class_path(msg, name);
635 MetaspaceShared::set_archive_loading_failed();
636 return false;
637 }
638
639 bool FileMapInfo::check_paths(int shared_path_start_idx, int num_paths, GrowableArray<char*>* rp_array) {
640 int i = 0;
641 int j = shared_path_start_idx;
642 bool mismatch = false;
643 while (i < num_paths && !mismatch) {
644 while (shared_path(j)->from_class_path_attr()) {
645 // shared_path(j) was expanded from the JAR file attribute "Class-Path:"
646 // during dump time. It's not included in the -classpath VM argument.
647 j++;
648 }
649 if (!os::same_files(shared_path(j)->name(), rp_array->at(i))) {
650 mismatch = true;
651 }
652 i++;
653 j++;
654 }
655 return mismatch;
656 }
657
658 bool FileMapInfo::validate_boot_class_paths() {
659 //
673 // after generating the shared archive), which is acceptable. For most
674 // common cases, the dump time boot path might contain modules_image only.
675 char* runtime_boot_path = Arguments::get_sysclasspath();
676 char* rp = skip_first_path_entry(runtime_boot_path);
677 assert(shared_path(0)->is_modules_image(), "first shared_path must be the modules image");
678 int dp_len = _header->_app_class_paths_start_index - 1; // ignore the first path to the module image
679 bool mismatch = false;
680
681 bool relaxed_check = !header()->has_platform_or_app_classes();
682 if (dp_len == 0 && rp == NULL) {
683 return true; // ok, both runtime and dump time boot paths have modules_images only
684 } else if (dp_len == 0 && rp != NULL) {
685 if (relaxed_check) {
686 return true; // ok, relaxed check, runtime has extra boot append path entries
687 } else {
688 mismatch = true;
689 }
690 } else if (dp_len > 0 && rp != NULL) {
691 int num;
692 ResourceMark rm;
693 GrowableArray<char*>* rp_array = create_path_array(rp);
694 int rp_len = rp_array->length();
695 if (rp_len >= dp_len) {
696 if (relaxed_check) {
697 // only check the leading entries in the runtime boot path, up to
698 // the length of the dump time boot path
699 num = dp_len;
700 } else {
701 // check the full runtime boot path, must match with dump time
702 num = rp_len;
703 }
704 mismatch = check_paths(1, num, rp_array);
705 }
706 }
707
708 if (mismatch) {
709 // The paths are different
710 return fail("[BOOT classpath mismatch, actual =", runtime_boot_path);
711 }
712 return true;
713 }
714
715 bool FileMapInfo::validate_app_class_paths(int shared_app_paths_len) {
716 const char *appcp = Arguments::get_appclasspath();
717 assert(appcp != NULL, "NULL app classpath");
718 int rp_len = num_paths(appcp);
719 bool mismatch = false;
720 if (rp_len < shared_app_paths_len) {
721 return fail("Run time APP classpath is shorter than the one at dump time: ", appcp);
722 }
723 if (shared_app_paths_len != 0 && rp_len != 0) {
724 // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar.
725 ResourceMark rm;
726 GrowableArray<char*>* rp_array = create_path_array(appcp);
727 if (rp_array->length() == 0) {
728 // None of the jar file specified in the runtime -cp exists.
729 return fail("None of the jar file specified in the runtime -cp exists: -Djava.class.path=", appcp);
730 }
731 int j = _header->_app_class_paths_start_index;
732 mismatch = check_paths(j, shared_app_paths_len, rp_array);
733 if (mismatch) {
734 return fail("[APP classpath mismatch, actual: -Djava.class.path=", appcp);
735 }
736 }
737 return true;
738 }
739
740 void FileMapInfo::log_paths(const char* msg, int start_idx, int end_idx) {
741 LogTarget(Info, class, path) lt;
742 if (lt.is_enabled()) {
743 LogStream ls(lt);
744 ls.print("%s", msg);
745 const char* prefix = "";
746 for (int i = start_idx; i < end_idx; i++) {
|
38 #include "memory/filemap.hpp"
39 #include "memory/heapShared.inline.hpp"
40 #include "memory/iterator.inline.hpp"
41 #include "memory/metadataFactory.hpp"
42 #include "memory/metaspaceClosure.hpp"
43 #include "memory/metaspaceShared.hpp"
44 #include "memory/oopFactory.hpp"
45 #include "memory/universe.hpp"
46 #include "oops/compressedOops.hpp"
47 #include "oops/compressedOops.inline.hpp"
48 #include "oops/objArrayOop.hpp"
49 #include "oops/oop.inline.hpp"
50 #include "prims/jvmtiExport.hpp"
51 #include "runtime/arguments.hpp"
52 #include "runtime/java.hpp"
53 #include "runtime/mutexLocker.hpp"
54 #include "runtime/os.inline.hpp"
55 #include "runtime/vm_version.hpp"
56 #include "services/memTracker.hpp"
57 #include "utilities/align.hpp"
58 #include "utilities/classpathStream.hpp"
59 #include "utilities/defaultStream.hpp"
60 #if INCLUDE_G1GC
61 #include "gc/g1/g1CollectedHeap.hpp"
62 #include "gc/g1/heapRegion.hpp"
63 #endif
64
65 # include <sys/stat.h>
66 # include <errno.h>
67
68 #ifndef O_BINARY // if defined (Win32) use binary files.
69 #define O_BINARY 0 // otherwise do nothing.
70 #endif
71
72 extern address JVM_FunctionAtStart();
73 extern address JVM_FunctionAtEnd();
74
75 // Complain and stop. All error conditions occurring during the writing of
76 // an archive file should stop the process. Unrecoverable errors during
77 // the reading of the archive file should stop the process.
78
583 int FileMapInfo::num_paths(const char* path) {
584 if (path == NULL) {
585 return 0;
586 }
587 int npaths = 1;
588 char* p = (char*)path;
589 while (p != NULL) {
590 char* prev = p;
591 p = strstr((char*)p, os::path_separator());
592 if (p != NULL) {
593 p++;
594 // don't count empty path
595 if ((p - prev) > 1) {
596 npaths++;
597 }
598 }
599 }
600 return npaths;
601 }
602
603 GrowableArray<const char*>* FileMapInfo::create_path_array(const char* paths) {
604 GrowableArray<const char*>* path_array = new(ResourceObj::RESOURCE_AREA, mtInternal)
605 GrowableArray<const char*>(10);
606
607 ClasspathStream cp_stream(paths);
608 while (cp_stream.has_next()) {
609 const char* path = cp_stream.get_next();
610 struct stat st;
611 if (os::stat(path, &st) == 0) {
612 path_array->append(path);
613 }
614 }
615 return path_array;
616 }
617
618 bool FileMapInfo::fail(const char* msg, const char* name) {
619 ClassLoader::trace_class_path(msg, name);
620 MetaspaceShared::set_archive_loading_failed();
621 return false;
622 }
623
624 bool FileMapInfo::check_paths(int shared_path_start_idx, int num_paths, GrowableArray<const char*>* rp_array) {
625 int i = 0;
626 int j = shared_path_start_idx;
627 bool mismatch = false;
628 while (i < num_paths && !mismatch) {
629 while (shared_path(j)->from_class_path_attr()) {
630 // shared_path(j) was expanded from the JAR file attribute "Class-Path:"
631 // during dump time. It's not included in the -classpath VM argument.
632 j++;
633 }
634 if (!os::same_files(shared_path(j)->name(), rp_array->at(i))) {
635 mismatch = true;
636 }
637 i++;
638 j++;
639 }
640 return mismatch;
641 }
642
643 bool FileMapInfo::validate_boot_class_paths() {
644 //
658 // after generating the shared archive), which is acceptable. For most
659 // common cases, the dump time boot path might contain modules_image only.
660 char* runtime_boot_path = Arguments::get_sysclasspath();
661 char* rp = skip_first_path_entry(runtime_boot_path);
662 assert(shared_path(0)->is_modules_image(), "first shared_path must be the modules image");
663 int dp_len = _header->_app_class_paths_start_index - 1; // ignore the first path to the module image
664 bool mismatch = false;
665
666 bool relaxed_check = !header()->has_platform_or_app_classes();
667 if (dp_len == 0 && rp == NULL) {
668 return true; // ok, both runtime and dump time boot paths have modules_images only
669 } else if (dp_len == 0 && rp != NULL) {
670 if (relaxed_check) {
671 return true; // ok, relaxed check, runtime has extra boot append path entries
672 } else {
673 mismatch = true;
674 }
675 } else if (dp_len > 0 && rp != NULL) {
676 int num;
677 ResourceMark rm;
678 GrowableArray<const char*>* rp_array = create_path_array(rp);
679 int rp_len = rp_array->length();
680 if (rp_len >= dp_len) {
681 if (relaxed_check) {
682 // only check the leading entries in the runtime boot path, up to
683 // the length of the dump time boot path
684 num = dp_len;
685 } else {
686 // check the full runtime boot path, must match with dump time
687 num = rp_len;
688 }
689 mismatch = check_paths(1, num, rp_array);
690 }
691 }
692
693 if (mismatch) {
694 // The paths are different
695 return fail("[BOOT classpath mismatch, actual =", runtime_boot_path);
696 }
697 return true;
698 }
699
700 bool FileMapInfo::validate_app_class_paths(int shared_app_paths_len) {
701 const char *appcp = Arguments::get_appclasspath();
702 assert(appcp != NULL, "NULL app classpath");
703 int rp_len = num_paths(appcp);
704 bool mismatch = false;
705 if (rp_len < shared_app_paths_len) {
706 return fail("Run time APP classpath is shorter than the one at dump time: ", appcp);
707 }
708 if (shared_app_paths_len != 0 && rp_len != 0) {
709 // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar.
710 ResourceMark rm;
711 GrowableArray<const char*>* rp_array = create_path_array(appcp);
712 if (rp_array->length() == 0) {
713 // None of the jar file specified in the runtime -cp exists.
714 return fail("None of the jar file specified in the runtime -cp exists: -Djava.class.path=", appcp);
715 }
716 int j = _header->_app_class_paths_start_index;
717 mismatch = check_paths(j, shared_app_paths_len, rp_array);
718 if (mismatch) {
719 return fail("[APP classpath mismatch, actual: -Djava.class.path=", appcp);
720 }
721 }
722 return true;
723 }
724
725 void FileMapInfo::log_paths(const char* msg, int start_idx, int end_idx) {
726 LogTarget(Info, class, path) lt;
727 if (lt.is_enabled()) {
728 LogStream ls(lt);
729 ls.print("%s", msg);
730 const char* prefix = "";
731 for (int i = start_idx; i < end_idx; i++) {
|