490 |
493 |
491 #ifndef PRODUCT |
494 #ifndef PRODUCT |
492 void test_loggc_filename() { |
495 void test_loggc_filename() { |
493 int pid; |
496 int pid; |
494 char tms[32]; |
497 char tms[32]; |
495 char i_result[FILENAMEBUFLEN]; |
498 char i_result[JVM_MAXPATHLEN]; |
496 const char* o_result; |
499 const char* o_result; |
497 get_datetime_string(tms, sizeof(tms)); |
500 get_datetime_string(tms, sizeof(tms)); |
498 pid = os::current_process_id(); |
501 pid = os::current_process_id(); |
499 |
502 |
500 // test.log |
503 // test.log |
501 jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test.log", tms); |
504 jio_snprintf(i_result, JVM_MAXPATHLEN, "test.log", tms); |
502 o_result = make_log_name_internal("test.log", NULL, pid, tms); |
505 o_result = make_log_name_internal("test.log", NULL, pid, tms); |
503 assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test.log\", NULL)"); |
506 assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test.log\", NULL)"); |
504 FREE_C_HEAP_ARRAY(char, o_result, mtInternal); |
507 FREE_C_HEAP_ARRAY(char, o_result, mtInternal); |
505 |
508 |
506 // test-%t-%p.log |
509 // test-%t-%p.log |
507 jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%s-pid%u.log", tms, pid); |
510 jio_snprintf(i_result, JVM_MAXPATHLEN, "test-%s-pid%u.log", tms, pid); |
508 o_result = make_log_name_internal("test-%t-%p.log", NULL, pid, tms); |
511 o_result = make_log_name_internal("test-%t-%p.log", NULL, pid, tms); |
509 assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t-%%p.log\", NULL)"); |
512 assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t-%%p.log\", NULL)"); |
510 FREE_C_HEAP_ARRAY(char, o_result, mtInternal); |
513 FREE_C_HEAP_ARRAY(char, o_result, mtInternal); |
511 |
514 |
512 // test-%t%p.log |
515 // test-%t%p.log |
513 jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "test-%spid%u.log", tms, pid); |
516 jio_snprintf(i_result, JVM_MAXPATHLEN, "test-%spid%u.log", tms, pid); |
514 o_result = make_log_name_internal("test-%t%p.log", NULL, pid, tms); |
517 o_result = make_log_name_internal("test-%t%p.log", NULL, pid, tms); |
515 assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t%%p.log\", NULL)"); |
518 assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"test-%%t%%p.log\", NULL)"); |
516 FREE_C_HEAP_ARRAY(char, o_result, mtInternal); |
519 FREE_C_HEAP_ARRAY(char, o_result, mtInternal); |
517 |
520 |
518 // %p%t.log |
521 // %p%t.log |
519 jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u%s.log", pid, tms); |
522 jio_snprintf(i_result, JVM_MAXPATHLEN, "pid%u%s.log", pid, tms); |
520 o_result = make_log_name_internal("%p%t.log", NULL, pid, tms); |
523 o_result = make_log_name_internal("%p%t.log", NULL, pid, tms); |
521 assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p%%t.log\", NULL)"); |
524 assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p%%t.log\", NULL)"); |
522 FREE_C_HEAP_ARRAY(char, o_result, mtInternal); |
525 FREE_C_HEAP_ARRAY(char, o_result, mtInternal); |
523 |
526 |
524 // %p-test.log |
527 // %p-test.log |
525 jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "pid%u-test.log", pid); |
528 jio_snprintf(i_result, JVM_MAXPATHLEN, "pid%u-test.log", pid); |
526 o_result = make_log_name_internal("%p-test.log", NULL, pid, tms); |
529 o_result = make_log_name_internal("%p-test.log", NULL, pid, tms); |
527 assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p-test.log\", NULL)"); |
530 assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%p-test.log\", NULL)"); |
528 FREE_C_HEAP_ARRAY(char, o_result, mtInternal); |
531 FREE_C_HEAP_ARRAY(char, o_result, mtInternal); |
529 |
532 |
530 // %t.log |
533 // %t.log |
531 jio_snprintf(i_result, sizeof(char)*FILENAMEBUFLEN, "%s.log", tms); |
534 jio_snprintf(i_result, JVM_MAXPATHLEN, "%s.log", tms); |
532 o_result = make_log_name_internal("%t.log", NULL, pid, tms); |
535 o_result = make_log_name_internal("%t.log", NULL, pid, tms); |
533 assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%t.log\", NULL)"); |
536 assert(strcmp(i_result, o_result) == 0, "failed on testing make_log_name(\"%%t.log\", NULL)"); |
534 FREE_C_HEAP_ARRAY(char, o_result, mtInternal); |
537 FREE_C_HEAP_ARRAY(char, o_result, mtInternal); |
|
538 |
|
539 { |
|
540 // longest filename |
|
541 char longest_name[JVM_MAXPATHLEN]; |
|
542 memset(longest_name, 'a', sizeof(longest_name)); |
|
543 longest_name[JVM_MAXPATHLEN - 1] = '\0'; |
|
544 o_result = make_log_name_internal((const char*)&longest_name, NULL, pid, tms); |
|
545 assert(strcmp(longest_name, o_result) == 0, err_msg("longest name does not match. expected '%s' but got '%s'", longest_name, o_result)); |
|
546 FREE_C_HEAP_ARRAY(char, o_result, mtInternal); |
|
547 } |
|
548 |
|
549 { |
|
550 // too long file name |
|
551 char too_long_name[JVM_MAXPATHLEN + 100]; |
|
552 int too_long_length = sizeof(too_long_name); |
|
553 memset(too_long_name, 'a', too_long_length); |
|
554 too_long_name[too_long_length - 1] = '\0'; |
|
555 o_result = make_log_name_internal((const char*)&too_long_name, NULL, pid, tms); |
|
556 assert(o_result == NULL, err_msg("Too long file name should return NULL, but got '%s'", o_result)); |
|
557 } |
|
558 |
|
559 { |
|
560 // too long with timestamp |
|
561 char longest_name[JVM_MAXPATHLEN]; |
|
562 memset(longest_name, 'a', JVM_MAXPATHLEN); |
|
563 longest_name[JVM_MAXPATHLEN - 3] = '%'; |
|
564 longest_name[JVM_MAXPATHLEN - 2] = 't'; |
|
565 longest_name[JVM_MAXPATHLEN - 1] = '\0'; |
|
566 o_result = make_log_name_internal((const char*)&longest_name, NULL, pid, tms); |
|
567 assert(o_result == NULL, err_msg("Too long file name after timestamp expansion should return NULL, but got '%s'", o_result)); |
|
568 } |
|
569 |
|
570 { |
|
571 // too long with pid |
|
572 char longest_name[JVM_MAXPATHLEN]; |
|
573 memset(longest_name, 'a', JVM_MAXPATHLEN); |
|
574 longest_name[JVM_MAXPATHLEN - 3] = '%'; |
|
575 longest_name[JVM_MAXPATHLEN - 2] = 'p'; |
|
576 longest_name[JVM_MAXPATHLEN - 1] = '\0'; |
|
577 o_result = make_log_name_internal((const char*)&longest_name, NULL, pid, tms); |
|
578 assert(o_result == NULL, err_msg("Too long file name after pid expansion should return NULL, but got '%s'", o_result)); |
|
579 } |
535 } |
580 } |
536 #endif // PRODUCT |
581 #endif // PRODUCT |
537 |
582 |
538 fileStream::fileStream(const char* file_name) { |
583 fileStream::fileStream(const char* file_name) { |
539 _file = fopen(file_name, "w"); |
584 _file = fopen(file_name, "w"); |
714 // rotate file in names extended_filename.0, extended_filename.1, ..., |
766 // rotate file in names extended_filename.0, extended_filename.1, ..., |
715 // extended_filename.<NumberOfGCLogFiles - 1>. Current rotation file name will |
767 // extended_filename.<NumberOfGCLogFiles - 1>. Current rotation file name will |
716 // have a form of extended_filename.<i>.current where i is the current rotation |
768 // have a form of extended_filename.<i>.current where i is the current rotation |
717 // file number. After it reaches max file size, the file will be saved and renamed |
769 // file number. After it reaches max file size, the file will be saved and renamed |
718 // with .current removed from its tail. |
770 // with .current removed from its tail. |
719 size_t filename_len = strlen(_file_name); |
|
720 if (_file != NULL) { |
771 if (_file != NULL) { |
721 jio_snprintf(renamed_file_name, filename_len + EXTRACHARLEN, "%s.%d", |
772 jio_snprintf(renamed_file_name, JVM_MAXPATHLEN, "%s.%d", |
722 _file_name, _cur_file_num); |
773 _file_name, _cur_file_num); |
723 jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX, |
774 int result = jio_snprintf(current_file_name, JVM_MAXPATHLEN, |
724 _file_name, _cur_file_num); |
775 "%s.%d" CURRENTAPPX, _file_name, _cur_file_num); |
|
776 if (result >= JVM_MAXPATHLEN) { |
|
777 warning("Cannot create new log file name: %s: file name is too long.\n", current_file_name); |
|
778 return; |
|
779 } |
725 |
780 |
726 const char* msg = force ? "GC log rotation request has been received." |
781 const char* msg = force ? "GC log rotation request has been received." |
727 : "GC log file has reached the maximum size."; |
782 : "GC log file has reached the maximum size."; |
728 jio_snprintf(time_msg, sizeof(time_msg), "%s %s Saved as %s\n", |
783 jio_snprintf(time_msg, sizeof(time_msg), "%s %s Saved as %s\n", |
729 os::local_time_string((char *)time_str, sizeof(time_str)), |
784 os::local_time_string((char *)time_str, sizeof(time_str)), |
758 } |
813 } |
759 } |
814 } |
760 |
815 |
761 _cur_file_num++; |
816 _cur_file_num++; |
762 if (_cur_file_num > NumberOfGCLogFiles - 1) _cur_file_num = 0; |
817 if (_cur_file_num > NumberOfGCLogFiles - 1) _cur_file_num = 0; |
763 jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX, |
818 int result = jio_snprintf(current_file_name, JVM_MAXPATHLEN, "%s.%d" CURRENTAPPX, |
764 _file_name, _cur_file_num); |
819 _file_name, _cur_file_num); |
|
820 if (result >= JVM_MAXPATHLEN) { |
|
821 warning("Cannot create new log file name: %s: file name is too long.\n", current_file_name); |
|
822 return; |
|
823 } |
|
824 |
765 _file = fopen(current_file_name, "w"); |
825 _file = fopen(current_file_name, "w"); |
766 |
826 |
767 if (_file != NULL) { |
827 if (_file != NULL) { |
768 _bytes_written = 0L; |
828 _bytes_written = 0L; |
769 _need_close = true; |
829 _need_close = true; |
770 // reuse current_file_name for time_msg |
830 // reuse current_file_name for time_msg |
771 jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, |
831 jio_snprintf(current_file_name, JVM_MAXPATHLEN, |
772 "%s.%d", _file_name, _cur_file_num); |
832 "%s.%d", _file_name, _cur_file_num); |
773 jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file created %s\n", |
833 jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file created %s\n", |
774 os::local_time_string((char *)time_str, sizeof(time_str)), |
834 os::local_time_string((char *)time_str, sizeof(time_str)), current_file_name); |
775 current_file_name); |
|
776 write(time_msg, strlen(time_msg)); |
835 write(time_msg, strlen(time_msg)); |
777 |
836 |
778 if (out != NULL) { |
837 if (out != NULL) { |
779 out->print("%s", time_msg); |
838 out->print("%s", time_msg); |
780 } |
839 } |
818 // if a VM error has been reported. |
877 // if a VM error has been reported. |
819 if (!_inited && !is_error_reported()) init(); |
878 if (!_inited && !is_error_reported()) init(); |
820 return _log_file != NULL; |
879 return _log_file != NULL; |
821 } |
880 } |
822 |
881 |
|
882 fileStream* defaultStream::open_file(const char* log_name) { |
|
883 const char* try_name = make_log_name(log_name, NULL); |
|
884 if (try_name == NULL) { |
|
885 warning("Cannot open file %s: file name is too long.\n", log_name); |
|
886 return NULL; |
|
887 } |
|
888 |
|
889 fileStream* file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name); |
|
890 FREE_C_HEAP_ARRAY(char, try_name, mtInternal); |
|
891 if (file->is_open()) { |
|
892 return file; |
|
893 } |
|
894 |
|
895 // Try again to open the file in the temp directory. |
|
896 delete file; |
|
897 char warnbuf[O_BUFLEN*2]; |
|
898 jio_snprintf(warnbuf, sizeof(warnbuf), "Warning: Cannot open log file: %s\n", log_name); |
|
899 // Note: This feature is for maintainer use only. No need for L10N. |
|
900 jio_print(warnbuf); |
|
901 try_name = make_log_name(log_name, os::get_temp_directory()); |
|
902 if (try_name == NULL) { |
|
903 warning("Cannot open file %s: file name is too long for directory %s.\n", log_name, os::get_temp_directory()); |
|
904 return NULL; |
|
905 } |
|
906 |
|
907 jio_snprintf(warnbuf, sizeof(warnbuf), |
|
908 "Warning: Forcing option -XX:LogFile=%s\n", try_name); |
|
909 jio_print(warnbuf); |
|
910 |
|
911 file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name); |
|
912 FREE_C_HEAP_ARRAY(char, try_name, mtInternal); |
|
913 if (file->is_open()) { |
|
914 return file; |
|
915 } |
|
916 |
|
917 delete file; |
|
918 return NULL; |
|
919 } |
|
920 |
823 void defaultStream::init_log() { |
921 void defaultStream::init_log() { |
824 // %%% Need a MutexLocker? |
922 // %%% Need a MutexLocker? |
825 const char* log_name = LogFile != NULL ? LogFile : "hotspot_%p.log"; |
923 const char* log_name = LogFile != NULL ? LogFile : "hotspot_%p.log"; |
826 const char* try_name = make_log_name(log_name, NULL); |
924 fileStream* file = open_file(log_name); |
827 fileStream* file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name); |
925 |
828 if (!file->is_open()) { |
926 if (file != NULL) { |
829 // Try again to open the file. |
|
830 char warnbuf[O_BUFLEN*2]; |
|
831 jio_snprintf(warnbuf, sizeof(warnbuf), |
|
832 "Warning: Cannot open log file: %s\n", try_name); |
|
833 // Note: This feature is for maintainer use only. No need for L10N. |
|
834 jio_print(warnbuf); |
|
835 FREE_C_HEAP_ARRAY(char, try_name, mtInternal); |
|
836 try_name = make_log_name(log_name, os::get_temp_directory()); |
|
837 jio_snprintf(warnbuf, sizeof(warnbuf), |
|
838 "Warning: Forcing option -XX:LogFile=%s\n", try_name); |
|
839 jio_print(warnbuf); |
|
840 delete file; |
|
841 file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name); |
|
842 } |
|
843 FREE_C_HEAP_ARRAY(char, try_name, mtInternal); |
|
844 |
|
845 if (file->is_open()) { |
|
846 _log_file = file; |
927 _log_file = file; |
847 xmlStream* xs = new(ResourceObj::C_HEAP, mtInternal) xmlStream(file); |
928 _outer_xmlStream = new(ResourceObj::C_HEAP, mtInternal) xmlStream(file); |
848 _outer_xmlStream = xs; |
929 start_log(); |
|
930 } else { |
|
931 // and leave xtty as NULL |
|
932 LogVMOutput = false; |
|
933 DisplayVMOutput = true; |
|
934 LogCompilation = false; |
|
935 } |
|
936 } |
|
937 |
|
938 void defaultStream::start_log() { |
|
939 xmlStream*xs = _outer_xmlStream; |
849 if (this == tty) xtty = xs; |
940 if (this == tty) xtty = xs; |
850 // Write XML header. |
941 // Write XML header. |
851 xs->print_cr("<?xml version='1.0' encoding='UTF-8'?>"); |
942 xs->print_cr("<?xml version='1.0' encoding='UTF-8'?>"); |
852 // (For now, don't bother to issue a DTD for this private format.) |
943 // (For now, don't bother to issue a DTD for this private format.) |
853 jlong time_ms = os::javaTimeMillis() - tty->time_stamp().milliseconds(); |
944 jlong time_ms = os::javaTimeMillis() - tty->time_stamp().milliseconds(); |