comparison src/share/vm/utilities/vmError.cpp @ 2199:d8a72fbc4be7

7003401: Implement VM error-reporting functionality on erroneous termination Summary: Add support for distribution-specific error reporting Reviewed-by: coleenp, phh, jcoomes, ohair
author kamg
date Tue, 08 Feb 2011 17:20:45 -0500
parents 34d64ad817f4
children 63d374c54045
comparison
equal deleted inserted replaced
2197:5e139f767ddb 2199:d8a72fbc4be7
33 #include "runtime/vmThread.hpp" 33 #include "runtime/vmThread.hpp"
34 #include "runtime/vm_operations.hpp" 34 #include "runtime/vm_operations.hpp"
35 #include "utilities/debug.hpp" 35 #include "utilities/debug.hpp"
36 #include "utilities/decoder.hpp" 36 #include "utilities/decoder.hpp"
37 #include "utilities/defaultStream.hpp" 37 #include "utilities/defaultStream.hpp"
38 #include "utilities/errorReporter.hpp"
38 #include "utilities/top.hpp" 39 #include "utilities/top.hpp"
39 #include "utilities/vmError.hpp" 40 #include "utilities/vmError.hpp"
40 41
41 // List of environment variables that should be reported in error log file. 42 // List of environment variables that should be reported in error log file.
42 const char *env_list[] = { 43 const char *env_list[] = {
767 768
768 // We will first print a brief message to standard out (verbose = false), 769 // We will first print a brief message to standard out (verbose = false),
769 // then save detailed information in log file (verbose = true). 770 // then save detailed information in log file (verbose = true).
770 static bool out_done = false; // done printing to standard out 771 static bool out_done = false; // done printing to standard out
771 static bool log_done = false; // done saving error log 772 static bool log_done = false; // done saving error log
773 static bool transmit_report_done = false; // done error reporting
772 static fdStream log; // error log 774 static fdStream log; // error log
773 775
774 if (SuppressFatalErrorMessage) { 776 if (SuppressFatalErrorMessage) {
775 os::abort(); 777 os::abort();
776 } 778 }
857 859
858 if (ErrorFile != NULL) { 860 if (ErrorFile != NULL) {
859 bool copy_ok = 861 bool copy_ok =
860 Arguments::copy_expand_pid(ErrorFile, strlen(ErrorFile), buffer, sizeof(buffer)); 862 Arguments::copy_expand_pid(ErrorFile, strlen(ErrorFile), buffer, sizeof(buffer));
861 if (copy_ok) { 863 if (copy_ok) {
862 fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, 0666); 864 fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
863 } 865 }
864 } 866 }
865 867
866 if (fd == -1) { 868 if (fd == -1) {
867 const char *cwd = os::get_current_directory(buffer, sizeof(buffer)); 869 const char *cwd = os::get_current_directory(buffer, sizeof(buffer));
868 size_t len = strlen(cwd); 870 size_t len = strlen(cwd);
869 // either user didn't specify, or the user's location failed, 871 // either user didn't specify, or the user's location failed,
870 // so use the default name in the current directory 872 // so use the default name in the current directory
871 jio_snprintf(&buffer[len], sizeof(buffer)-len, "%shs_err_pid%u.log", 873 jio_snprintf(&buffer[len], sizeof(buffer)-len, "%shs_err_pid%u.log",
872 os::file_separator(), os::current_process_id()); 874 os::file_separator(), os::current_process_id());
873 fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, 0666); 875 fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
874 } 876 }
875 877
876 if (fd == -1) { 878 if (fd == -1) {
877 const char * tmpdir = os::get_temp_directory(); 879 const char * tmpdir = os::get_temp_directory();
878 // try temp directory if it exists. 880 // try temp directory if it exists.
879 if (tmpdir != NULL && tmpdir[0] != '\0') { 881 if (tmpdir != NULL && tmpdir[0] != '\0') {
880 jio_snprintf(buffer, sizeof(buffer), "%s%shs_err_pid%u.log", 882 jio_snprintf(buffer, sizeof(buffer), "%s%shs_err_pid%u.log",
881 tmpdir, os::file_separator(), os::current_process_id()); 883 tmpdir, os::file_separator(), os::current_process_id());
882 fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, 0666); 884 fd = open(buffer, O_RDWR | O_CREAT | O_TRUNC, 0666);
883 } 885 }
884 } 886 }
885 887
886 if (fd != -1) { 888 if (fd != -1) {
887 out.print_raw("# An error report file with more information is saved as:\n# "); 889 out.print_raw("# An error report file with more information is saved as:\n# ");
890 892
891 log.set_fd(fd); 893 log.set_fd(fd);
892 } else { 894 } else {
893 out.print_raw_cr("# Can not save log file, dump to screen.."); 895 out.print_raw_cr("# Can not save log file, dump to screen..");
894 log.set_fd(defaultStream::output_fd()); 896 log.set_fd(defaultStream::output_fd());
897 /* Error reporting currently needs dumpfile.
898 * Maybe implement direct streaming in the future.*/
899 transmit_report_done = true;
895 } 900 }
896 } 901 }
897 902
898 staticBufferStream sbs(buffer, O_BUFLEN, &log); 903 staticBufferStream sbs(buffer, O_BUFLEN, &log);
899 first_error->report(&sbs); 904 first_error->report(&sbs);
900 first_error->_current_step = 0; // reset current_step 905 first_error->_current_step = 0; // reset current_step
901 first_error->_current_step_info = ""; // reset current_step string 906 first_error->_current_step_info = ""; // reset current_step string
907
908 // Run error reporting to determine whether or not to report the crash.
909 if (!transmit_report_done && should_report_bug(first_error->_id)) {
910 transmit_report_done = true;
911 FILE* hs_err = ::fdopen(log.fd(), "r");
912 if (NULL != hs_err) {
913 ErrorReporter er;
914 er.call(hs_err, buffer, O_BUFLEN);
915 }
916 }
902 917
903 if (log.fd() != defaultStream::output_fd()) { 918 if (log.fd() != defaultStream::output_fd()) {
904 close(log.fd()); 919 close(log.fd());
905 } 920 }
906 921