|
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