OpenJDK / jdk / jdk10
changeset 25949:34557722059b
6424123: 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/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -29,6 +29,7 @@ #include "compiler/disassembler.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" @@ -108,7 +109,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/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -26,6 +26,7 @@ #include "asm/macroAssembler.inline.hpp" #include "memory/resourceArea.hpp" #include "runtime/java.hpp" +#include "runtime/os.hpp" #include "runtime/stubCodeGenerator.hpp" #include "vm_version_sparc.hpp" @@ -249,7 +250,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); // There are three 64-bit SPARC families that do not overlap, e.g., // both is_ultra3() and is_sparc64() cannot be true at the same time.
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -27,6 +27,7 @@ #include "asm/macroAssembler.inline.hpp" #include "memory/resourceArea.hpp" #include "runtime/java.hpp" +#include "runtime/os.hpp" #include "runtime/stubCodeGenerator.hpp" #include "vm_version_x86.hpp" @@ -514,7 +515,7 @@ (supports_tscinv() ? ", tscinv": ""), (supports_bmi1() ? ", bmi1" : ""), (supports_bmi2() ? ", bmi2" : "")); - _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/hotspot/src/os/aix/vm/os_aix.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/os/aix/vm/os_aix.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -58,6 +58,7 @@ #include "runtime/mutexLocker.hpp" #include "runtime/objectMonitor.hpp" #include "runtime/orderAccess.inline.hpp" +#include "runtime/os.hpp" #include "runtime/osThread.hpp" #include "runtime/perfMemory.hpp" #include "runtime/sharedRuntime.hpp" @@ -378,10 +379,10 @@ // default should be 4K. size_t data_page_size = SIZE_4K; { - void* p = ::malloc(SIZE_16M); + void* p = os::malloc(SIZE_16M, mtInternal); guarantee(p != NULL, "malloc failed"); data_page_size = os::Aix::query_pagesize(p); - ::free(p); + os::free(p); } // query default shm page size (LDR_CNTRL SHMPSIZE)
--- a/hotspot/src/os/aix/vm/porting_aix.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/os/aix/vm/porting_aix.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -24,6 +24,8 @@ #include "asm/assembler.hpp" #include "memory/allocation.hpp" +#include "memory/allocation.inline.hpp" +#include "runtime/os.hpp" #include "loadlib_aix.hpp" #include "porting_aix.hpp" #include "utilities/debug.hpp" @@ -83,7 +85,7 @@ while (n) { node* p = n; n = n->next; - free(p->v); + os::free(p->v); delete p; } } @@ -95,7 +97,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/hotspot/src/os/windows/vm/perfMemory_windows.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/os/windows/vm/perfMemory_windows.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -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/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -23,6 +23,8 @@ */ #include "precompiled.hpp" +#include "memory/allocation.hpp" +#include "memory/allocation.inline.hpp" #include "runtime/os.hpp" #include "vm_version_sparc.hpp" @@ -48,7 +50,7 @@ // All SI defines used below must be supported. guarantee(bufsize != -1, "must be supported"); - char* buf = (char*) malloc(bufsize); + char* buf = (char*) os::malloc(bufsize, mtInternal); if (buf == NULL) return; @@ -60,7 +62,7 @@ } } - free(buf); + os::free(buf); } int VM_Version::platform_features(int features) { @@ -161,7 +163,7 @@ char tmp; size_t bufsize = sysinfo(SI_ISALIST, &tmp, 1); - char* buf = (char*) malloc(bufsize); + char* buf = (char*) os::malloc(bufsize, mtInternal); if (buf != NULL) { if (sysinfo(SI_ISALIST, buf, bufsize) == bufsize) { @@ -184,7 +186,7 @@ if (vis[3] == '2') features |= vis2_instructions_m; } } - free(buf); + os::free(buf); } } @@ -228,7 +230,7 @@ } #endif // Convert to UPPER case before compare. - char* impl = strdup(implementation); + char* impl = os::strdup_check_oom(implementation); for (int i = 0; impl[i] != 0; i++) impl[i] = (char)toupper((uint)impl[i]); @@ -252,7 +254,7 @@ implementation = "SPARC"; } } - free((void*)impl); + os::free((void*)impl); break; } } // for(
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -30,6 +30,7 @@ #include "c1/c1_MacroAssembler.hpp" #include "c1/c1_ValueStack.hpp" #include "ci/ciInstance.hpp" +#include "runtime/os.hpp" void LIR_Assembler::patching_epilog(PatchingStub* patch, LIR_PatchCode patch_code, Register obj, CodeEmitInfo* info) { // we must have enough patching space so that call can be inserted @@ -848,7 +849,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/hotspot/src/share/vm/classfile/classLoader.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/share/vm/classfile/classLoader.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -273,13 +273,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(_path); +} + bool LazyClassPathEntry::is_jar_file() { return ((_st.st_mode & S_IFREG) == S_IFREG); } @@ -416,7 +420,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); } } @@ -438,7 +442,7 @@ void ClassLoader::setup_bootstrap_search_path() { assert(_first_entry == NULL, "should not setup bootstrap class search path twice"); - char* sys_class_path = os::strdup(Arguments::get_sysclasspath()); + char* sys_class_path = os::strdup_check_oom(Arguments::get_sysclasspath()); if (TraceClassLoading && Verbose) { tty->print_cr("[Bootstrap loader class path=%s]", sys_class_path); } @@ -460,6 +464,7 @@ end++; } } + os::free(sys_class_path); } ClassPathEntry* ClassLoader::create_class_path_entry(char *path, const struct stat* st, bool lazy, TRAPS) {
--- a/hotspot/src/share/vm/classfile/classLoader.hpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/share/vm/classfile/classLoader.hpp Mon Aug 11 10:18:09 2014 -0700 @@ -128,6 +128,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/hotspot/src/share/vm/compiler/compilerOracle.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -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: @@ -175,7 +176,11 @@ Symbol* method_name, Mode method_mode, Symbol* signature, const char * opt, MethodMatcher* next): MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next) { - option = opt; + option = os::strdup_check_oom(opt); + } + + virtual ~MethodOptionMatcher() { + os::free((void*)option); } bool match(methodHandle method, const char* opt) { @@ -498,7 +503,7 @@ tty->print("CompilerOracle: %s ", command_names[command]); match->print(); } - match = add_option_string(c_name, c_match, m_name, m_match, signature, strdup(option)); + match = add_option_string(c_name, c_match, m_name, m_match, signature, option); line += bytes_read; } } else {
--- a/hotspot/src/share/vm/opto/runtime.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/share/vm/opto/runtime.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -1381,11 +1381,11 @@ } NamedCounter* c; if (tag == NamedCounter::BiasedLockingCounter) { - c = new BiasedLockingNamedCounter(strdup(st.as_string())); + c = new BiasedLockingNamedCounter(st.as_string()); } else if (tag == NamedCounter::RTMLockingCounter) { - c = new RTMLockingNamedCounter(strdup(st.as_string())); + c = new RTMLockingNamedCounter(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/hotspot/src/share/vm/opto/runtime.hpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/share/vm/opto/runtime.hpp Mon Aug 11 10:18:09 2014 -0700 @@ -75,11 +75,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/hotspot/src/share/vm/runtime/arguments.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -800,7 +800,7 @@ } else { *bldarray = REALLOC_C_HEAP_ARRAY(char*, *bldarray, new_count, mtInternal); } - (*bldarray)[*count] = strdup(arg); + (*bldarray)[*count] = os::strdup_check_oom(arg); *count = new_count; } @@ -1886,7 +1886,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); } bool Arguments::created_by_java_launcher() { @@ -2996,7 +2996,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/hotspot/src/share/vm/runtime/fprofiler.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/share/vm/runtime/fprofiler.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -629,10 +629,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; } @@ -784,7 +790,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()) { @@ -794,7 +800,7 @@ } prev = node; } - prev->set_next(new (this) vmNode(os::strdup(name), where)); + prev->set_next(new (this) vmNode(name, where)); } }
--- a/hotspot/src/share/vm/runtime/os.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/share/vm/runtime/os.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -517,6 +517,14 @@ return dup_str; } +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; +} + #define paranoid 0 /* only set to 1 if you suspect checking code has bug */
--- a/hotspot/src/share/vm/runtime/os.hpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/share/vm/runtime/os.hpp Mon Aug 11 10:18:09 2014 -0700 @@ -664,6 +664,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/hotspot/src/share/vm/runtime/vmStructs.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -52,6 +52,7 @@ #include "interpreter/bytecodes.hpp" #include "interpreter/interpreter.hpp" #include "memory/allocation.hpp" +#include "memory/allocation.inline.hpp" #include "memory/cardTableRS.hpp" #include "memory/defNewGeneration.hpp" #include "memory/freeBlockDictionary.hpp" @@ -93,6 +94,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" @@ -3296,14 +3298,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/hotspot/src/share/vm/services/management.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/share/vm/services/management.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -1914,7 +1914,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++; @@ -1932,7 +1932,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/hotspot/src/share/vm/shark/sharkBuilder.cpp Mon Aug 11 07:30:46 2014 -0700 +++ b/hotspot/src/share/vm/shark/sharkBuilder.cpp Mon Aug 11 10:18:09 2014 -0700 @@ -413,7 +413,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";