comparison src/share/vm/utilities/vmError.cpp @ 10408:836a62f43af9

Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author Doug Simon <doug.simon@oracle.com>
date Wed, 19 Jun 2013 10:45:56 +0200
parents 89e4d67fdd2a 9ce110b1d14a
children 6b0fd0964b87
comparison
equal deleted inserted replaced
10086:e0fb8a213650 10408:836a62f43af9
98 // Constructor for internal errors 98 // Constructor for internal errors
99 VMError::VMError(Thread* thread, const char* filename, int lineno, 99 VMError::VMError(Thread* thread, const char* filename, int lineno,
100 const char* message, const char * detail_msg) 100 const char* message, const char * detail_msg)
101 { 101 {
102 _thread = thread; 102 _thread = thread;
103 _id = internal_error; // Value that's not an OS exception/signal 103 _id = INTERNAL_ERROR; // Value that's not an OS exception/signal
104 _filename = filename; 104 _filename = filename;
105 _lineno = lineno; 105 _lineno = lineno;
106 _message = message; 106 _message = message;
107 _detail_msg = detail_msg; 107 _detail_msg = detail_msg;
108 108
117 _size = 0; 117 _size = 0;
118 } 118 }
119 119
120 // Constructor for OOM errors 120 // Constructor for OOM errors
121 VMError::VMError(Thread* thread, const char* filename, int lineno, size_t size, 121 VMError::VMError(Thread* thread, const char* filename, int lineno, size_t size,
122 const char* message) { 122 VMErrorType vm_err_type, const char* message) {
123 _thread = thread; 123 _thread = thread;
124 _id = oom_error; // Value that's not an OS exception/signal 124 _id = vm_err_type; // Value that's not an OS exception/signal
125 _filename = filename; 125 _filename = filename;
126 _lineno = lineno; 126 _lineno = lineno;
127 _message = message; 127 _message = message;
128 _detail_msg = NULL; 128 _detail_msg = NULL;
129 129
140 140
141 141
142 // Constructor for non-fatal errors 142 // Constructor for non-fatal errors
143 VMError::VMError(const char* message) { 143 VMError::VMError(const char* message) {
144 _thread = NULL; 144 _thread = NULL;
145 _id = internal_error; // Value that's not an OS exception/signal 145 _id = INTERNAL_ERROR; // Value that's not an OS exception/signal
146 _filename = NULL; 146 _filename = NULL;
147 _lineno = 0; 147 _lineno = 0;
148 _message = message; 148 _message = message;
149 _detail_msg = NULL; 149 _detail_msg = NULL;
150 150
349 } 349 }
350 350
351 STEP(15, "(printing type of error)") 351 STEP(15, "(printing type of error)")
352 352
353 switch(_id) { 353 switch(_id) {
354 case oom_error: 354 case OOM_MALLOC_ERROR:
355 case OOM_MMAP_ERROR:
355 if (_size) { 356 if (_size) {
356 st->print("# Native memory allocation (malloc) failed to allocate "); 357 st->print("# Native memory allocation ");
358 st->print((_id == (int)OOM_MALLOC_ERROR) ? "(malloc) failed to allocate " :
359 "(mmap) failed to map ");
357 jio_snprintf(buf, sizeof(buf), SIZE_FORMAT, _size); 360 jio_snprintf(buf, sizeof(buf), SIZE_FORMAT, _size);
358 st->print(buf); 361 st->print(buf);
359 st->print(" bytes"); 362 st->print(" bytes");
360 if (_message != NULL) { 363 if (_message != NULL) {
361 st->print(" for "); 364 st->print(" for ");
384 st->print_cr("# This output file may be truncated or incomplete."); 387 st->print_cr("# This output file may be truncated or incomplete.");
385 } else { 388 } else {
386 return; // that's enough for the screen 389 return; // that's enough for the screen
387 } 390 }
388 break; 391 break;
389 case internal_error: 392 case INTERNAL_ERROR:
390 default: 393 default:
391 break; 394 break;
392 } 395 }
393 396
394 STEP(20, "(printing exception/signal name)") 397 STEP(20, "(printing exception/signal name)")
794 } 797 }
795 798
796 VMError* volatile VMError::first_error = NULL; 799 VMError* volatile VMError::first_error = NULL;
797 volatile jlong VMError::first_error_tid = -1; 800 volatile jlong VMError::first_error_tid = -1;
798 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
799 void VMError::report_and_die() { 852 void VMError::report_and_die() {
800 // Don't allocate large buffer on stack 853 // Don't allocate large buffer on stack
801 static char buffer[O_BUFLEN]; 854 static char buffer[O_BUFLEN];
802 855
803 // 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
903 first_error->_verbose = true; 956 first_error->_verbose = true;
904 957
905 // see if log file is already open 958 // see if log file is already open
906 if (!log.is_open()) { 959 if (!log.is_open()) {
907 // open log file 960 // open log file
908 int fd = -1; 961 int fd = prepare_log_file(ErrorFile, "hs_err_pid%p.log", buffer, sizeof(buffer));
909
910 if (ErrorFile != NULL) {
911 bool copy_ok =
912 Arguments::copy_expand_pid(ErrorFile, strlen(ErrorFile), buffer, sizeof(buffer));
913 if (copy_ok) {
914 fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
915 }
916 }
917
918 if (fd == -1) {
919 const char *cwd = os::get_current_directory(buffer, sizeof(buffer));
920 size_t len = strlen(cwd);
921 // either user didn't specify, or the user's location failed,
922 // so use the default name in the current directory
923 jio_snprintf(&buffer[len], sizeof(buffer)-len, "%shs_err_pid%u.log",
924 os::file_separator(), os::current_process_id());
925 fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
926 }
927
928 if (fd == -1) {
929 const char * tmpdir = os::get_temp_directory();
930 // try temp directory if it exists.
931 if (tmpdir != NULL && tmpdir[0] != '\0') {
932 jio_snprintf(buffer, sizeof(buffer), "%s%shs_err_pid%u.log",
933 tmpdir, os::file_separator(), os::current_process_id());
934 fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
935 }
936 }
937
938 if (fd != -1) { 962 if (fd != -1) {
939 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# ");
940 out.print_raw_cr(buffer); 964 out.print_raw_cr(buffer);
941 os::set_error_file(buffer); 965 os::set_error_file(buffer);
942 966
956 first_error->_current_step_info = ""; // reset current_step string 980 first_error->_current_step_info = ""; // reset current_step string
957 981
958 // 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.
959 if (!transmit_report_done && should_report_bug(first_error->_id)) { 983 if (!transmit_report_done && should_report_bug(first_error->_id)) {
960 transmit_report_done = true; 984 transmit_report_done = true;
961 FILE* hs_err = ::fdopen(log.fd(), "r"); 985 FILE* hs_err = os::open(log.fd(), "r");
962 if (NULL != hs_err) { 986 if (NULL != hs_err) {
963 ErrorReporter er; 987 ErrorReporter er;
964 er.call(hs_err, buffer, O_BUFLEN); 988 er.call(hs_err, buffer, O_BUFLEN);
965 } 989 }
966 } 990 }
1006 static bool skip_replay = false; 1030 static bool skip_replay = false;
1007 if (DumpReplayDataOnError && _thread && _thread->is_Compiler_thread() && !skip_replay) { 1031 if (DumpReplayDataOnError && _thread && _thread->is_Compiler_thread() && !skip_replay) {
1008 skip_replay = true; 1032 skip_replay = true;
1009 ciEnv* env = ciEnv::current(); 1033 ciEnv* env = ciEnv::current();
1010 if (env != NULL) { 1034 if (env != NULL) {
1011 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 }
1012 } 1048 }
1013 } 1049 }
1014 1050
1015 static bool skip_bug_url = !should_report_bug(first_error->_id); 1051 static bool skip_bug_url = !should_report_bug(first_error->_id);
1016 if (!skip_bug_url) { 1052 if (!skip_bug_url) {