797 } |
797 } |
798 |
798 |
799 VMError* volatile VMError::first_error = NULL; |
799 VMError* volatile VMError::first_error = NULL; |
800 volatile jlong VMError::first_error_tid = -1; |
800 volatile jlong VMError::first_error_tid = -1; |
801 |
801 |
|
802 /** Expand a pattern into a buffer starting at pos and open a file using constructed path */ |
|
803 static int expand_and_open(const char* pattern, char* buf, size_t buflen, size_t pos) { |
|
804 int fd = -1; |
|
805 if (Arguments::copy_expand_pid(pattern, strlen(pattern), &buf[pos], buflen - pos)) { |
|
806 fd = open(buf, O_RDWR | O_CREAT | O_TRUNC, 0666); |
|
807 } |
|
808 return fd; |
|
809 } |
|
810 |
|
811 /** |
|
812 * Construct file name for a log file and return it's file descriptor. |
|
813 * Name and location depends on pattern, default_pattern params and access |
|
814 * permissions. |
|
815 */ |
|
816 static int prepare_log_file(const char* pattern, const char* default_pattern, char* buf, size_t buflen) { |
|
817 int fd = -1; |
|
818 |
|
819 // If possible, use specified pattern to construct log file name |
|
820 if (pattern != NULL) { |
|
821 fd = expand_and_open(pattern, buf, buflen, 0); |
|
822 } |
|
823 |
|
824 // Either user didn't specify, or the user's location failed, |
|
825 // so use the default name in the current directory |
|
826 if (fd == -1) { |
|
827 const char* cwd = os::get_current_directory(buf, buflen); |
|
828 if (cwd != NULL) { |
|
829 size_t pos = strlen(cwd); |
|
830 int fsep_len = jio_snprintf(&buf[pos], buflen-pos, "%s", os::file_separator()); |
|
831 pos += fsep_len; |
|
832 if (fsep_len > 0) { |
|
833 fd = expand_and_open(default_pattern, buf, buflen, pos); |
|
834 } |
|
835 } |
|
836 } |
|
837 |
|
838 // try temp directory if it exists. |
|
839 if (fd == -1) { |
|
840 const char* tmpdir = os::get_temp_directory(); |
|
841 if (tmpdir != NULL && strlen(tmpdir) > 0) { |
|
842 int pos = jio_snprintf(buf, buflen, "%s%s", tmpdir, os::file_separator()); |
|
843 if (pos > 0) { |
|
844 fd = expand_and_open(default_pattern, buf, buflen, pos); |
|
845 } |
|
846 } |
|
847 } |
|
848 |
|
849 return fd; |
|
850 } |
|
851 |
802 void VMError::report_and_die() { |
852 void VMError::report_and_die() { |
803 // Don't allocate large buffer on stack |
853 // Don't allocate large buffer on stack |
804 static char buffer[O_BUFLEN]; |
854 static char buffer[O_BUFLEN]; |
805 |
855 |
806 // An error could happen before tty is initialized or after it has been |
856 // An error could happen before tty is initialized or after it has been |
906 first_error->_verbose = true; |
956 first_error->_verbose = true; |
907 |
957 |
908 // see if log file is already open |
958 // see if log file is already open |
909 if (!log.is_open()) { |
959 if (!log.is_open()) { |
910 // open log file |
960 // open log file |
911 int fd = -1; |
961 int fd = prepare_log_file(ErrorFile, "hs_err_pid%p.log", buffer, sizeof(buffer)); |
912 |
|
913 if (ErrorFile != NULL) { |
|
914 bool copy_ok = |
|
915 Arguments::copy_expand_pid(ErrorFile, strlen(ErrorFile), buffer, sizeof(buffer)); |
|
916 if (copy_ok) { |
|
917 fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666); |
|
918 } |
|
919 } |
|
920 |
|
921 if (fd == -1) { |
|
922 const char *cwd = os::get_current_directory(buffer, sizeof(buffer)); |
|
923 size_t len = strlen(cwd); |
|
924 // either user didn't specify, or the user's location failed, |
|
925 // so use the default name in the current directory |
|
926 jio_snprintf(&buffer[len], sizeof(buffer)-len, "%shs_err_pid%u.log", |
|
927 os::file_separator(), os::current_process_id()); |
|
928 fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666); |
|
929 } |
|
930 |
|
931 if (fd == -1) { |
|
932 const char * tmpdir = os::get_temp_directory(); |
|
933 // try temp directory if it exists. |
|
934 if (tmpdir != NULL && tmpdir[0] != '\0') { |
|
935 jio_snprintf(buffer, sizeof(buffer), "%s%shs_err_pid%u.log", |
|
936 tmpdir, os::file_separator(), os::current_process_id()); |
|
937 fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666); |
|
938 } |
|
939 } |
|
940 |
|
941 if (fd != -1) { |
962 if (fd != -1) { |
942 out.print_raw("# An error report file with more information is saved as:\n# "); |
963 out.print_raw("# An error report file with more information is saved as:\n# "); |
943 out.print_raw_cr(buffer); |
964 out.print_raw_cr(buffer); |
944 os::set_error_file(buffer); |
965 os::set_error_file(buffer); |
945 |
966 |
959 first_error->_current_step_info = ""; // reset current_step string |
980 first_error->_current_step_info = ""; // reset current_step string |
960 |
981 |
961 // Run error reporting to determine whether or not to report the crash. |
982 // Run error reporting to determine whether or not to report the crash. |
962 if (!transmit_report_done && should_report_bug(first_error->_id)) { |
983 if (!transmit_report_done && should_report_bug(first_error->_id)) { |
963 transmit_report_done = true; |
984 transmit_report_done = true; |
964 FILE* hs_err = ::fdopen(log.fd(), "r"); |
985 FILE* hs_err = os::open(log.fd(), "r"); |
965 if (NULL != hs_err) { |
986 if (NULL != hs_err) { |
966 ErrorReporter er; |
987 ErrorReporter er; |
967 er.call(hs_err, buffer, O_BUFLEN); |
988 er.call(hs_err, buffer, O_BUFLEN); |
968 } |
989 } |
969 } |
990 } |
1009 static bool skip_replay = false; |
1030 static bool skip_replay = false; |
1010 if (DumpReplayDataOnError && _thread && _thread->is_Compiler_thread() && !skip_replay) { |
1031 if (DumpReplayDataOnError && _thread && _thread->is_Compiler_thread() && !skip_replay) { |
1011 skip_replay = true; |
1032 skip_replay = true; |
1012 ciEnv* env = ciEnv::current(); |
1033 ciEnv* env = ciEnv::current(); |
1013 if (env != NULL) { |
1034 if (env != NULL) { |
1014 env->dump_replay_data(); |
1035 int fd = prepare_log_file(ReplayDataFile, "replay_pid%p.log", buffer, sizeof(buffer)); |
|
1036 if (fd != -1) { |
|
1037 FILE* replay_data_file = os::open(fd, "w"); |
|
1038 if (replay_data_file != NULL) { |
|
1039 fileStream replay_data_stream(replay_data_file, /*need_close=*/true); |
|
1040 env->dump_replay_data(&replay_data_stream); |
|
1041 out.print_raw("#\n# Compiler replay data is saved as:\n# "); |
|
1042 out.print_raw_cr(buffer); |
|
1043 } else { |
|
1044 out.print_raw("#\n# Can't open file to dump replay data. Error: "); |
|
1045 out.print_raw_cr(strerror(os::get_last_error())); |
|
1046 } |
|
1047 } |
1015 } |
1048 } |
1016 } |
1049 } |
1017 |
1050 |
1018 static bool skip_bug_url = !should_report_bug(first_error->_id); |
1051 static bool skip_bug_url = !should_report_bug(first_error->_id); |
1019 if (!skip_bug_url) { |
1052 if (!skip_bug_url) { |