Mercurial > hg > release > icedtea7-forest-2.6 > hotspot
changeset 6694:0553e00f9404
6424123, PR3702: JVM crashes on failed 'strdup' call
Summary: Calling os::malloc()/os::strdup() and new os::strdup_check_oom() instead of ::malloc()/::strdup() for native memory tracking purpose
Reviewed-by: coleenp, ctornqvi, kvn
line wrap: on
line diff
--- a/src/cpu/ppc/vm/vm_version_ppc.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/cpu/ppc/vm/vm_version_ppc.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -28,6 +28,7 @@ #include "macroAssembler_ppc.inline.hpp" #include "memory/resourceArea.hpp" #include "runtime/java.hpp" +#include "runtime/os.hpp" #include "runtime/stubCodeGenerator.hpp" #include "utilities/defaultStream.hpp" #include "vm_version_ppc.hpp" @@ -110,7 +111,7 @@ (has_vand() ? " vand" : "") // Make sure number of %s matches num_features! ); - _features_str = strdup(buf); + _features_str = os::strdup(buf); NOT_PRODUCT(if (Verbose) print_features();); // PPC64 supports 8-byte compare-exchange operations (see
--- a/src/cpu/sparc/vm/vm_version_sparc.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/cpu/sparc/vm/vm_version_sparc.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -26,6 +26,7 @@ #include "assembler_sparc.inline.hpp" #include "memory/resourceArea.hpp" #include "runtime/java.hpp" +#include "runtime/os.hpp" #include "runtime/stubCodeGenerator.hpp" #include "vm_version_sparc.hpp" #ifdef TARGET_OS_FAMILY_linux @@ -261,7 +262,7 @@ (!has_hardware_fsmuld() ? ", no-fsmuld" : "")); // buf is started with ", " or is empty - _features_str = strdup(strlen(buf) > 2 ? buf + 2 : buf); + _features_str = os::strdup(strlen(buf) > 2 ? buf + 2 : buf); // UseVIS is set to the smallest of what hardware supports and what // the command line requires. I.e., you cannot set UseVIS to 3 on
--- a/src/cpu/x86/vm/vm_version_x86.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/cpu/x86/vm/vm_version_x86.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -26,6 +26,7 @@ #include "assembler_x86.inline.hpp" #include "memory/resourceArea.hpp" #include "runtime/java.hpp" +#include "runtime/os.hpp" #include "runtime/stubCodeGenerator.hpp" #include "vm_version_x86.hpp" #ifdef TARGET_OS_FAMILY_linux @@ -454,7 +455,7 @@ (supports_tsc() ? ", tsc": ""), (supports_tscinv_bit() ? ", tscinvbit": ""), (supports_tscinv() ? ", tscinv": "")); - _features_str = strdup(buf); + _features_str = os::strdup(buf); // UseSSE is set to the smaller of what hardware supports and what // the command line requires. I.e., you cannot set UseSSE to 2 on
--- a/src/os/aix/vm/os_aix.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/os/aix/vm/os_aix.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -55,6 +55,7 @@ #include "runtime/javaCalls.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/objectMonitor.hpp" +#include "runtime/os.hpp" #include "runtime/osThread.hpp" #include "runtime/perfMemory.hpp" #include "runtime/sharedRuntime.hpp" @@ -388,9 +389,9 @@ // default should be 4K. size_t data_page_size = SIZE_4K; { - void* p = ::malloc(SIZE_16M); + void* p = os::malloc(SIZE_16M, mtInternal); data_page_size = os::Aix::query_pagesize(p); - ::free(p); + os::free(p); } // query default shm page size (LDR_CNTRL SHMPSIZE)
--- a/src/os/aix/vm/porting_aix.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/os/aix/vm/porting_aix.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -22,6 +22,8 @@ * */ +#include "memory/allocation.inline.hpp" +#include "runtime/os.hpp" #include "loadlib_aix.hpp" #include "porting_aix.hpp" #include "utilities/debug.hpp" @@ -84,7 +86,7 @@ while (n) { node* p = n; n = n->next; - free(p->v); + os::free(p->v); delete p; } } @@ -96,7 +98,7 @@ } } node* p = new node; - p->v = strdup(s); + p->v = os::strdup_check_oom(s); p->next = first; first = p; return p->v;
--- a/src/os/windows/vm/perfMemory_windows.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/os/windows/vm/perfMemory_windows.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -29,6 +29,7 @@ #include "oops/oop.inline.hpp" #include "os_windows.inline.hpp" #include "runtime/handles.inline.hpp" +#include "runtime/os.hpp" #include "runtime/perfMemory.hpp" #include "services/memTracker.hpp" #include "utilities/exceptions.hpp" @@ -1388,7 +1389,7 @@ // the file has been successfully created and the file mapping // object has been created. sharedmem_fileHandle = fh; - sharedmem_fileName = strdup(filename); + sharedmem_fileName = os::strdup(filename); return fmh; }
--- a/src/share/vm/c1/c1_LIRAssembler.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/share/vm/c1/c1_LIRAssembler.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -30,6 +30,7 @@ #include "c1/c1_MacroAssembler.hpp" #include "c1/c1_ValueStack.hpp" #include "ci/ciInstance.hpp" +#include "runtime/os.hpp" #ifdef TARGET_ARCH_x86 # include "nativeInst_x86.hpp" # include "vmreg_x86.inline.hpp" @@ -860,7 +861,7 @@ stringStream st; st.print("bad oop %s at %d", r->as_Register()->name(), _masm->offset()); #ifdef SPARC - _masm->_verify_oop(r->as_Register(), strdup(st.as_string()), __FILE__, __LINE__); + _masm->_verify_oop(r->as_Register(), os::strdup(st.as_string(), mtCompiler), __FILE__, __LINE__); #else _masm->verify_oop(r->as_Register()); #endif
--- a/src/share/vm/classfile/classLoader.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/share/vm/classfile/classLoader.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -288,13 +288,17 @@ } LazyClassPathEntry::LazyClassPathEntry(char* path, const struct stat* st) : ClassPathEntry() { - _path = strdup(path); + _path = os::strdup_check_oom(path); _st = *st; _meta_index = NULL; _resolved_entry = NULL; _has_error = false; } +LazyClassPathEntry::~LazyClassPathEntry() { + os::free((void*) _path); +} + bool LazyClassPathEntry::is_jar_file() { return ((_st.st_mode & S_IFREG) == S_IFREG); } @@ -431,7 +435,7 @@ default: { if (!skipCurrentJar && cur_entry != NULL) { - char* new_name = strdup(package_name); + char* new_name = os::strdup_check_oom(package_name); boot_class_path_packages.append(new_name); } }
--- a/src/share/vm/classfile/classLoader.hpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/share/vm/classfile/classLoader.hpp Wed Feb 20 02:15:29 2019 +0000 @@ -132,6 +132,8 @@ bool is_jar_file(); const char* name() { return _path; } LazyClassPathEntry(char* path, const struct stat* st); + virtual ~LazyClassPathEntry(); + ClassFileStream* open_stream(const char* name, TRAPS); void set_meta_index(MetaIndex* meta_index) { _meta_index = meta_index; } virtual bool is_lazy();
--- a/src/share/vm/compiler/compilerOracle.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/share/vm/compiler/compilerOracle.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -33,6 +33,7 @@ #include "oops/symbol.hpp" #include "runtime/handles.inline.hpp" #include "runtime/jniHandles.hpp" +#include "runtime/os.hpp" class MethodMatcher : public CHeapObj<mtCompiler> { public: @@ -224,7 +225,7 @@ const T value, MethodMatcher* next) : MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next), _type(get_type_for<T>()), _value(copy_value<T>(value)) { - _option = strdup(opt); + _option = os::strdup_check_oom(opt); } ~TypedMethodOptionMatcher() {
--- a/src/share/vm/opto/runtime.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/share/vm/opto/runtime.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -1331,9 +1331,9 @@ } NamedCounter* c; if (tag == NamedCounter::BiasedLockingCounter) { - c = new BiasedLockingNamedCounter(strdup(st.as_string())); + c = new BiasedLockingNamedCounter(st.as_string()); } else { - c = new NamedCounter(strdup(st.as_string()), tag); + c = new NamedCounter(st.as_string(), tag); } // atomically add the new counter to the head of the list. We only
--- a/src/share/vm/opto/runtime.hpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/share/vm/opto/runtime.hpp Wed Feb 20 02:15:29 2019 +0000 @@ -72,11 +72,17 @@ public: NamedCounter(const char *n, CounterTag tag = NoTag): - _name(n), + _name(n == NULL ? NULL : os::strdup(n)), _count(0), _next(NULL), _tag(tag) {} + ~NamedCounter() { + if (_name != NULL) { + os::free((void*)_name); + } + } + const char * name() const { return _name; } int count() const { return _count; } address addr() { return (address)&_count; }
--- a/src/share/vm/runtime/arguments.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/share/vm/runtime/arguments.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -792,7 +792,7 @@ } else { *bldarray = REALLOC_C_HEAP_ARRAY(char*, *bldarray, *count, mtInternal); } - (*bldarray)[index] = strdup(arg); + (*bldarray)[index] = os::strdup_check_oom(arg); } void Arguments::build_jvm_args(const char* arg) { @@ -1810,7 +1810,7 @@ } void Arguments::process_java_launcher_argument(const char* launcher, void* extra_info) { - _sun_java_launcher = strdup(launcher); + _sun_java_launcher = os::strdup_check_oom(launcher); if (strcmp("gamma", _sun_java_launcher) == 0) { _created_by_gamma_launcher = true; } @@ -2703,7 +2703,7 @@ // Redirect GC output to the file. -Xloggc:<filename> // ostream_init_log(), when called will use this filename // to initialize a fileStream. - _gc_log_filename = strdup(tail); + _gc_log_filename = os::strdup_check_oom(tail); if (!is_filename_valid(_gc_log_filename)) { jio_fprintf(defaultStream::output_stream(), "Invalid file name for use with -Xloggc: Filename can only contain the "
--- a/src/share/vm/runtime/fprofiler.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/share/vm/runtime/fprofiler.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -618,10 +618,16 @@ } vmNode(const char* name, const TickPosition where) : ProfilerNode() { - _name = name; + _name = os::strdup(name); update(where); } + ~vmNode() { + if (_name != NULL) { + os::free((void*)_name); + } + } + const char *name() const { return _name; } bool is_compiled() const { return true; } @@ -773,7 +779,7 @@ assert(index >= 0, "Must be positive"); // Note that we call strdup below since the symbol may be resource allocated if (!table[index]) { - table[index] = new (this) vmNode(os::strdup(name), where); + table[index] = new (this) vmNode(name, where); } else { ProfilerNode* prev = table[index]; for(ProfilerNode* node = prev; node; node = node->next()) { @@ -783,7 +789,7 @@ } prev = node; } - prev->set_next(new (this) vmNode(os::strdup(name), where)); + prev->set_next(new (this) vmNode(name, where)); } }
--- a/src/share/vm/runtime/os.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/share/vm/runtime/os.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -454,6 +454,13 @@ } +char* os::strdup_check_oom(const char* str, MEMFLAGS flags) { + char* p = os::strdup(str, flags); + if (p == NULL) { + vm_exit_out_of_memory(strlen(str) + 1, OOM_MALLOC_ERROR, "os::strdup_check_oom"); + } + return p; +} #ifdef ASSERT #define space_before (MallocCushion + sizeof(double)) @@ -544,7 +551,6 @@ } } - void report_heap_error(void* memblock, void* bad, const char* where) { tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees); tty->print_cr("## memory stomp: byte at " PTR_FORMAT " %s object " PTR_FORMAT, bad, where, memblock);
--- a/src/share/vm/runtime/os.hpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/share/vm/runtime/os.hpp Wed Feb 20 02:15:29 2019 +0000 @@ -650,6 +650,8 @@ static void free (void *memblock, MEMFLAGS flags = mtNone); static bool check_heap(bool force = false); // verify C heap integrity static char* strdup(const char *, MEMFLAGS flags = mtInternal); // Like strdup + // Like strdup, but exit VM when strdup() returns NULL + static char* strdup_check_oom(const char*, MEMFLAGS flags = mtInternal); #ifndef PRODUCT static julong num_mallocs; // # of calls to malloc/realloc
--- a/src/share/vm/runtime/vmStructs.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/share/vm/runtime/vmStructs.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -51,6 +51,7 @@ #include "interpreter/bytecodeInterpreter.hpp" #include "interpreter/bytecodes.hpp" #include "interpreter/interpreter.hpp" +#include "memory/allocation.inline.hpp" #include "memory/cardTableRS.hpp" #include "memory/compactPermGen.hpp" #include "memory/defNewGeneration.hpp" @@ -102,6 +103,7 @@ #include "runtime/globals.hpp" #include "runtime/java.hpp" #include "runtime/javaCalls.hpp" +#include "runtime/os.hpp" #include "runtime/perfMemory.hpp" #include "runtime/serviceThread.hpp" #include "runtime/sharedRuntime.hpp" @@ -3226,14 +3228,14 @@ } } if (strstr(typeName, " const") == typeName + len - 6) { - char * s = strdup(typeName); + char * s = os::strdup_check_oom(typeName); s[len - 6] = '\0'; // tty->print_cr("checking \"%s\" for \"%s\"", s, typeName); if (recursiveFindType(origtypes, s, true) == 1) { - free(s); + os::free(s); return 1; } - free(s); + os::free(s); } if (!isRecurse) { tty->print_cr("type \"%s\" not found", typeName);
--- a/src/share/vm/services/management.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/share/vm/services/management.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -1876,7 +1876,7 @@ ResourceMark rm(THREAD); // thread->name() uses ResourceArea assert(thread->name() != NULL, "All threads should have a name"); - _names_chars[_count] = strdup(thread->name()); + _names_chars[_count] = os::strdup(thread->name()); _times->long_at_put(_count, os::is_thread_cpu_time_supported() ? os::thread_cpu_time(thread) : -1); _count++; @@ -1894,7 +1894,7 @@ ThreadTimesClosure::~ThreadTimesClosure() { for (int i = 0; i < _count; i++) { - free(_names_chars[i]); + os::free(_names_chars[i]); } FREE_C_HEAP_ARRAY(char *, _names_chars, mtInternal); }
--- a/src/share/vm/shark/sharkBuilder.cpp Wed Feb 20 01:05:45 2019 +0000 +++ b/src/share/vm/shark/sharkBuilder.cpp Wed Feb 20 02:15:29 2019 +0000 @@ -503,7 +503,7 @@ const char *name; if (value->hasName()) // XXX this leaks, but it's only debug code - name = strdup(value->getName().str().c_str()); + name = os::strdup(value->getName().str().c_str()); else name = "unnamed_value";