Mercurial > hg > truffle
annotate src/os/posix/vm/os_posix.cpp @ 20338:8d5f66b42c53
8055525: Bigapp weblogic+medrec fails to startup after JDK-8038423
Summary: If large pages are enabled and configured in Linux, the VM always pre-commits the entire space. The VM fails verification of the commit of the initial heap because some internal data structure marked all memory pages of the heap as committed during initialization. This makes the code think that we attempted a double-commit during first allocation of the heap. Remove the initial marking of memory pages of the heap to committed.
Reviewed-by: mgerdin
author | tschatzl |
---|---|
date | Wed, 20 Aug 2014 14:34:40 +0200 |
parents | 78bbf4d43a14 |
children | 52b4284cb496 833b0f92429a |
rev | line source |
---|---|
2204 | 1 /* |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17805
diff
changeset
|
2 * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. |
14410 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 * | |
23 */ | |
2204 | 24 |
14410 | 25 #include "utilities/globalDefinitions.hpp" |
2204 | 26 #include "prims/jvm.h" |
6197 | 27 #include "runtime/frame.inline.hpp" |
2204 | 28 #include "runtime/os.hpp" |
29 #include "utilities/vmError.hpp" | |
30 | |
14410 | 31 #include <signal.h> |
2204 | 32 #include <unistd.h> |
33 #include <sys/resource.h> | |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
34 #include <sys/utsname.h> |
12141
cc56f122f3f7
8023720: (hotspot) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
11151
diff
changeset
|
35 #include <pthread.h> |
cc56f122f3f7
8023720: (hotspot) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
11151
diff
changeset
|
36 #include <signal.h> |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
37 |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17805
diff
changeset
|
38 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17805
diff
changeset
|
39 |
14410 | 40 // Todo: provide a os::get_max_process_id() or similar. Number of processes |
41 // may have been configured, can be read more accurately from proc fs etc. | |
42 #ifndef MAX_PID | |
43 #define MAX_PID INT_MAX | |
44 #endif | |
45 #define IS_VALID_PID(p) (p > 0 && p < MAX_PID) | |
2204 | 46 |
47 // Check core dump limit and report possible place where core can be found | |
48 void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) { | |
6200
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
49 int n; |
2204 | 50 struct rlimit rlim; |
51 bool success; | |
52 | |
6200
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
53 n = get_core_path(buffer, bufferSize); |
2204 | 54 |
55 if (getrlimit(RLIMIT_CORE, &rlim) != 0) { | |
6200
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
56 jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d (may not exist)", current_process_id()); |
2204 | 57 success = true; |
58 } else { | |
59 switch(rlim.rlim_cur) { | |
60 case RLIM_INFINITY: | |
6200
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
61 jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d", current_process_id()); |
2204 | 62 success = true; |
63 break; | |
64 case 0: | |
65 jio_snprintf(buffer, bufferSize, "Core dumps have been disabled. To enable core dumping, try \"ulimit -c unlimited\" before starting Java again"); | |
66 success = false; | |
67 break; | |
68 default: | |
6200
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
69 jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d (max size %lu kB). To ensure a full core dump, try \"ulimit -c unlimited\" before starting Java again", current_process_id(), (unsigned long)(rlim.rlim_cur >> 10)); |
2204 | 70 success = true; |
71 break; | |
72 } | |
73 } | |
74 VMError::report_coredump_status(buffer, success); | |
75 } | |
76 | |
6197 | 77 address os::get_caller_pc(int n) { |
78 #ifdef _NMT_NOINLINE_ | |
79 n ++; | |
80 #endif | |
81 frame fr = os::current_frame(); | |
82 while (n > 0 && fr.pc() && | |
83 !os::is_first_C_frame(&fr) && fr.sender_pc()) { | |
84 fr = os::get_sender_for_C_frame(&fr); | |
85 n --; | |
86 } | |
87 if (n == 0) { | |
88 return fr.pc(); | |
89 } else { | |
90 return NULL; | |
91 } | |
92 } | |
93 | |
4750
b16494a69d3d
7126185: Clean up lasterror handling, add os::get_last_error()
phh
parents:
2302
diff
changeset
|
94 int os::get_last_error() { |
b16494a69d3d
7126185: Clean up lasterror handling, add os::get_last_error()
phh
parents:
2302
diff
changeset
|
95 return errno; |
b16494a69d3d
7126185: Clean up lasterror handling, add os::get_last_error()
phh
parents:
2302
diff
changeset
|
96 } |
b16494a69d3d
7126185: Clean up lasterror handling, add os::get_last_error()
phh
parents:
2302
diff
changeset
|
97 |
2302
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
98 bool os::is_debugger_attached() { |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
99 // not implemented |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
100 return false; |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
101 } |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
102 |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
103 void os::wait_for_keypress_at_exit(void) { |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
104 // don't do anything on posix platforms |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
105 return; |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
106 } |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
107 |
7433
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
108 // Multiple threads can race in this code, and can remap over each other with MAP_FIXED, |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
109 // so on posix, unmap the section at the start and at the end of the chunk that we mapped |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
110 // rather than unmapping and remapping the whole chunk to get requested alignment. |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
111 char* os::reserve_memory_aligned(size_t size, size_t alignment) { |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
112 assert((alignment & (os::vm_allocation_granularity() - 1)) == 0, |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
113 "Alignment must be a multiple of allocation granularity (page size)"); |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
114 assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned"); |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
115 |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
116 size_t extra_size = size + alignment; |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
117 assert(extra_size >= size, "overflow, size is too large to allow alignment"); |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
118 |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
119 char* extra_base = os::reserve_memory(extra_size, NULL, alignment); |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
120 |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
121 if (extra_base == NULL) { |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
122 return NULL; |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
123 } |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
124 |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
125 // Do manual alignment |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
126 char* aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment); |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
127 |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
128 // [ | | ] |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
129 // ^ extra_base |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
130 // ^ extra_base + begin_offset == aligned_base |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
131 // extra_base + begin_offset + size ^ |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
132 // extra_base + extra_size ^ |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
133 // |<>| == begin_offset |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
134 // end_offset == |<>| |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
135 size_t begin_offset = aligned_base - extra_base; |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
136 size_t end_offset = (extra_base + extra_size) - (aligned_base + size); |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
137 |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
138 if (begin_offset > 0) { |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
139 os::release_memory(extra_base, begin_offset); |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
140 } |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
141 |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
142 if (end_offset > 0) { |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
143 os::release_memory(extra_base + begin_offset + size, end_offset); |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
144 } |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
145 |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
146 return aligned_base; |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
147 } |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
148 |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
149 void os::Posix::print_load_average(outputStream* st) { |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
150 st->print("load average:"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
151 double loadavg[3]; |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
152 os::loadavg(loadavg, 3); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
153 st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
154 st->cr(); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
155 } |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
156 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
157 void os::Posix::print_rlimit_info(outputStream* st) { |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
158 st->print("rlimit:"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
159 struct rlimit rlim; |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
160 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
161 st->print(" STACK "); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
162 getrlimit(RLIMIT_STACK, &rlim); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
163 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
164 else st->print("%uk", rlim.rlim_cur >> 10); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
165 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
166 st->print(", CORE "); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
167 getrlimit(RLIMIT_CORE, &rlim); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
168 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
169 else st->print("%uk", rlim.rlim_cur >> 10); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
170 |
14410 | 171 // Isn't there on solaris |
14412 | 172 #if !defined(TARGET_OS_FAMILY_solaris) && !defined(TARGET_OS_FAMILY_aix) |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
173 st->print(", NPROC "); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
174 getrlimit(RLIMIT_NPROC, &rlim); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
175 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
176 else st->print("%d", rlim.rlim_cur); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
177 #endif |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
178 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
179 st->print(", NOFILE "); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
180 getrlimit(RLIMIT_NOFILE, &rlim); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
181 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
182 else st->print("%d", rlim.rlim_cur); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
183 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
184 st->print(", AS "); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
185 getrlimit(RLIMIT_AS, &rlim); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
186 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
187 else st->print("%uk", rlim.rlim_cur >> 10); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
188 st->cr(); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
189 } |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
190 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
191 void os::Posix::print_uname_info(outputStream* st) { |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
192 // kernel |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
193 st->print("uname:"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
194 struct utsname name; |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
195 uname(&name); |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17805
diff
changeset
|
196 st->print("%s ", name.sysname); |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17805
diff
changeset
|
197 st->print("%s ", name.release); |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17805
diff
changeset
|
198 st->print("%s ", name.version); |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17805
diff
changeset
|
199 st->print("%s", name.machine); |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
200 st->cr(); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
201 } |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
202 |
8854
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
203 bool os::has_allocatable_memory_limit(julong* limit) { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
204 struct rlimit rlim; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
205 int getrlimit_res = getrlimit(RLIMIT_AS, &rlim); |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
206 // if there was an error when calling getrlimit, assume that there is no limitation |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
207 // on virtual memory. |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
208 bool result; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
209 if ((getrlimit_res != 0) || (rlim.rlim_cur == RLIM_INFINITY)) { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
210 result = false; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
211 } else { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
212 *limit = (julong)rlim.rlim_cur; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
213 result = true; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
214 } |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
215 #ifdef _LP64 |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
216 return result; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
217 #else |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
218 // arbitrary virtual space limit for 32 bit Unices found by testing. If |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
219 // getrlimit above returned a limit, bound it with this limit. Otherwise |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
220 // directly use it. |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
221 const julong max_virtual_limit = (julong)3800*M; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
222 if (result) { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
223 *limit = MIN2(*limit, max_virtual_limit); |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
224 } else { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
225 *limit = max_virtual_limit; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
226 } |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
227 |
8854
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
228 // bound by actually allocatable memory. The algorithm uses two bounds, an |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
229 // upper and a lower limit. The upper limit is the current highest amount of |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
230 // memory that could not be allocated, the lower limit is the current highest |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
231 // amount of memory that could be allocated. |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
232 // The algorithm iteratively refines the result by halving the difference |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
233 // between these limits, updating either the upper limit (if that value could |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
234 // not be allocated) or the lower limit (if the that value could be allocated) |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
235 // until the difference between these limits is "small". |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
236 |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
237 // the minimum amount of memory we care about allocating. |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
238 const julong min_allocation_size = M; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
239 |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
240 julong upper_limit = *limit; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
241 |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
242 // first check a few trivial cases |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
243 if (is_allocatable(upper_limit) || (upper_limit <= min_allocation_size)) { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
244 *limit = upper_limit; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
245 } else if (!is_allocatable(min_allocation_size)) { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
246 // we found that not even min_allocation_size is allocatable. Return it |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
247 // anyway. There is no point to search for a better value any more. |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
248 *limit = min_allocation_size; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
249 } else { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
250 // perform the binary search. |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
251 julong lower_limit = min_allocation_size; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
252 while ((upper_limit - lower_limit) > min_allocation_size) { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
253 julong temp_limit = ((upper_limit - lower_limit) / 2) + lower_limit; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
254 temp_limit = align_size_down_(temp_limit, min_allocation_size); |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
255 if (is_allocatable(temp_limit)) { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
256 lower_limit = temp_limit; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
257 } else { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
258 upper_limit = temp_limit; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
259 } |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
260 } |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
261 *limit = lower_limit; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
262 } |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
263 return true; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
264 #endif |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
265 } |
10195
e12c9b3740db
8012260: ciReplay: Include PID into the name of replay data file
vlivanov
parents:
8854
diff
changeset
|
266 |
e12c9b3740db
8012260: ciReplay: Include PID into the name of replay data file
vlivanov
parents:
8854
diff
changeset
|
267 const char* os::get_current_directory(char *buf, size_t buflen) { |
e12c9b3740db
8012260: ciReplay: Include PID into the name of replay data file
vlivanov
parents:
8854
diff
changeset
|
268 return getcwd(buf, buflen); |
e12c9b3740db
8012260: ciReplay: Include PID into the name of replay data file
vlivanov
parents:
8854
diff
changeset
|
269 } |
e12c9b3740db
8012260: ciReplay: Include PID into the name of replay data file
vlivanov
parents:
8854
diff
changeset
|
270 |
e12c9b3740db
8012260: ciReplay: Include PID into the name of replay data file
vlivanov
parents:
8854
diff
changeset
|
271 FILE* os::open(int fd, const char* mode) { |
e12c9b3740db
8012260: ciReplay: Include PID into the name of replay data file
vlivanov
parents:
8854
diff
changeset
|
272 return ::fdopen(fd, mode); |
e12c9b3740db
8012260: ciReplay: Include PID into the name of replay data file
vlivanov
parents:
8854
diff
changeset
|
273 } |
11151 | 274 |
12117
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
275 // Builds a platform dependent Agent_OnLoad_<lib_name> function name |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
276 // which is used to find statically linked in agents. |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
277 // Parameters: |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
278 // sym_name: Symbol in library we are looking for |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
279 // lib_name: Name of library to look in, NULL for shared libs. |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
280 // is_absolute_path == true if lib_name is absolute path to agent |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
281 // such as "/a/b/libL.so" |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
282 // == false if only the base name of the library is passed in |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
283 // such as "L" |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
284 char* os::build_agent_function_name(const char *sym_name, const char *lib_name, |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
285 bool is_absolute_path) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
286 char *agent_entry_name; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
287 size_t len; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
288 size_t name_len; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
289 size_t prefix_len = strlen(JNI_LIB_PREFIX); |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
290 size_t suffix_len = strlen(JNI_LIB_SUFFIX); |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
291 const char *start; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
292 |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
293 if (lib_name != NULL) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
294 len = name_len = strlen(lib_name); |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
295 if (is_absolute_path) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
296 // Need to strip path, prefix and suffix |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
297 if ((start = strrchr(lib_name, *os::file_separator())) != NULL) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
298 lib_name = ++start; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
299 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
300 if (len <= (prefix_len + suffix_len)) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
301 return NULL; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
302 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
303 lib_name += prefix_len; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
304 name_len = strlen(lib_name) - suffix_len; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
305 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
306 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
307 len = (lib_name != NULL ? name_len : 0) + strlen(sym_name) + 2; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
308 agent_entry_name = NEW_C_HEAP_ARRAY_RETURN_NULL(char, len, mtThread); |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
309 if (agent_entry_name == NULL) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
310 return NULL; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
311 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
312 strcpy(agent_entry_name, sym_name); |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
313 if (lib_name != NULL) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
314 strcat(agent_entry_name, "_"); |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
315 strncat(agent_entry_name, lib_name, name_len); |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
316 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
317 return agent_entry_name; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
318 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
319 |
14410 | 320 // Returned string is a constant. For unknown signals "UNKNOWN" is returned. |
321 const char* os::Posix::get_signal_name(int sig, char* out, size_t outlen) { | |
322 | |
323 static const struct { | |
324 int sig; const char* name; | |
325 } | |
326 info[] = | |
327 { | |
328 { SIGABRT, "SIGABRT" }, | |
329 #ifdef SIGAIO | |
330 { SIGAIO, "SIGAIO" }, | |
331 #endif | |
332 { SIGALRM, "SIGALRM" }, | |
333 #ifdef SIGALRM1 | |
334 { SIGALRM1, "SIGALRM1" }, | |
335 #endif | |
336 { SIGBUS, "SIGBUS" }, | |
337 #ifdef SIGCANCEL | |
338 { SIGCANCEL, "SIGCANCEL" }, | |
339 #endif | |
340 { SIGCHLD, "SIGCHLD" }, | |
341 #ifdef SIGCLD | |
342 { SIGCLD, "SIGCLD" }, | |
343 #endif | |
344 { SIGCONT, "SIGCONT" }, | |
345 #ifdef SIGCPUFAIL | |
346 { SIGCPUFAIL, "SIGCPUFAIL" }, | |
347 #endif | |
348 #ifdef SIGDANGER | |
349 { SIGDANGER, "SIGDANGER" }, | |
350 #endif | |
351 #ifdef SIGDIL | |
352 { SIGDIL, "SIGDIL" }, | |
353 #endif | |
354 #ifdef SIGEMT | |
355 { SIGEMT, "SIGEMT" }, | |
356 #endif | |
357 { SIGFPE, "SIGFPE" }, | |
358 #ifdef SIGFREEZE | |
359 { SIGFREEZE, "SIGFREEZE" }, | |
360 #endif | |
361 #ifdef SIGGFAULT | |
362 { SIGGFAULT, "SIGGFAULT" }, | |
363 #endif | |
364 #ifdef SIGGRANT | |
365 { SIGGRANT, "SIGGRANT" }, | |
366 #endif | |
367 { SIGHUP, "SIGHUP" }, | |
368 { SIGILL, "SIGILL" }, | |
369 { SIGINT, "SIGINT" }, | |
370 #ifdef SIGIO | |
371 { SIGIO, "SIGIO" }, | |
372 #endif | |
373 #ifdef SIGIOINT | |
374 { SIGIOINT, "SIGIOINT" }, | |
375 #endif | |
376 #ifdef SIGIOT | |
377 // SIGIOT is there for BSD compatibility, but on most Unices just a | |
378 // synonym for SIGABRT. The result should be "SIGABRT", not | |
379 // "SIGIOT". | |
380 #if (SIGIOT != SIGABRT ) | |
381 { SIGIOT, "SIGIOT" }, | |
382 #endif | |
383 #endif | |
384 #ifdef SIGKAP | |
385 { SIGKAP, "SIGKAP" }, | |
386 #endif | |
387 { SIGKILL, "SIGKILL" }, | |
388 #ifdef SIGLOST | |
389 { SIGLOST, "SIGLOST" }, | |
390 #endif | |
391 #ifdef SIGLWP | |
392 { SIGLWP, "SIGLWP" }, | |
393 #endif | |
394 #ifdef SIGLWPTIMER | |
395 { SIGLWPTIMER, "SIGLWPTIMER" }, | |
396 #endif | |
397 #ifdef SIGMIGRATE | |
398 { SIGMIGRATE, "SIGMIGRATE" }, | |
399 #endif | |
400 #ifdef SIGMSG | |
401 { SIGMSG, "SIGMSG" }, | |
402 #endif | |
403 { SIGPIPE, "SIGPIPE" }, | |
404 #ifdef SIGPOLL | |
405 { SIGPOLL, "SIGPOLL" }, | |
406 #endif | |
407 #ifdef SIGPRE | |
408 { SIGPRE, "SIGPRE" }, | |
409 #endif | |
410 { SIGPROF, "SIGPROF" }, | |
411 #ifdef SIGPTY | |
412 { SIGPTY, "SIGPTY" }, | |
413 #endif | |
414 #ifdef SIGPWR | |
415 { SIGPWR, "SIGPWR" }, | |
416 #endif | |
417 { SIGQUIT, "SIGQUIT" }, | |
418 #ifdef SIGRECONFIG | |
419 { SIGRECONFIG, "SIGRECONFIG" }, | |
420 #endif | |
421 #ifdef SIGRECOVERY | |
422 { SIGRECOVERY, "SIGRECOVERY" }, | |
423 #endif | |
424 #ifdef SIGRESERVE | |
425 { SIGRESERVE, "SIGRESERVE" }, | |
426 #endif | |
427 #ifdef SIGRETRACT | |
428 { SIGRETRACT, "SIGRETRACT" }, | |
429 #endif | |
430 #ifdef SIGSAK | |
431 { SIGSAK, "SIGSAK" }, | |
432 #endif | |
433 { SIGSEGV, "SIGSEGV" }, | |
434 #ifdef SIGSOUND | |
435 { SIGSOUND, "SIGSOUND" }, | |
436 #endif | |
437 { SIGSTOP, "SIGSTOP" }, | |
438 { SIGSYS, "SIGSYS" }, | |
439 #ifdef SIGSYSERROR | |
440 { SIGSYSERROR, "SIGSYSERROR" }, | |
441 #endif | |
442 #ifdef SIGTALRM | |
443 { SIGTALRM, "SIGTALRM" }, | |
444 #endif | |
445 { SIGTERM, "SIGTERM" }, | |
446 #ifdef SIGTHAW | |
447 { SIGTHAW, "SIGTHAW" }, | |
448 #endif | |
449 { SIGTRAP, "SIGTRAP" }, | |
450 #ifdef SIGTSTP | |
451 { SIGTSTP, "SIGTSTP" }, | |
452 #endif | |
453 { SIGTTIN, "SIGTTIN" }, | |
454 { SIGTTOU, "SIGTTOU" }, | |
455 #ifdef SIGURG | |
456 { SIGURG, "SIGURG" }, | |
457 #endif | |
458 { SIGUSR1, "SIGUSR1" }, | |
459 { SIGUSR2, "SIGUSR2" }, | |
460 #ifdef SIGVIRT | |
461 { SIGVIRT, "SIGVIRT" }, | |
462 #endif | |
463 { SIGVTALRM, "SIGVTALRM" }, | |
464 #ifdef SIGWAITING | |
465 { SIGWAITING, "SIGWAITING" }, | |
466 #endif | |
467 #ifdef SIGWINCH | |
468 { SIGWINCH, "SIGWINCH" }, | |
469 #endif | |
470 #ifdef SIGWINDOW | |
471 { SIGWINDOW, "SIGWINDOW" }, | |
472 #endif | |
473 { SIGXCPU, "SIGXCPU" }, | |
474 { SIGXFSZ, "SIGXFSZ" }, | |
475 #ifdef SIGXRES | |
476 { SIGXRES, "SIGXRES" }, | |
477 #endif | |
478 { -1, NULL } | |
479 }; | |
480 | |
481 const char* ret = NULL; | |
482 | |
483 #ifdef SIGRTMIN | |
484 if (sig >= SIGRTMIN && sig <= SIGRTMAX) { | |
485 if (sig == SIGRTMIN) { | |
486 ret = "SIGRTMIN"; | |
487 } else if (sig == SIGRTMAX) { | |
488 ret = "SIGRTMAX"; | |
489 } else { | |
490 jio_snprintf(out, outlen, "SIGRTMIN+%d", sig - SIGRTMIN); | |
491 return out; | |
492 } | |
493 } | |
494 #endif | |
495 | |
496 if (sig > 0) { | |
497 for (int idx = 0; info[idx].sig != -1; idx ++) { | |
498 if (info[idx].sig == sig) { | |
499 ret = info[idx].name; | |
500 break; | |
501 } | |
502 } | |
503 } | |
504 | |
505 if (!ret) { | |
506 if (!is_valid_signal(sig)) { | |
507 ret = "INVALID"; | |
508 } else { | |
509 ret = "UNKNOWN"; | |
510 } | |
511 } | |
512 | |
513 jio_snprintf(out, outlen, ret); | |
514 return out; | |
515 } | |
516 | |
517 // Returns true if signal number is valid. | |
518 bool os::Posix::is_valid_signal(int sig) { | |
519 // MacOS not really POSIX compliant: sigaddset does not return | |
520 // an error for invalid signal numbers. However, MacOS does not | |
521 // support real time signals and simply seems to have just 33 | |
522 // signals with no holes in the signal range. | |
523 #ifdef __APPLE__ | |
524 return sig >= 1 && sig < NSIG; | |
525 #else | |
526 // Use sigaddset to check for signal validity. | |
527 sigset_t set; | |
528 if (sigaddset(&set, sig) == -1 && errno == EINVAL) { | |
529 return false; | |
530 } | |
531 return true; | |
532 #endif | |
533 } | |
534 | |
535 #define NUM_IMPORTANT_SIGS 32 | |
536 // Returns one-line short description of a signal set in a user provided buffer. | |
537 const char* os::Posix::describe_signal_set_short(const sigset_t* set, char* buffer, size_t buf_size) { | |
14411 | 538 assert(buf_size == (NUM_IMPORTANT_SIGS + 1), "wrong buffer size"); |
14410 | 539 // Note: for shortness, just print out the first 32. That should |
540 // cover most of the useful ones, apart from realtime signals. | |
541 for (int sig = 1; sig <= NUM_IMPORTANT_SIGS; sig++) { | |
542 const int rc = sigismember(set, sig); | |
543 if (rc == -1 && errno == EINVAL) { | |
544 buffer[sig-1] = '?'; | |
545 } else { | |
546 buffer[sig-1] = rc == 0 ? '0' : '1'; | |
547 } | |
548 } | |
549 buffer[NUM_IMPORTANT_SIGS] = 0; | |
550 return buffer; | |
551 } | |
552 | |
553 // Prints one-line description of a signal set. | |
554 void os::Posix::print_signal_set_short(outputStream* st, const sigset_t* set) { | |
555 char buf[NUM_IMPORTANT_SIGS + 1]; | |
556 os::Posix::describe_signal_set_short(set, buf, sizeof(buf)); | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17805
diff
changeset
|
557 st->print("%s", buf); |
14410 | 558 } |
559 | |
560 // Writes one-line description of a combination of sigaction.sa_flags into a user | |
561 // provided buffer. Returns that buffer. | |
562 const char* os::Posix::describe_sa_flags(int flags, char* buffer, size_t size) { | |
563 char* p = buffer; | |
564 size_t remaining = size; | |
565 bool first = true; | |
566 int idx = 0; | |
567 | |
568 assert(buffer, "invalid argument"); | |
569 | |
570 if (size == 0) { | |
571 return buffer; | |
572 } | |
573 | |
574 strncpy(buffer, "none", size); | |
575 | |
576 const struct { | |
577 int i; | |
578 const char* s; | |
579 } flaginfo [] = { | |
580 { SA_NOCLDSTOP, "SA_NOCLDSTOP" }, | |
581 { SA_ONSTACK, "SA_ONSTACK" }, | |
582 { SA_RESETHAND, "SA_RESETHAND" }, | |
583 { SA_RESTART, "SA_RESTART" }, | |
584 { SA_SIGINFO, "SA_SIGINFO" }, | |
585 { SA_NOCLDWAIT, "SA_NOCLDWAIT" }, | |
586 { SA_NODEFER, "SA_NODEFER" }, | |
587 #ifdef AIX | |
588 { SA_ONSTACK, "SA_ONSTACK" }, | |
589 { SA_OLDSTYLE, "SA_OLDSTYLE" }, | |
590 #endif | |
591 { 0, NULL } | |
592 }; | |
593 | |
594 for (idx = 0; flaginfo[idx].s && remaining > 1; idx++) { | |
595 if (flags & flaginfo[idx].i) { | |
596 if (first) { | |
597 jio_snprintf(p, remaining, "%s", flaginfo[idx].s); | |
598 first = false; | |
599 } else { | |
600 jio_snprintf(p, remaining, "|%s", flaginfo[idx].s); | |
601 } | |
602 const size_t len = strlen(p); | |
603 p += len; | |
604 remaining -= len; | |
605 } | |
606 } | |
607 | |
608 buffer[size - 1] = '\0'; | |
609 | |
610 return buffer; | |
611 } | |
612 | |
613 // Prints one-line description of a combination of sigaction.sa_flags. | |
614 void os::Posix::print_sa_flags(outputStream* st, int flags) { | |
615 char buffer[0x100]; | |
616 os::Posix::describe_sa_flags(flags, buffer, sizeof(buffer)); | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
17805
diff
changeset
|
617 st->print("%s", buffer); |
14410 | 618 } |
619 | |
620 // Helper function for os::Posix::print_siginfo_...(): | |
621 // return a textual description for signal code. | |
622 struct enum_sigcode_desc_t { | |
623 const char* s_name; | |
624 const char* s_desc; | |
625 }; | |
626 | |
627 static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t* out) { | |
628 | |
629 const struct { | |
630 int sig; int code; const char* s_code; const char* s_desc; | |
631 } t1 [] = { | |
632 { SIGILL, ILL_ILLOPC, "ILL_ILLOPC", "Illegal opcode." }, | |
633 { SIGILL, ILL_ILLOPN, "ILL_ILLOPN", "Illegal operand." }, | |
634 { SIGILL, ILL_ILLADR, "ILL_ILLADR", "Illegal addressing mode." }, | |
635 { SIGILL, ILL_ILLTRP, "ILL_ILLTRP", "Illegal trap." }, | |
636 { SIGILL, ILL_PRVOPC, "ILL_PRVOPC", "Privileged opcode." }, | |
637 { SIGILL, ILL_PRVREG, "ILL_PRVREG", "Privileged register." }, | |
638 { SIGILL, ILL_COPROC, "ILL_COPROC", "Coprocessor error." }, | |
639 { SIGILL, ILL_BADSTK, "ILL_BADSTK", "Internal stack error." }, | |
640 #if defined(IA64) && defined(LINUX) | |
641 { SIGILL, ILL_BADIADDR, "ILL_BADIADDR", "Unimplemented instruction address" }, | |
642 { SIGILL, ILL_BREAK, "ILL_BREAK", "Application Break instruction" }, | |
643 #endif | |
644 { SIGFPE, FPE_INTDIV, "FPE_INTDIV", "Integer divide by zero." }, | |
645 { SIGFPE, FPE_INTOVF, "FPE_INTOVF", "Integer overflow." }, | |
646 { SIGFPE, FPE_FLTDIV, "FPE_FLTDIV", "Floating-point divide by zero." }, | |
647 { SIGFPE, FPE_FLTOVF, "FPE_FLTOVF", "Floating-point overflow." }, | |
648 { SIGFPE, FPE_FLTUND, "FPE_FLTUND", "Floating-point underflow." }, | |
649 { SIGFPE, FPE_FLTRES, "FPE_FLTRES", "Floating-point inexact result." }, | |
650 { SIGFPE, FPE_FLTINV, "FPE_FLTINV", "Invalid floating-point operation." }, | |
651 { SIGFPE, FPE_FLTSUB, "FPE_FLTSUB", "Subscript out of range." }, | |
652 { SIGSEGV, SEGV_MAPERR, "SEGV_MAPERR", "Address not mapped to object." }, | |
653 { SIGSEGV, SEGV_ACCERR, "SEGV_ACCERR", "Invalid permissions for mapped object." }, | |
654 #ifdef AIX | |
655 // no explanation found what keyerr would be | |
656 { SIGSEGV, SEGV_KEYERR, "SEGV_KEYERR", "key error" }, | |
657 #endif | |
658 #if defined(IA64) && !defined(AIX) | |
659 { SIGSEGV, SEGV_PSTKOVF, "SEGV_PSTKOVF", "Paragraph stack overflow" }, | |
660 #endif | |
661 { SIGBUS, BUS_ADRALN, "BUS_ADRALN", "Invalid address alignment." }, | |
662 { SIGBUS, BUS_ADRERR, "BUS_ADRERR", "Nonexistent physical address." }, | |
663 { SIGBUS, BUS_OBJERR, "BUS_OBJERR", "Object-specific hardware error." }, | |
664 { SIGTRAP, TRAP_BRKPT, "TRAP_BRKPT", "Process breakpoint." }, | |
665 { SIGTRAP, TRAP_TRACE, "TRAP_TRACE", "Process trace trap." }, | |
666 { SIGCHLD, CLD_EXITED, "CLD_EXITED", "Child has exited." }, | |
667 { SIGCHLD, CLD_KILLED, "CLD_KILLED", "Child has terminated abnormally and did not create a core file." }, | |
668 { SIGCHLD, CLD_DUMPED, "CLD_DUMPED", "Child has terminated abnormally and created a core file." }, | |
669 { SIGCHLD, CLD_TRAPPED, "CLD_TRAPPED", "Traced child has trapped." }, | |
670 { SIGCHLD, CLD_STOPPED, "CLD_STOPPED", "Child has stopped." }, | |
671 { SIGCHLD, CLD_CONTINUED,"CLD_CONTINUED","Stopped child has continued." }, | |
672 #ifdef SIGPOLL | |
673 { SIGPOLL, POLL_OUT, "POLL_OUT", "Output buffers available." }, | |
674 { SIGPOLL, POLL_MSG, "POLL_MSG", "Input message available." }, | |
675 { SIGPOLL, POLL_ERR, "POLL_ERR", "I/O error." }, | |
676 { SIGPOLL, POLL_PRI, "POLL_PRI", "High priority input available." }, | |
677 { SIGPOLL, POLL_HUP, "POLL_HUP", "Device disconnected. [Option End]" }, | |
678 #endif | |
679 { -1, -1, NULL, NULL } | |
680 }; | |
681 | |
682 // Codes valid in any signal context. | |
683 const struct { | |
684 int code; const char* s_code; const char* s_desc; | |
685 } t2 [] = { | |
686 { SI_USER, "SI_USER", "Signal sent by kill()." }, | |
687 { SI_QUEUE, "SI_QUEUE", "Signal sent by the sigqueue()." }, | |
688 { SI_TIMER, "SI_TIMER", "Signal generated by expiration of a timer set by timer_settime()." }, | |
689 { SI_ASYNCIO, "SI_ASYNCIO", "Signal generated by completion of an asynchronous I/O request." }, | |
690 { SI_MESGQ, "SI_MESGQ", "Signal generated by arrival of a message on an empty message queue." }, | |
691 // Linux specific | |
692 #ifdef SI_TKILL | |
693 { SI_TKILL, "SI_TKILL", "Signal sent by tkill (pthread_kill)" }, | |
694 #endif | |
695 #ifdef SI_DETHREAD | |
696 { SI_DETHREAD, "SI_DETHREAD", "Signal sent by execve() killing subsidiary threads" }, | |
697 #endif | |
698 #ifdef SI_KERNEL | |
699 { SI_KERNEL, "SI_KERNEL", "Signal sent by kernel." }, | |
700 #endif | |
701 #ifdef SI_SIGIO | |
702 { SI_SIGIO, "SI_SIGIO", "Signal sent by queued SIGIO" }, | |
703 #endif | |
704 | |
705 #ifdef AIX | |
706 { SI_UNDEFINED, "SI_UNDEFINED","siginfo contains partial information" }, | |
707 { SI_EMPTY, "SI_EMPTY", "siginfo contains no useful information" }, | |
708 #endif | |
709 | |
710 #ifdef __sun | |
711 { SI_NOINFO, "SI_NOINFO", "No signal information" }, | |
712 { SI_RCTL, "SI_RCTL", "kernel generated signal via rctl action" }, | |
713 { SI_LWP, "SI_LWP", "Signal sent via lwp_kill" }, | |
714 #endif | |
715 | |
716 { -1, NULL, NULL } | |
717 }; | |
718 | |
719 const char* s_code = NULL; | |
720 const char* s_desc = NULL; | |
721 | |
722 for (int i = 0; t1[i].sig != -1; i ++) { | |
723 if (t1[i].sig == si->si_signo && t1[i].code == si->si_code) { | |
724 s_code = t1[i].s_code; | |
725 s_desc = t1[i].s_desc; | |
726 break; | |
727 } | |
728 } | |
729 | |
730 if (s_code == NULL) { | |
731 for (int i = 0; t2[i].s_code != NULL; i ++) { | |
732 if (t2[i].code == si->si_code) { | |
733 s_code = t2[i].s_code; | |
734 s_desc = t2[i].s_desc; | |
735 } | |
736 } | |
737 } | |
738 | |
739 if (s_code == NULL) { | |
740 out->s_name = "unknown"; | |
741 out->s_desc = "unknown"; | |
742 return false; | |
743 } | |
744 | |
745 out->s_name = s_code; | |
746 out->s_desc = s_desc; | |
747 | |
748 return true; | |
749 } | |
750 | |
751 // A POSIX conform, platform-independend siginfo print routine. | |
752 // Short print out on one line. | |
753 void os::Posix::print_siginfo_brief(outputStream* os, const siginfo_t* si) { | |
754 char buf[20]; | |
755 os->print("siginfo: "); | |
756 | |
757 if (!si) { | |
758 os->print("<null>"); | |
759 return; | |
760 } | |
761 | |
762 // See print_siginfo_full() for details. | |
763 const int sig = si->si_signo; | |
764 | |
765 os->print("si_signo: %d (%s)", sig, os::Posix::get_signal_name(sig, buf, sizeof(buf))); | |
766 | |
767 enum_sigcode_desc_t ed; | |
768 if (get_signal_code_description(si, &ed)) { | |
769 os->print(", si_code: %d (%s)", si->si_code, ed.s_name); | |
770 } else { | |
771 os->print(", si_code: %d (unknown)", si->si_code); | |
772 } | |
773 | |
774 if (si->si_errno) { | |
775 os->print(", si_errno: %d", si->si_errno); | |
776 } | |
777 | |
778 const int me = (int) ::getpid(); | |
779 const int pid = (int) si->si_pid; | |
780 | |
781 if (si->si_code == SI_USER || si->si_code == SI_QUEUE) { | |
782 if (IS_VALID_PID(pid) && pid != me) { | |
783 os->print(", sent from pid: %d (uid: %d)", pid, (int) si->si_uid); | |
784 } | |
785 } else if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || | |
786 sig == SIGTRAP || sig == SIGFPE) { | |
787 os->print(", si_addr: " PTR_FORMAT, si->si_addr); | |
788 #ifdef SIGPOLL | |
789 } else if (sig == SIGPOLL) { | |
790 os->print(", si_band: " PTR64_FORMAT, (uint64_t)si->si_band); | |
791 #endif | |
792 } else if (sig == SIGCHLD) { | |
793 os->print_cr(", si_pid: %d, si_uid: %d, si_status: %d", (int) si->si_pid, si->si_uid, si->si_status); | |
794 } | |
795 } | |
796 | |
11151 | 797 os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { |
798 assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); | |
799 } | |
800 | |
801 /* | |
802 * See the caveats for this class in os_posix.hpp | |
803 * Protects the callback call so that SIGSEGV / SIGBUS jumps back into this | |
804 * method and returns false. If none of the signals are raised, returns true. | |
805 * The callback is supposed to provide the method that should be protected. | |
806 */ | |
807 bool os::WatcherThreadCrashProtection::call(os::CrashProtectionCallback& cb) { | |
12141
cc56f122f3f7
8023720: (hotspot) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
11151
diff
changeset
|
808 sigset_t saved_sig_mask; |
cc56f122f3f7
8023720: (hotspot) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
11151
diff
changeset
|
809 |
11151 | 810 assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread"); |
811 assert(!WatcherThread::watcher_thread()->has_crash_protection(), | |
812 "crash_protection already set?"); | |
813 | |
12141
cc56f122f3f7
8023720: (hotspot) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
11151
diff
changeset
|
814 // we cannot rely on sigsetjmp/siglongjmp to save/restore the signal mask |
cc56f122f3f7
8023720: (hotspot) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
11151
diff
changeset
|
815 // since on at least some systems (OS X) siglongjmp will restore the mask |
cc56f122f3f7
8023720: (hotspot) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
11151
diff
changeset
|
816 // for the process, not the thread |
cc56f122f3f7
8023720: (hotspot) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
11151
diff
changeset
|
817 pthread_sigmask(0, NULL, &saved_sig_mask); |
cc56f122f3f7
8023720: (hotspot) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
11151
diff
changeset
|
818 if (sigsetjmp(_jmpbuf, 0) == 0) { |
11151 | 819 // make sure we can see in the signal handler that we have crash protection |
820 // installed | |
821 WatcherThread::watcher_thread()->set_crash_protection(this); | |
822 cb.call(); | |
823 // and clear the crash protection | |
824 WatcherThread::watcher_thread()->set_crash_protection(NULL); | |
825 return true; | |
826 } | |
827 // this happens when we siglongjmp() back | |
12141
cc56f122f3f7
8023720: (hotspot) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
11151
diff
changeset
|
828 pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL); |
11151 | 829 WatcherThread::watcher_thread()->set_crash_protection(NULL); |
830 return false; | |
831 } | |
832 | |
833 void os::WatcherThreadCrashProtection::restore() { | |
834 assert(WatcherThread::watcher_thread()->has_crash_protection(), | |
835 "must have crash protection"); | |
836 | |
837 siglongjmp(_jmpbuf, 1); | |
838 } | |
839 | |
840 void os::WatcherThreadCrashProtection::check_crash_protection(int sig, | |
841 Thread* thread) { | |
842 | |
843 if (thread != NULL && | |
844 thread->is_Watcher_thread() && | |
845 WatcherThread::watcher_thread()->has_crash_protection()) { | |
846 | |
847 if (sig == SIGSEGV || sig == SIGBUS) { | |
848 WatcherThread::watcher_thread()->crash_protection()->restore(); | |
849 } | |
850 } | |
851 } |