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