8010389: After fix for 7107135 a failed dlopen() call results in a VM crash

Thu, 21 Mar 2013 20:46:46 -0700

author
iklam
date
Thu, 21 Mar 2013 20:46:46 -0700
changeset 4812
14509df4cd63
parent 4811
0ac03fef364f
child 4813
6574f999e0cf
child 4814
c342fbdf8a70

8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
Summary: Call dlerror() in VM thread as necessary.
Reviewed-by: coleenp, dholmes

src/os/linux/vm/os_linux.cpp file | annotate | diff | comparison | revisions
src/os/linux/vm/os_linux.hpp file | annotate | diff | comparison | revisions
test/runtime/8010389/VMThreadDlopen.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/os/linux/vm/os_linux.cpp	Thu Mar 21 06:53:53 2013 -0700
     1.2 +++ b/src/os/linux/vm/os_linux.cpp	Thu Mar 21 20:46:46 2013 -0700
     1.3 @@ -1811,13 +1811,15 @@
     1.4  class VM_LinuxDllLoad: public VM_Operation {
     1.5   private:
     1.6    const char *_filename;
     1.7 +  char *_ebuf;
     1.8 +  int _ebuflen;
     1.9    void *_lib;
    1.10   public:
    1.11 -  VM_LinuxDllLoad(const char *fn) :
    1.12 -    _filename(fn), _lib(NULL) {}
    1.13 +  VM_LinuxDllLoad(const char *fn, char *ebuf, int ebuflen) :
    1.14 +    _filename(fn), _ebuf(ebuf), _ebuflen(ebuflen), _lib(NULL) {}
    1.15    VMOp_Type type() const { return VMOp_LinuxDllLoad; }
    1.16    void doit() {
    1.17 -    _lib = os::Linux::dll_load_inner(_filename);
    1.18 +    _lib = os::Linux::dll_load_in_vmthread(_filename, _ebuf, _ebuflen);
    1.19      os::Linux::_stack_is_executable = true;
    1.20    }
    1.21    void* loaded_library() { return _lib; }
    1.22 @@ -1865,13 +1867,13 @@
    1.23              // This is for the case where the DLL has an static
    1.24              // constructor function that executes JNI code. We cannot
    1.25              // load such DLLs in the VMThread.
    1.26 -            result = ::dlopen(filename, RTLD_LAZY);
    1.27 +            result = os::Linux::dlopen_helper(filename, ebuf, ebuflen);
    1.28            }
    1.29  
    1.30            ThreadInVMfromNative tiv(jt);
    1.31            debug_only(VMNativeEntryWrapper vew;)
    1.32  
    1.33 -          VM_LinuxDllLoad op(filename);
    1.34 +          VM_LinuxDllLoad op(filename, ebuf, ebuflen);
    1.35            VMThread::execute(&op);
    1.36            if (LoadExecStackDllInVMThread) {
    1.37              result = op.loaded_library();
    1.38 @@ -1883,7 +1885,7 @@
    1.39    }
    1.40  
    1.41    if (!load_attempted) {
    1.42 -    result = ::dlopen(filename, RTLD_LAZY);
    1.43 +    result = os::Linux::dlopen_helper(filename, ebuf, ebuflen);
    1.44    }
    1.45  
    1.46    if (result != NULL) {
    1.47 @@ -1892,11 +1894,6 @@
    1.48    }
    1.49  
    1.50    Elf32_Ehdr elf_head;
    1.51 -
    1.52 -  // Read system error message into ebuf
    1.53 -  // It may or may not be overwritten below
    1.54 -  ::strncpy(ebuf, ::dlerror(), ebuflen-1);
    1.55 -  ebuf[ebuflen-1]='\0';
    1.56    int diag_msg_max_length=ebuflen-strlen(ebuf);
    1.57    char* diag_msg_buf=ebuf+strlen(ebuf);
    1.58  
    1.59 @@ -2039,10 +2036,19 @@
    1.60    return NULL;
    1.61  }
    1.62  
    1.63 -void * os::Linux::dll_load_inner(const char *filename) {
    1.64 +void * os::Linux::dlopen_helper(const char *filename, char *ebuf, int ebuflen) {
    1.65 +  void * result = ::dlopen(filename, RTLD_LAZY);
    1.66 +  if (result == NULL) {
    1.67 +    ::strncpy(ebuf, ::dlerror(), ebuflen - 1);
    1.68 +    ebuf[ebuflen-1] = '\0';
    1.69 +  }
    1.70 +  return result;
    1.71 +}
    1.72 +
    1.73 +void * os::Linux::dll_load_in_vmthread(const char *filename, char *ebuf, int ebuflen) {
    1.74    void * result = NULL;
    1.75    if (LoadExecStackDllInVMThread) {
    1.76 -    result = ::dlopen(filename, RTLD_LAZY);
    1.77 +    result = dlopen_helper(filename, ebuf, ebuflen);
    1.78    }
    1.79  
    1.80    // Since 7019808, libjvm.so is linked with -noexecstack. If the VM loads a
     2.1 --- a/src/os/linux/vm/os_linux.hpp	Thu Mar 21 06:53:53 2013 -0700
     2.2 +++ b/src/os/linux/vm/os_linux.hpp	Thu Mar 21 20:46:46 2013 -0700
     2.3 @@ -95,7 +95,8 @@
     2.4  
     2.5   public:
     2.6    static bool _stack_is_executable;
     2.7 -  static void *dll_load_inner(const char *name);
     2.8 +  static void *dlopen_helper(const char *name, char *ebuf, int ebuflen);
     2.9 +  static void *dll_load_in_vmthread(const char *name, char *ebuf, int ebuflen);
    2.10  
    2.11    static void init_thread_fpu_state();
    2.12    static int  get_fpu_control_word();
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/test/runtime/8010389/VMThreadDlopen.java	Thu Mar 21 20:46:46 2013 -0700
     3.3 @@ -0,0 +1,44 @@
     3.4 +/*
     3.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.
    3.11 + *
    3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.15 + * version 2 for more details (a copy is included in the LICENSE file that
    3.16 + * accompanied this code).
    3.17 + *
    3.18 + * You should have received a copy of the GNU General Public License version
    3.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.21 + *
    3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.23 + * or visit www.oracle.com if you need additional information or have any
    3.24 + * questions.
    3.25 + */
    3.26 +
    3.27 +import java.io.File;
    3.28 +
    3.29 +/*
    3.30 + * @test
    3.31 + * @key regression
    3.32 + * @bug 8010389
    3.33 + * @run main/othervm -Djava.library.path=. VMThreadDlopen
    3.34 + */
    3.35 +
    3.36 +public class VMThreadDlopen {
    3.37 +    public static void main(String[] args) throws Exception {
    3.38 +        File file = new File("libbroken.so");
    3.39 +        file.createNewFile();
    3.40 +        try {
    3.41 +            System.loadLibrary("broken");
    3.42 +        } catch (UnsatisfiedLinkError e) {
    3.43 +            e.printStackTrace();
    3.44 +            // expected
    3.45 +        }
    3.46 +    }
    3.47 +}

mercurial