Mercurial > hg > truffle
annotate src/os/posix/vm/os_posix.cpp @ 21204:4a5df5570b7f
Truffle: make ReplaceObserver return a boolean in order to consume replace events. It can be useful for nodes to consume all replace events if they are always executed behind a @TruffleBoundary.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Mon, 04 May 2015 11:24:13 +0200 |
parents | 7848fc12602b |
children |
rev | line source |
---|---|
2204 | 1 /* |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
14460
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:
14460
diff
changeset
|
38 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
14460
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 | |
20360 | 77 int os::get_native_stack(address* stack, int frames, int toSkip) { |
6197 | 78 #ifdef _NMT_NOINLINE_ |
20360 | 79 toSkip++; |
6197 | 80 #endif |
20360 | 81 |
82 int frame_idx = 0; | |
83 int num_of_frames; // number of frames captured | |
6197 | 84 frame fr = os::current_frame(); |
20360 | 85 while (fr.pc() && frame_idx < frames) { |
86 if (toSkip > 0) { | |
87 toSkip --; | |
88 } else { | |
89 stack[frame_idx ++] = fr.pc(); | |
90 } | |
91 if (fr.fp() == NULL || os::is_first_C_frame(&fr) | |
92 ||fr.sender_pc() == NULL || fr.cb() != NULL) break; | |
93 | |
94 if (fr.sender_pc() && !os::is_first_C_frame(&fr)) { | |
95 fr = os::get_sender_for_C_frame(&fr); | |
96 } else { | |
97 break; | |
98 } | |
6197 | 99 } |
20360 | 100 num_of_frames = frame_idx; |
101 for (; frame_idx < frames; frame_idx ++) { | |
102 stack[frame_idx] = NULL; | |
6197 | 103 } |
20360 | 104 |
105 return num_of_frames; | |
106 } | |
107 | |
108 | |
109 bool os::unsetenv(const char* name) { | |
110 assert(name != NULL, "Null pointer"); | |
111 return (::unsetenv(name) == 0); | |
6197 | 112 } |
113 | |
4750
b16494a69d3d
7126185: Clean up lasterror handling, add os::get_last_error()
phh
parents:
2302
diff
changeset
|
114 int os::get_last_error() { |
b16494a69d3d
7126185: Clean up lasterror handling, add os::get_last_error()
phh
parents:
2302
diff
changeset
|
115 return errno; |
b16494a69d3d
7126185: Clean up lasterror handling, add os::get_last_error()
phh
parents:
2302
diff
changeset
|
116 } |
b16494a69d3d
7126185: Clean up lasterror handling, add os::get_last_error()
phh
parents:
2302
diff
changeset
|
117 |
2302
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
118 bool os::is_debugger_attached() { |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
119 // not implemented |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
120 return false; |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
121 } |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
122 |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
123 void os::wait_for_keypress_at_exit(void) { |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
124 // don't do anything on posix platforms |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
125 return; |
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
126 } |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
127 |
7433
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
128 // 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
|
129 // 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
|
130 // 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
|
131 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
|
132 assert((alignment & (os::vm_allocation_granularity() - 1)) == 0, |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
133 "Alignment must be a multiple of allocation granularity (page size)"); |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
134 assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned"); |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
135 |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
136 size_t extra_size = size + alignment; |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
137 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
|
138 |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
139 char* extra_base = os::reserve_memory(extra_size, NULL, alignment); |
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 if (extra_base == NULL) { |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
142 return NULL; |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
143 } |
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 // Do manual alignment |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
146 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
|
147 |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
148 // [ | | ] |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
149 // ^ extra_base |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
150 // ^ extra_base + begin_offset == aligned_base |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
151 // extra_base + begin_offset + size ^ |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
152 // extra_base + extra_size ^ |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
153 // |<>| == begin_offset |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
154 // end_offset == |<>| |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
155 size_t begin_offset = aligned_base - extra_base; |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
156 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
|
157 |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
158 if (begin_offset > 0) { |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
159 os::release_memory(extra_base, begin_offset); |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
160 } |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
161 |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
162 if (end_offset > 0) { |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
163 os::release_memory(extra_base + begin_offset + size, end_offset); |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
164 } |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
165 |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
166 return aligned_base; |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
167 } |
730cc4ddd550
7173959: Jvm crashed during coherence exabus (tmb) testing
brutisso
parents:
6842
diff
changeset
|
168 |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
169 void os::Posix::print_load_average(outputStream* st) { |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
170 st->print("load average:"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
171 double loadavg[3]; |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
172 os::loadavg(loadavg, 3); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
173 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
|
174 st->cr(); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
175 } |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
176 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
177 void os::Posix::print_rlimit_info(outputStream* st) { |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
178 st->print("rlimit:"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
179 struct rlimit rlim; |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
180 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
181 st->print(" STACK "); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
182 getrlimit(RLIMIT_STACK, &rlim); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
183 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
|
184 else st->print("%uk", rlim.rlim_cur >> 10); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
185 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
186 st->print(", CORE "); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
187 getrlimit(RLIMIT_CORE, &rlim); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
188 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
|
189 else st->print("%uk", rlim.rlim_cur >> 10); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
190 |
14410 | 191 // Isn't there on solaris |
14412 | 192 #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
|
193 st->print(", NPROC "); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
194 getrlimit(RLIMIT_NPROC, &rlim); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
195 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
|
196 else st->print("%d", rlim.rlim_cur); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
197 #endif |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
198 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
199 st->print(", NOFILE "); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
200 getrlimit(RLIMIT_NOFILE, &rlim); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
201 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
|
202 else st->print("%d", rlim.rlim_cur); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
203 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
204 st->print(", AS "); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
205 getrlimit(RLIMIT_AS, &rlim); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
206 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
|
207 else st->print("%uk", rlim.rlim_cur >> 10); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
208 st->cr(); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
209 } |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
210 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
211 void os::Posix::print_uname_info(outputStream* st) { |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
212 // kernel |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
213 st->print("uname:"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
214 struct utsname name; |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
215 uname(&name); |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
14460
diff
changeset
|
216 st->print("%s ", name.sysname); |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
14460
diff
changeset
|
217 st->print("%s ", name.release); |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
14460
diff
changeset
|
218 st->print("%s ", name.version); |
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
14460
diff
changeset
|
219 st->print("%s", name.machine); |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
220 st->cr(); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
221 } |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
222 |
8854
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
223 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
|
224 struct rlimit rlim; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
225 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
|
226 // 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
|
227 // on virtual memory. |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
228 bool result; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
229 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
|
230 result = false; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
231 } else { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
232 *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
|
233 result = true; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
234 } |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
235 #ifdef _LP64 |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
236 return result; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
237 #else |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
238 // 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
|
239 // 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
|
240 // directly use it. |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
241 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
|
242 if (result) { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
243 *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
|
244 } else { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
245 *limit = max_virtual_limit; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
246 } |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
4750
diff
changeset
|
247 |
8854
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
248 // 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
|
249 // 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
|
250 // 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
|
251 // 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
|
252 // 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
|
253 // 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
|
254 // 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
|
255 // 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
|
256 |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
257 // 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
|
258 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
|
259 |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
260 julong upper_limit = *limit; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
261 |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
262 // 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
|
263 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
|
264 *limit = upper_limit; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
265 } 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
|
266 // 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
|
267 // 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
|
268 *limit = min_allocation_size; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
269 } else { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
270 // perform the binary search. |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
271 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
|
272 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
|
273 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
|
274 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
|
275 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
|
276 lower_limit = temp_limit; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
277 } else { |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
278 upper_limit = temp_limit; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
279 } |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
280 } |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
281 *limit = lower_limit; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
282 } |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
283 return true; |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
284 #endif |
754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
tschatzl
parents:
7433
diff
changeset
|
285 } |
10195
e12c9b3740db
8012260: ciReplay: Include PID into the name of replay data file
vlivanov
parents:
8854
diff
changeset
|
286 |
e12c9b3740db
8012260: ciReplay: Include PID into the name of replay data file
vlivanov
parents:
8854
diff
changeset
|
287 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
|
288 return getcwd(buf, buflen); |
e12c9b3740db
8012260: ciReplay: Include PID into the name of replay data file
vlivanov
parents:
8854
diff
changeset
|
289 } |
e12c9b3740db
8012260: ciReplay: Include PID into the name of replay data file
vlivanov
parents:
8854
diff
changeset
|
290 |
e12c9b3740db
8012260: ciReplay: Include PID into the name of replay data file
vlivanov
parents:
8854
diff
changeset
|
291 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
|
292 return ::fdopen(fd, mode); |
e12c9b3740db
8012260: ciReplay: Include PID into the name of replay data file
vlivanov
parents:
8854
diff
changeset
|
293 } |
11151 | 294 |
12117
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
295 // 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
|
296 // 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
|
297 // Parameters: |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
298 // 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
|
299 // 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
|
300 // 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
|
301 // 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
|
302 // == 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
|
303 // such as "L" |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
304 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
|
305 bool is_absolute_path) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
306 char *agent_entry_name; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
307 size_t len; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
308 size_t name_len; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
309 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
|
310 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
|
311 const char *start; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
312 |
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 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
|
315 if (is_absolute_path) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
316 // 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
|
317 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
|
318 lib_name = ++start; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
319 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
320 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
|
321 return NULL; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
322 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
323 lib_name += prefix_len; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
324 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
|
325 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
326 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
327 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
|
328 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
|
329 if (agent_entry_name == NULL) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
330 return NULL; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
331 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
332 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
|
333 if (lib_name != NULL) { |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
334 strcat(agent_entry_name, "_"); |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
335 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
|
336 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
337 return agent_entry_name; |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
338 } |
f92b82d454fa
8014135: The JVMTI specification does not conform to recent changes in JNI specification
bpittore
parents:
11151
diff
changeset
|
339 |
14410 | 340 // Returned string is a constant. For unknown signals "UNKNOWN" is returned. |
341 const char* os::Posix::get_signal_name(int sig, char* out, size_t outlen) { | |
342 | |
343 static const struct { | |
344 int sig; const char* name; | |
345 } | |
346 info[] = | |
347 { | |
348 { SIGABRT, "SIGABRT" }, | |
349 #ifdef SIGAIO | |
350 { SIGAIO, "SIGAIO" }, | |
351 #endif | |
352 { SIGALRM, "SIGALRM" }, | |
353 #ifdef SIGALRM1 | |
354 { SIGALRM1, "SIGALRM1" }, | |
355 #endif | |
356 { SIGBUS, "SIGBUS" }, | |
357 #ifdef SIGCANCEL | |
358 { SIGCANCEL, "SIGCANCEL" }, | |
359 #endif | |
360 { SIGCHLD, "SIGCHLD" }, | |
361 #ifdef SIGCLD | |
362 { SIGCLD, "SIGCLD" }, | |
363 #endif | |
364 { SIGCONT, "SIGCONT" }, | |
365 #ifdef SIGCPUFAIL | |
366 { SIGCPUFAIL, "SIGCPUFAIL" }, | |
367 #endif | |
368 #ifdef SIGDANGER | |
369 { SIGDANGER, "SIGDANGER" }, | |
370 #endif | |
371 #ifdef SIGDIL | |
372 { SIGDIL, "SIGDIL" }, | |
373 #endif | |
374 #ifdef SIGEMT | |
375 { SIGEMT, "SIGEMT" }, | |
376 #endif | |
377 { SIGFPE, "SIGFPE" }, | |
378 #ifdef SIGFREEZE | |
379 { SIGFREEZE, "SIGFREEZE" }, | |
380 #endif | |
381 #ifdef SIGGFAULT | |
382 { SIGGFAULT, "SIGGFAULT" }, | |
383 #endif | |
384 #ifdef SIGGRANT | |
385 { SIGGRANT, "SIGGRANT" }, | |
386 #endif | |
387 { SIGHUP, "SIGHUP" }, | |
388 { SIGILL, "SIGILL" }, | |
389 { SIGINT, "SIGINT" }, | |
390 #ifdef SIGIO | |
391 { SIGIO, "SIGIO" }, | |
392 #endif | |
393 #ifdef SIGIOINT | |
394 { SIGIOINT, "SIGIOINT" }, | |
395 #endif | |
396 #ifdef SIGIOT | |
397 // SIGIOT is there for BSD compatibility, but on most Unices just a | |
398 // synonym for SIGABRT. The result should be "SIGABRT", not | |
399 // "SIGIOT". | |
400 #if (SIGIOT != SIGABRT ) | |
401 { SIGIOT, "SIGIOT" }, | |
402 #endif | |
403 #endif | |
404 #ifdef SIGKAP | |
405 { SIGKAP, "SIGKAP" }, | |
406 #endif | |
407 { SIGKILL, "SIGKILL" }, | |
408 #ifdef SIGLOST | |
409 { SIGLOST, "SIGLOST" }, | |
410 #endif | |
411 #ifdef SIGLWP | |
412 { SIGLWP, "SIGLWP" }, | |
413 #endif | |
414 #ifdef SIGLWPTIMER | |
415 { SIGLWPTIMER, "SIGLWPTIMER" }, | |
416 #endif | |
417 #ifdef SIGMIGRATE | |
418 { SIGMIGRATE, "SIGMIGRATE" }, | |
419 #endif | |
420 #ifdef SIGMSG | |
421 { SIGMSG, "SIGMSG" }, | |
422 #endif | |
423 { SIGPIPE, "SIGPIPE" }, | |
424 #ifdef SIGPOLL | |
425 { SIGPOLL, "SIGPOLL" }, | |
426 #endif | |
427 #ifdef SIGPRE | |
428 { SIGPRE, "SIGPRE" }, | |
429 #endif | |
430 { SIGPROF, "SIGPROF" }, | |
431 #ifdef SIGPTY | |
432 { SIGPTY, "SIGPTY" }, | |
433 #endif | |
434 #ifdef SIGPWR | |
435 { SIGPWR, "SIGPWR" }, | |
436 #endif | |
437 { SIGQUIT, "SIGQUIT" }, | |
438 #ifdef SIGRECONFIG | |
439 { SIGRECONFIG, "SIGRECONFIG" }, | |
440 #endif | |
441 #ifdef SIGRECOVERY | |
442 { SIGRECOVERY, "SIGRECOVERY" }, | |
443 #endif | |
444 #ifdef SIGRESERVE | |
445 { SIGRESERVE, "SIGRESERVE" }, | |
446 #endif | |
447 #ifdef SIGRETRACT | |
448 { SIGRETRACT, "SIGRETRACT" }, | |
449 #endif | |
450 #ifdef SIGSAK | |
451 { SIGSAK, "SIGSAK" }, | |
452 #endif | |
453 { SIGSEGV, "SIGSEGV" }, | |
454 #ifdef SIGSOUND | |
455 { SIGSOUND, "SIGSOUND" }, | |
456 #endif | |
457 { SIGSTOP, "SIGSTOP" }, | |
458 { SIGSYS, "SIGSYS" }, | |
459 #ifdef SIGSYSERROR | |
460 { SIGSYSERROR, "SIGSYSERROR" }, | |
461 #endif | |
462 #ifdef SIGTALRM | |
463 { SIGTALRM, "SIGTALRM" }, | |
464 #endif | |
465 { SIGTERM, "SIGTERM" }, | |
466 #ifdef SIGTHAW | |
467 { SIGTHAW, "SIGTHAW" }, | |
468 #endif | |
469 { SIGTRAP, "SIGTRAP" }, | |
470 #ifdef SIGTSTP | |
471 { SIGTSTP, "SIGTSTP" }, | |
472 #endif | |
473 { SIGTTIN, "SIGTTIN" }, | |
474 { SIGTTOU, "SIGTTOU" }, | |
475 #ifdef SIGURG | |
476 { SIGURG, "SIGURG" }, | |
477 #endif | |
478 { SIGUSR1, "SIGUSR1" }, | |
479 { SIGUSR2, "SIGUSR2" }, | |
480 #ifdef SIGVIRT | |
481 { SIGVIRT, "SIGVIRT" }, | |
482 #endif | |
483 { SIGVTALRM, "SIGVTALRM" }, | |
484 #ifdef SIGWAITING | |
485 { SIGWAITING, "SIGWAITING" }, | |
486 #endif | |
487 #ifdef SIGWINCH | |
488 { SIGWINCH, "SIGWINCH" }, | |
489 #endif | |
490 #ifdef SIGWINDOW | |
491 { SIGWINDOW, "SIGWINDOW" }, | |
492 #endif | |
493 { SIGXCPU, "SIGXCPU" }, | |
494 { SIGXFSZ, "SIGXFSZ" }, | |
495 #ifdef SIGXRES | |
496 { SIGXRES, "SIGXRES" }, | |
497 #endif | |
498 { -1, NULL } | |
499 }; | |
500 | |
501 const char* ret = NULL; | |
502 | |
503 #ifdef SIGRTMIN | |
504 if (sig >= SIGRTMIN && sig <= SIGRTMAX) { | |
505 if (sig == SIGRTMIN) { | |
506 ret = "SIGRTMIN"; | |
507 } else if (sig == SIGRTMAX) { | |
508 ret = "SIGRTMAX"; | |
509 } else { | |
510 jio_snprintf(out, outlen, "SIGRTMIN+%d", sig - SIGRTMIN); | |
511 return out; | |
512 } | |
513 } | |
514 #endif | |
515 | |
516 if (sig > 0) { | |
517 for (int idx = 0; info[idx].sig != -1; idx ++) { | |
518 if (info[idx].sig == sig) { | |
519 ret = info[idx].name; | |
520 break; | |
521 } | |
522 } | |
523 } | |
524 | |
525 if (!ret) { | |
526 if (!is_valid_signal(sig)) { | |
527 ret = "INVALID"; | |
528 } else { | |
529 ret = "UNKNOWN"; | |
530 } | |
531 } | |
532 | |
533 jio_snprintf(out, outlen, ret); | |
534 return out; | |
535 } | |
536 | |
537 // Returns true if signal number is valid. | |
538 bool os::Posix::is_valid_signal(int sig) { | |
539 // MacOS not really POSIX compliant: sigaddset does not return | |
540 // an error for invalid signal numbers. However, MacOS does not | |
541 // support real time signals and simply seems to have just 33 | |
542 // signals with no holes in the signal range. | |
543 #ifdef __APPLE__ | |
544 return sig >= 1 && sig < NSIG; | |
545 #else | |
546 // Use sigaddset to check for signal validity. | |
547 sigset_t set; | |
548 if (sigaddset(&set, sig) == -1 && errno == EINVAL) { | |
549 return false; | |
550 } | |
551 return true; | |
552 #endif | |
553 } | |
554 | |
555 #define NUM_IMPORTANT_SIGS 32 | |
556 // Returns one-line short description of a signal set in a user provided buffer. | |
557 const char* os::Posix::describe_signal_set_short(const sigset_t* set, char* buffer, size_t buf_size) { | |
14411 | 558 assert(buf_size == (NUM_IMPORTANT_SIGS + 1), "wrong buffer size"); |
14410 | 559 // Note: for shortness, just print out the first 32. That should |
560 // cover most of the useful ones, apart from realtime signals. | |
561 for (int sig = 1; sig <= NUM_IMPORTANT_SIGS; sig++) { | |
562 const int rc = sigismember(set, sig); | |
563 if (rc == -1 && errno == EINVAL) { | |
564 buffer[sig-1] = '?'; | |
565 } else { | |
566 buffer[sig-1] = rc == 0 ? '0' : '1'; | |
567 } | |
568 } | |
569 buffer[NUM_IMPORTANT_SIGS] = 0; | |
570 return buffer; | |
571 } | |
572 | |
573 // Prints one-line description of a signal set. | |
574 void os::Posix::print_signal_set_short(outputStream* st, const sigset_t* set) { | |
575 char buf[NUM_IMPORTANT_SIGS + 1]; | |
576 os::Posix::describe_signal_set_short(set, buf, sizeof(buf)); | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
14460
diff
changeset
|
577 st->print("%s", buf); |
14410 | 578 } |
579 | |
580 // Writes one-line description of a combination of sigaction.sa_flags into a user | |
581 // provided buffer. Returns that buffer. | |
582 const char* os::Posix::describe_sa_flags(int flags, char* buffer, size_t size) { | |
583 char* p = buffer; | |
584 size_t remaining = size; | |
585 bool first = true; | |
586 int idx = 0; | |
587 | |
588 assert(buffer, "invalid argument"); | |
589 | |
590 if (size == 0) { | |
591 return buffer; | |
592 } | |
593 | |
594 strncpy(buffer, "none", size); | |
595 | |
596 const struct { | |
597 int i; | |
598 const char* s; | |
599 } flaginfo [] = { | |
600 { SA_NOCLDSTOP, "SA_NOCLDSTOP" }, | |
601 { SA_ONSTACK, "SA_ONSTACK" }, | |
602 { SA_RESETHAND, "SA_RESETHAND" }, | |
603 { SA_RESTART, "SA_RESTART" }, | |
604 { SA_SIGINFO, "SA_SIGINFO" }, | |
605 { SA_NOCLDWAIT, "SA_NOCLDWAIT" }, | |
606 { SA_NODEFER, "SA_NODEFER" }, | |
607 #ifdef AIX | |
608 { SA_ONSTACK, "SA_ONSTACK" }, | |
609 { SA_OLDSTYLE, "SA_OLDSTYLE" }, | |
610 #endif | |
611 { 0, NULL } | |
612 }; | |
613 | |
614 for (idx = 0; flaginfo[idx].s && remaining > 1; idx++) { | |
615 if (flags & flaginfo[idx].i) { | |
616 if (first) { | |
617 jio_snprintf(p, remaining, "%s", flaginfo[idx].s); | |
618 first = false; | |
619 } else { | |
620 jio_snprintf(p, remaining, "|%s", flaginfo[idx].s); | |
621 } | |
622 const size_t len = strlen(p); | |
623 p += len; | |
624 remaining -= len; | |
625 } | |
626 } | |
627 | |
628 buffer[size - 1] = '\0'; | |
629 | |
630 return buffer; | |
631 } | |
632 | |
633 // Prints one-line description of a combination of sigaction.sa_flags. | |
634 void os::Posix::print_sa_flags(outputStream* st, int flags) { | |
635 char buffer[0x100]; | |
636 os::Posix::describe_sa_flags(flags, buffer, sizeof(buffer)); | |
17937
78bbf4d43a14
8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents:
14460
diff
changeset
|
637 st->print("%s", buffer); |
14410 | 638 } |
639 | |
640 // Helper function for os::Posix::print_siginfo_...(): | |
641 // return a textual description for signal code. | |
642 struct enum_sigcode_desc_t { | |
643 const char* s_name; | |
644 const char* s_desc; | |
645 }; | |
646 | |
647 static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t* out) { | |
648 | |
649 const struct { | |
650 int sig; int code; const char* s_code; const char* s_desc; | |
651 } t1 [] = { | |
652 { SIGILL, ILL_ILLOPC, "ILL_ILLOPC", "Illegal opcode." }, | |
653 { SIGILL, ILL_ILLOPN, "ILL_ILLOPN", "Illegal operand." }, | |
654 { SIGILL, ILL_ILLADR, "ILL_ILLADR", "Illegal addressing mode." }, | |
655 { SIGILL, ILL_ILLTRP, "ILL_ILLTRP", "Illegal trap." }, | |
656 { SIGILL, ILL_PRVOPC, "ILL_PRVOPC", "Privileged opcode." }, | |
657 { SIGILL, ILL_PRVREG, "ILL_PRVREG", "Privileged register." }, | |
658 { SIGILL, ILL_COPROC, "ILL_COPROC", "Coprocessor error." }, | |
659 { SIGILL, ILL_BADSTK, "ILL_BADSTK", "Internal stack error." }, | |
660 #if defined(IA64) && defined(LINUX) | |
661 { SIGILL, ILL_BADIADDR, "ILL_BADIADDR", "Unimplemented instruction address" }, | |
662 { SIGILL, ILL_BREAK, "ILL_BREAK", "Application Break instruction" }, | |
663 #endif | |
664 { SIGFPE, FPE_INTDIV, "FPE_INTDIV", "Integer divide by zero." }, | |
665 { SIGFPE, FPE_INTOVF, "FPE_INTOVF", "Integer overflow." }, | |
666 { SIGFPE, FPE_FLTDIV, "FPE_FLTDIV", "Floating-point divide by zero." }, | |
667 { SIGFPE, FPE_FLTOVF, "FPE_FLTOVF", "Floating-point overflow." }, | |
668 { SIGFPE, FPE_FLTUND, "FPE_FLTUND", "Floating-point underflow." }, | |
669 { SIGFPE, FPE_FLTRES, "FPE_FLTRES", "Floating-point inexact result." }, | |
670 { SIGFPE, FPE_FLTINV, "FPE_FLTINV", "Invalid floating-point operation." }, | |
671 { SIGFPE, FPE_FLTSUB, "FPE_FLTSUB", "Subscript out of range." }, | |
672 { SIGSEGV, SEGV_MAPERR, "SEGV_MAPERR", "Address not mapped to object." }, | |
673 { SIGSEGV, SEGV_ACCERR, "SEGV_ACCERR", "Invalid permissions for mapped object." }, | |
674 #ifdef AIX | |
675 // no explanation found what keyerr would be | |
676 { SIGSEGV, SEGV_KEYERR, "SEGV_KEYERR", "key error" }, | |
677 #endif | |
678 #if defined(IA64) && !defined(AIX) | |
679 { SIGSEGV, SEGV_PSTKOVF, "SEGV_PSTKOVF", "Paragraph stack overflow" }, | |
680 #endif | |
681 { SIGBUS, BUS_ADRALN, "BUS_ADRALN", "Invalid address alignment." }, | |
682 { SIGBUS, BUS_ADRERR, "BUS_ADRERR", "Nonexistent physical address." }, | |
683 { SIGBUS, BUS_OBJERR, "BUS_OBJERR", "Object-specific hardware error." }, | |
684 { SIGTRAP, TRAP_BRKPT, "TRAP_BRKPT", "Process breakpoint." }, | |
685 { SIGTRAP, TRAP_TRACE, "TRAP_TRACE", "Process trace trap." }, | |
686 { SIGCHLD, CLD_EXITED, "CLD_EXITED", "Child has exited." }, | |
687 { SIGCHLD, CLD_KILLED, "CLD_KILLED", "Child has terminated abnormally and did not create a core file." }, | |
688 { SIGCHLD, CLD_DUMPED, "CLD_DUMPED", "Child has terminated abnormally and created a core file." }, | |
689 { SIGCHLD, CLD_TRAPPED, "CLD_TRAPPED", "Traced child has trapped." }, | |
690 { SIGCHLD, CLD_STOPPED, "CLD_STOPPED", "Child has stopped." }, | |
691 { SIGCHLD, CLD_CONTINUED,"CLD_CONTINUED","Stopped child has continued." }, | |
692 #ifdef SIGPOLL | |
693 { SIGPOLL, POLL_OUT, "POLL_OUT", "Output buffers available." }, | |
694 { SIGPOLL, POLL_MSG, "POLL_MSG", "Input message available." }, | |
695 { SIGPOLL, POLL_ERR, "POLL_ERR", "I/O error." }, | |
696 { SIGPOLL, POLL_PRI, "POLL_PRI", "High priority input available." }, | |
697 { SIGPOLL, POLL_HUP, "POLL_HUP", "Device disconnected. [Option End]" }, | |
698 #endif | |
699 { -1, -1, NULL, NULL } | |
700 }; | |
701 | |
702 // Codes valid in any signal context. | |
703 const struct { | |
704 int code; const char* s_code; const char* s_desc; | |
705 } t2 [] = { | |
706 { SI_USER, "SI_USER", "Signal sent by kill()." }, | |
707 { SI_QUEUE, "SI_QUEUE", "Signal sent by the sigqueue()." }, | |
708 { SI_TIMER, "SI_TIMER", "Signal generated by expiration of a timer set by timer_settime()." }, | |
709 { SI_ASYNCIO, "SI_ASYNCIO", "Signal generated by completion of an asynchronous I/O request." }, | |
710 { SI_MESGQ, "SI_MESGQ", "Signal generated by arrival of a message on an empty message queue." }, | |
711 // Linux specific | |
712 #ifdef SI_TKILL | |
713 { SI_TKILL, "SI_TKILL", "Signal sent by tkill (pthread_kill)" }, | |
714 #endif | |
715 #ifdef SI_DETHREAD | |
716 { SI_DETHREAD, "SI_DETHREAD", "Signal sent by execve() killing subsidiary threads" }, | |
717 #endif | |
718 #ifdef SI_KERNEL | |
719 { SI_KERNEL, "SI_KERNEL", "Signal sent by kernel." }, | |
720 #endif | |
721 #ifdef SI_SIGIO | |
722 { SI_SIGIO, "SI_SIGIO", "Signal sent by queued SIGIO" }, | |
723 #endif | |
724 | |
725 #ifdef AIX | |
726 { SI_UNDEFINED, "SI_UNDEFINED","siginfo contains partial information" }, | |
727 { SI_EMPTY, "SI_EMPTY", "siginfo contains no useful information" }, | |
728 #endif | |
729 | |
730 #ifdef __sun | |
731 { SI_NOINFO, "SI_NOINFO", "No signal information" }, | |
732 { SI_RCTL, "SI_RCTL", "kernel generated signal via rctl action" }, | |
733 { SI_LWP, "SI_LWP", "Signal sent via lwp_kill" }, | |
734 #endif | |
735 | |
736 { -1, NULL, NULL } | |
737 }; | |
738 | |
739 const char* s_code = NULL; | |
740 const char* s_desc = NULL; | |
741 | |
742 for (int i = 0; t1[i].sig != -1; i ++) { | |
743 if (t1[i].sig == si->si_signo && t1[i].code == si->si_code) { | |
744 s_code = t1[i].s_code; | |
745 s_desc = t1[i].s_desc; | |
746 break; | |
747 } | |
748 } | |
749 | |
750 if (s_code == NULL) { | |
751 for (int i = 0; t2[i].s_code != NULL; i ++) { | |
752 if (t2[i].code == si->si_code) { | |
753 s_code = t2[i].s_code; | |
754 s_desc = t2[i].s_desc; | |
755 } | |
756 } | |
757 } | |
758 | |
759 if (s_code == NULL) { | |
760 out->s_name = "unknown"; | |
761 out->s_desc = "unknown"; | |
762 return false; | |
763 } | |
764 | |
765 out->s_name = s_code; | |
766 out->s_desc = s_desc; | |
767 | |
768 return true; | |
769 } | |
770 | |
771 // A POSIX conform, platform-independend siginfo print routine. | |
772 // Short print out on one line. | |
773 void os::Posix::print_siginfo_brief(outputStream* os, const siginfo_t* si) { | |
774 char buf[20]; | |
775 os->print("siginfo: "); | |
776 | |
777 if (!si) { | |
778 os->print("<null>"); | |
779 return; | |
780 } | |
781 | |
782 // See print_siginfo_full() for details. | |
783 const int sig = si->si_signo; | |
784 | |
785 os->print("si_signo: %d (%s)", sig, os::Posix::get_signal_name(sig, buf, sizeof(buf))); | |
786 | |
787 enum_sigcode_desc_t ed; | |
788 if (get_signal_code_description(si, &ed)) { | |
789 os->print(", si_code: %d (%s)", si->si_code, ed.s_name); | |
790 } else { | |
791 os->print(", si_code: %d (unknown)", si->si_code); | |
792 } | |
793 | |
794 if (si->si_errno) { | |
795 os->print(", si_errno: %d", si->si_errno); | |
796 } | |
797 | |
798 const int me = (int) ::getpid(); | |
799 const int pid = (int) si->si_pid; | |
800 | |
801 if (si->si_code == SI_USER || si->si_code == SI_QUEUE) { | |
802 if (IS_VALID_PID(pid) && pid != me) { | |
803 os->print(", sent from pid: %d (uid: %d)", pid, (int) si->si_uid); | |
804 } | |
805 } else if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || | |
806 sig == SIGTRAP || sig == SIGFPE) { | |
807 os->print(", si_addr: " PTR_FORMAT, si->si_addr); | |
808 #ifdef SIGPOLL | |
809 } else if (sig == SIGPOLL) { | |
810 os->print(", si_band: " PTR64_FORMAT, (uint64_t)si->si_band); | |
811 #endif | |
812 } else if (sig == SIGCHLD) { | |
813 os->print_cr(", si_pid: %d, si_uid: %d, si_status: %d", (int) si->si_pid, si->si_uid, si->si_status); | |
814 } | |
815 } | |
816 | |
11151 | 817 os::WatcherThreadCrashProtection::WatcherThreadCrashProtection() { |
818 assert(Thread::current()->is_Watcher_thread(), "Must be WatcherThread"); | |
819 } | |
820 | |
821 /* | |
822 * See the caveats for this class in os_posix.hpp | |
823 * Protects the callback call so that SIGSEGV / SIGBUS jumps back into this | |
824 * method and returns false. If none of the signals are raised, returns true. | |
825 * The callback is supposed to provide the method that should be protected. | |
826 */ | |
827 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
|
828 sigset_t saved_sig_mask; |
cc56f122f3f7
8023720: (hotspot) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
11151
diff
changeset
|
829 |
11151 | 830 assert(Thread::current()->is_Watcher_thread(), "Only for WatcherThread"); |
831 assert(!WatcherThread::watcher_thread()->has_crash_protection(), | |
832 "crash_protection already set?"); | |
833 | |
12141
cc56f122f3f7
8023720: (hotspot) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
11151
diff
changeset
|
834 // 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
|
835 // 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
|
836 // for the process, not the thread |
cc56f122f3f7
8023720: (hotspot) setjmp/longjmp changes the process signal mask on OS X
sla
parents:
11151
diff
changeset
|
837 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
|
838 if (sigsetjmp(_jmpbuf, 0) == 0) { |
11151 | 839 // make sure we can see in the signal handler that we have crash protection |
840 // installed | |
841 WatcherThread::watcher_thread()->set_crash_protection(this); | |
842 cb.call(); | |
843 // and clear the crash protection | |
844 WatcherThread::watcher_thread()->set_crash_protection(NULL); | |
845 return true; | |
846 } | |
847 // 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
|
848 pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL); |
11151 | 849 WatcherThread::watcher_thread()->set_crash_protection(NULL); |
850 return false; | |
851 } | |
852 | |
853 void os::WatcherThreadCrashProtection::restore() { | |
854 assert(WatcherThread::watcher_thread()->has_crash_protection(), | |
855 "must have crash protection"); | |
856 | |
857 siglongjmp(_jmpbuf, 1); | |
858 } | |
859 | |
860 void os::WatcherThreadCrashProtection::check_crash_protection(int sig, | |
861 Thread* thread) { | |
862 | |
863 if (thread != NULL && | |
864 thread->is_Watcher_thread() && | |
865 WatcherThread::watcher_thread()->has_crash_protection()) { | |
866 | |
867 if (sig == SIGSEGV || sig == SIGBUS) { | |
868 WatcherThread::watcher_thread()->crash_protection()->restore(); | |
869 } | |
870 } | |
871 } |