|
43 | 43 | #include "oops/objArrayOop.inline.hpp" |
44 | 44 | #include "oops/oop.inline.hpp" |
45 | 45 | #include "oops/typeArrayOop.inline.hpp" |
| 46 | +#include "runtime/arguments.hpp" |
46 | 47 | #include "runtime/continuationWrapper.inline.hpp" |
47 | 48 | #include "runtime/frame.inline.hpp" |
48 | 49 | #include "runtime/handles.inline.hpp" |
@@ -2747,77 +2748,50 @@ void HeapDumper::dump_heap() { |
2747 | 2748 | void HeapDumper::dump_heap(bool oome) { |
2748 | 2749 | static char base_path[JVM_MAXPATHLEN] = {'\0'}; |
2749 | 2750 | static uint dump_file_seq = 0; |
2750 | | - char* my_path; |
| 2751 | + char my_path[JVM_MAXPATHLEN]; |
2751 | 2752 | const int max_digit_chars = 20; |
2752 | | - |
2753 | | - const char* dump_file_name = "java_pid"; |
2754 | | - const char* dump_file_ext = HeapDumpGzipLevel > 0 ? ".hprof.gz" : ".hprof"; |
| 2753 | + const char* dump_file_name = HeapDumpGzipLevel > 0 ? "java_pid%p.hprof.gz" : "java_pid%p.hprof"; |
2755 | 2754 |
|
2756 | 2755 | // The dump file defaults to java_pid<pid>.hprof in the current working |
2757 | 2756 | // directory. HeapDumpPath=<file> can be used to specify an alternative |
2758 | 2757 | // dump file name or a directory where dump file is created. |
2759 | 2758 | if (dump_file_seq == 0) { // first time in, we initialize base_path |
2760 | | - // Calculate potentially longest base path and check if we have enough |
2761 | | - // allocated statically. |
2762 | | - const size_t total_length = |
2763 | | - (HeapDumpPath == nullptr ? 0 : strlen(HeapDumpPath)) + |
2764 | | - strlen(os::file_separator()) + max_digit_chars + |
2765 | | - strlen(dump_file_name) + strlen(dump_file_ext) + 1; |
2766 | | - if (total_length > sizeof(base_path)) { |
| 2759 | + // Set base path (name or directory, default or custom, without seq no), doing %p substitution. |
| 2760 | + const char *path_src = (HeapDumpPath != nullptr && HeapDumpPath[0] != '\0') ? HeapDumpPath : dump_file_name; |
| 2761 | + if (!Arguments::copy_expand_pid(path_src, strlen(path_src), base_path, JVM_MAXPATHLEN - max_digit_chars)) { |
2767 | 2762 | warning("Cannot create heap dump file. HeapDumpPath is too long."); |
2768 | 2763 | return; |
2769 | 2764 | } |
2770 | | - |
2771 | | - bool use_default_filename = true; |
2772 | | - if (HeapDumpPath == nullptr || HeapDumpPath[0] == '\0') { |
2773 | | - // HeapDumpPath=<file> not specified |
2774 | | - } else { |
2775 | | - strcpy(base_path, HeapDumpPath); |
2776 | | - // check if the path is a directory (must exist) |
2777 | | - DIR* dir = os::opendir(base_path); |
2778 | | - if (dir == nullptr) { |
2779 | | - use_default_filename = false; |
2780 | | - } else { |
2781 | | - // HeapDumpPath specified a directory. We append a file separator |
2782 | | - // (if needed). |
2783 | | - os::closedir(dir); |
2784 | | - size_t fs_len = strlen(os::file_separator()); |
2785 | | - if (strlen(base_path) >= fs_len) { |
2786 | | - char* end = base_path; |
2787 | | - end += (strlen(base_path) - fs_len); |
2788 | | - if (strcmp(end, os::file_separator()) != 0) { |
2789 | | - strcat(base_path, os::file_separator()); |
2790 | | - } |
| 2765 | + // Check if the path is an existing directory |
| 2766 | + DIR* dir = os::opendir(base_path); |
| 2767 | + if (dir != nullptr) { |
| 2768 | + os::closedir(dir); |
| 2769 | + // Path is a directory. Append a file separator (if needed). |
| 2770 | + size_t fs_len = strlen(os::file_separator()); |
| 2771 | + if (strlen(base_path) >= fs_len) { |
| 2772 | + char* end = base_path; |
| 2773 | + end += (strlen(base_path) - fs_len); |
| 2774 | + if (strcmp(end, os::file_separator()) != 0) { |
| 2775 | + strcat(base_path, os::file_separator()); |
2791 | 2776 | } |
2792 | 2777 | } |
| 2778 | + // Then add the default name, with %p substitution. Use my_path temporarily. |
| 2779 | + if (!Arguments::copy_expand_pid(dump_file_name, strlen(dump_file_name), my_path, JVM_MAXPATHLEN - max_digit_chars)) { |
| 2780 | + warning("Cannot create heap dump file. HeapDumpPath is too long."); |
| 2781 | + return; |
| 2782 | + } |
| 2783 | + const size_t dlen = strlen(base_path); |
| 2784 | + jio_snprintf(&base_path[dlen], sizeof(base_path) - dlen, "%s", my_path); |
2793 | 2785 | } |
2794 | | - // If HeapDumpPath wasn't a file name then we append the default name |
2795 | | - if (use_default_filename) { |
2796 | | - const size_t dlen = strlen(base_path); // if heap dump dir specified |
2797 | | - jio_snprintf(&base_path[dlen], sizeof(base_path)-dlen, "%s%d%s", |
2798 | | - dump_file_name, os::current_process_id(), dump_file_ext); |
2799 | | - } |
2800 | | - const size_t len = strlen(base_path) + 1; |
2801 | | - my_path = (char*)os::malloc(len, mtInternal); |
2802 | | - if (my_path == nullptr) { |
2803 | | - warning("Cannot create heap dump file. Out of system memory."); |
2804 | | - return; |
2805 | | - } |
2806 | | - strncpy(my_path, base_path, len); |
| 2786 | + strncpy(my_path, base_path, JVM_MAXPATHLEN); |
2807 | 2787 | } else { |
2808 | 2788 | // Append a sequence number id for dumps following the first |
2809 | 2789 | const size_t len = strlen(base_path) + max_digit_chars + 2; // for '.' and \0 |
2810 | | - my_path = (char*)os::malloc(len, mtInternal); |
2811 | | - if (my_path == nullptr) { |
2812 | | - warning("Cannot create heap dump file. Out of system memory."); |
2813 | | - return; |
2814 | | - } |
2815 | 2790 | jio_snprintf(my_path, len, "%s.%d", base_path, dump_file_seq); |
2816 | 2791 | } |
2817 | 2792 | dump_file_seq++; // increment seq number for next time we dump |
2818 | 2793 |
|
2819 | 2794 | HeapDumper dumper(false /* no GC before heap dump */, |
2820 | 2795 | oome /* pass along out-of-memory-error flag */); |
2821 | 2796 | dumper.dump(my_path, tty, HeapDumpGzipLevel); |
2822 | | - os::free(my_path); |
2823 | 2797 | } |
0 commit comments