Mercurial > hg > graal-jvmci-8
comparison src/os/linux/vm/os_linux.cpp @ 8812:14509df4cd63
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
author | iklam |
---|---|
date | Thu, 21 Mar 2013 20:46:46 -0700 |
parents | 6b803ba47588 |
children | 15c04fe93c18 17bf4d428955 |
comparison
equal
deleted
inserted
replaced
8811:0ac03fef364f | 8812:14509df4cd63 |
---|---|
1809 // do not stop the Java threads, they can stack overflow before the stacks | 1809 // do not stop the Java threads, they can stack overflow before the stacks |
1810 // are protected again. | 1810 // are protected again. |
1811 class VM_LinuxDllLoad: public VM_Operation { | 1811 class VM_LinuxDllLoad: public VM_Operation { |
1812 private: | 1812 private: |
1813 const char *_filename; | 1813 const char *_filename; |
1814 char *_ebuf; | |
1815 int _ebuflen; | |
1814 void *_lib; | 1816 void *_lib; |
1815 public: | 1817 public: |
1816 VM_LinuxDllLoad(const char *fn) : | 1818 VM_LinuxDllLoad(const char *fn, char *ebuf, int ebuflen) : |
1817 _filename(fn), _lib(NULL) {} | 1819 _filename(fn), _ebuf(ebuf), _ebuflen(ebuflen), _lib(NULL) {} |
1818 VMOp_Type type() const { return VMOp_LinuxDllLoad; } | 1820 VMOp_Type type() const { return VMOp_LinuxDllLoad; } |
1819 void doit() { | 1821 void doit() { |
1820 _lib = os::Linux::dll_load_inner(_filename); | 1822 _lib = os::Linux::dll_load_in_vmthread(_filename, _ebuf, _ebuflen); |
1821 os::Linux::_stack_is_executable = true; | 1823 os::Linux::_stack_is_executable = true; |
1822 } | 1824 } |
1823 void* loaded_library() { return _lib; } | 1825 void* loaded_library() { return _lib; } |
1824 }; | 1826 }; |
1825 | 1827 |
1863 } else { | 1865 } else { |
1864 if (!LoadExecStackDllInVMThread) { | 1866 if (!LoadExecStackDllInVMThread) { |
1865 // This is for the case where the DLL has an static | 1867 // This is for the case where the DLL has an static |
1866 // constructor function that executes JNI code. We cannot | 1868 // constructor function that executes JNI code. We cannot |
1867 // load such DLLs in the VMThread. | 1869 // load such DLLs in the VMThread. |
1868 result = ::dlopen(filename, RTLD_LAZY); | 1870 result = os::Linux::dlopen_helper(filename, ebuf, ebuflen); |
1869 } | 1871 } |
1870 | 1872 |
1871 ThreadInVMfromNative tiv(jt); | 1873 ThreadInVMfromNative tiv(jt); |
1872 debug_only(VMNativeEntryWrapper vew;) | 1874 debug_only(VMNativeEntryWrapper vew;) |
1873 | 1875 |
1874 VM_LinuxDllLoad op(filename); | 1876 VM_LinuxDllLoad op(filename, ebuf, ebuflen); |
1875 VMThread::execute(&op); | 1877 VMThread::execute(&op); |
1876 if (LoadExecStackDllInVMThread) { | 1878 if (LoadExecStackDllInVMThread) { |
1877 result = op.loaded_library(); | 1879 result = op.loaded_library(); |
1878 } | 1880 } |
1879 load_attempted = true; | 1881 load_attempted = true; |
1881 } | 1883 } |
1882 } | 1884 } |
1883 } | 1885 } |
1884 | 1886 |
1885 if (!load_attempted) { | 1887 if (!load_attempted) { |
1886 result = ::dlopen(filename, RTLD_LAZY); | 1888 result = os::Linux::dlopen_helper(filename, ebuf, ebuflen); |
1887 } | 1889 } |
1888 | 1890 |
1889 if (result != NULL) { | 1891 if (result != NULL) { |
1890 // Successful loading | 1892 // Successful loading |
1891 return result; | 1893 return result; |
1892 } | 1894 } |
1893 | 1895 |
1894 Elf32_Ehdr elf_head; | 1896 Elf32_Ehdr elf_head; |
1895 | |
1896 // Read system error message into ebuf | |
1897 // It may or may not be overwritten below | |
1898 ::strncpy(ebuf, ::dlerror(), ebuflen-1); | |
1899 ebuf[ebuflen-1]='\0'; | |
1900 int diag_msg_max_length=ebuflen-strlen(ebuf); | 1897 int diag_msg_max_length=ebuflen-strlen(ebuf); |
1901 char* diag_msg_buf=ebuf+strlen(ebuf); | 1898 char* diag_msg_buf=ebuf+strlen(ebuf); |
1902 | 1899 |
1903 if (diag_msg_max_length==0) { | 1900 if (diag_msg_max_length==0) { |
1904 // No more space in ebuf for additional diagnostics message | 1901 // No more space in ebuf for additional diagnostics message |
2037 } | 2034 } |
2038 | 2035 |
2039 return NULL; | 2036 return NULL; |
2040 } | 2037 } |
2041 | 2038 |
2042 void * os::Linux::dll_load_inner(const char *filename) { | 2039 void * os::Linux::dlopen_helper(const char *filename, char *ebuf, int ebuflen) { |
2040 void * result = ::dlopen(filename, RTLD_LAZY); | |
2041 if (result == NULL) { | |
2042 ::strncpy(ebuf, ::dlerror(), ebuflen - 1); | |
2043 ebuf[ebuflen-1] = '\0'; | |
2044 } | |
2045 return result; | |
2046 } | |
2047 | |
2048 void * os::Linux::dll_load_in_vmthread(const char *filename, char *ebuf, int ebuflen) { | |
2043 void * result = NULL; | 2049 void * result = NULL; |
2044 if (LoadExecStackDllInVMThread) { | 2050 if (LoadExecStackDllInVMThread) { |
2045 result = ::dlopen(filename, RTLD_LAZY); | 2051 result = dlopen_helper(filename, ebuf, ebuflen); |
2046 } | 2052 } |
2047 | 2053 |
2048 // Since 7019808, libjvm.so is linked with -noexecstack. If the VM loads a | 2054 // Since 7019808, libjvm.so is linked with -noexecstack. If the VM loads a |
2049 // library that requires an executable stack, or which does not have this | 2055 // library that requires an executable stack, or which does not have this |
2050 // stack attribute set, dlopen changes the stack attribute to executable. The | 2056 // stack attribute set, dlopen changes the stack attribute to executable. The |