Print this page
11210 libm should be cstyle(1ONBLD) clean
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libm/common/m9x/fex_log.c
+++ new/usr/src/lib/libm/common/m9x/fex_log.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
24 24 */
25 +
25 26 /*
26 27 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
27 28 * Use is subject to license terms.
28 29 */
29 30
30 31 #pragma weak __fex_get_log = fex_get_log
31 32 #pragma weak __fex_set_log = fex_set_log
32 33 #pragma weak __fex_get_log_depth = fex_get_log_depth
33 34 #pragma weak __fex_set_log_depth = fex_set_log_depth
34 35 #pragma weak __fex_log_entry = fex_log_entry
35 36
36 37 #include <stdio.h>
37 38 #include <stdlib.h>
38 39 #include <unistd.h>
39 40 #include <string.h>
40 41 #include <signal.h>
41 42 #include <ucontext.h>
42 43 #include <sys/frame.h>
43 44 #include <fenv.h>
44 45 #include <sys/ieeefp.h>
45 46 #include <thread.h>
46 47 #include "fex_handler.h"
47 48
48 49 #if !defined(PC)
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
49 50 #if defined(REG_PC)
50 51 #define PC REG_PC
51 52 #else
52 53 #error Neither PC nor REG_PC is defined!
53 54 #endif
54 55 #endif
55 56
56 57 static FILE *log_fp = NULL;
57 58 static mutex_t log_lock = DEFAULTMUTEX;
58 59 static int log_depth = 100;
59 -
60 -FILE *fex_get_log(void)
60 +FILE *
61 +fex_get_log(void)
61 62 {
62 - FILE *fp;
63 + FILE *fp;
63 64
64 65 mutex_lock(&log_lock);
65 66 fp = log_fp;
66 67 mutex_unlock(&log_lock);
67 - return fp;
68 + return (fp);
68 69 }
69 70
70 -int fex_set_log(FILE *fp)
71 +int
72 +fex_set_log(FILE *fp)
71 73 {
72 74 mutex_lock(&log_lock);
73 75 log_fp = fp;
74 76 mutex_unlock(&log_lock);
75 77 __fex_update_te();
76 - return 1;
78 + return (1);
77 79 }
78 80
79 -int fex_get_log_depth(void)
81 +int
82 +fex_get_log_depth(void)
80 83 {
81 - int d;
84 + int d;
82 85
83 86 mutex_lock(&log_lock);
84 87 d = log_depth;
85 88 mutex_unlock(&log_lock);
86 - return d;
89 + return (d);
87 90 }
88 91
89 -int fex_set_log_depth(int d)
92 +int
93 +fex_set_log_depth(int d)
90 94 {
91 95 if (d < 0)
92 - return 0;
96 + return (0);
97 +
93 98 mutex_lock(&log_lock);
94 99 log_depth = d;
95 100 mutex_unlock(&log_lock);
96 - return 1;
101 + return (1);
97 102 }
98 103
99 104 static struct exc_list {
100 - struct exc_list *next;
101 - char *addr;
102 - unsigned long code;
103 - int nstack;
104 - char *stack[1]; /* actual length is max(1,nstack) */
105 + struct exc_list *next;
106 + char *addr;
107 + unsigned long code;
108 + int nstack;
109 + char *stack[1]; /* actual length is max(1,nstack) */
105 110 } *list = NULL;
106 111
107 112 #ifdef __sparcv9
108 -#define FRAMEP(X) (struct frame *)((char*)(X)+(((long)(X)&1)?2047:0))
113 +#define FRAMEP(X) (struct frame *)((char *)(X) + (((long)(X) & \
114 + 1) ? 2047 : 0))
109 115 #else
110 -#define FRAMEP(X) (struct frame *)(X)
116 +#define FRAMEP(X) (struct frame *)(X)
111 117 #endif
112 118
113 119 #ifdef _LP64
114 -#define PDIG "16"
120 +#define PDIG "16"
115 121 #else
116 -#define PDIG "8"
122 +#define PDIG "8"
117 123 #endif
118 124
119 -/* look for a matching exc_list; return 1 if one is found,
120 - otherwise add this one to the list and return 0 */
121 -static int check_exc_list(char *addr, unsigned long code, char *stk,
122 - struct frame *fp)
125 +/*
126 + * look for a matching exc_list; return 1 if one is found,
127 + * otherwise add this one to the list and return 0
128 + */
129 +static int
130 +check_exc_list(char *addr, unsigned long code, char *stk, struct frame *fp)
123 131 {
124 - struct exc_list *l, *ll = NULL;
125 - struct frame *f;
126 - int i, n;
132 + struct exc_list *l, *ll = NULL;
133 + struct frame *f;
134 + int i, n;
127 135
128 136 if (list) {
129 137 for (l = list; l; ll = l, l = l->next) {
130 138 if (l->addr != addr || l->code != code)
131 139 continue;
140 +
132 141 if (log_depth < 1 || l->nstack < 1)
133 - return 1;
142 + return (1);
143 +
134 144 if (l->stack[0] != stk)
135 145 continue;
146 +
136 147 n = 1;
148 +
137 149 for (i = 1, f = fp; i < log_depth && i < l->nstack &&
138 150 f && f->fr_savpc; i++, f = FRAMEP(f->fr_savfp))
139 151 if (l->stack[i] != (char *)f->fr_savpc) {
140 152 n = 0;
141 153 break;
142 154 }
155 +
143 156 if (n)
144 - return 1;
157 + return (1);
145 158 }
146 159 }
147 160
148 161 /* create a new exc_list structure and tack it on the list */
149 162 for (n = 1, f = fp; n < log_depth && f && f->fr_savpc;
150 - n++, f = FRAMEP(f->fr_savfp)) ;
151 - if ((l = (struct exc_list *)malloc(sizeof(struct exc_list) +
152 - (n - 1) * sizeof(char *))) != NULL) {
163 + n++, f = FRAMEP(f->fr_savfp))
164 + ;
165 +
166 + if ((l = (struct exc_list *)malloc(sizeof (struct exc_list) + (n - 1) *
167 + sizeof (char *))) != NULL) {
153 168 l->next = NULL;
154 169 l->addr = addr;
155 170 l->code = code;
156 - l->nstack = ((log_depth < 1)? 0 : n);
171 + l->nstack = ((log_depth < 1) ? 0 : n);
157 172 l->stack[0] = stk;
173 +
158 174 for (i = 1; i < n; i++) {
159 175 l->stack[i] = (char *)fp->fr_savpc;
160 176 fp = FRAMEP(fp->fr_savfp);
161 177 }
178 +
162 179 if (list)
163 180 ll->next = l;
164 181 else
165 182 list = l;
166 183 }
167 - return 0;
184 +
185 + return (0);
168 186 }
169 187
170 188 /*
171 -* Warning: cleverness ahead
172 -*
173 -* In the following code, the use of sprintf+write rather than fprintf
174 -* to send output to the log file is intentional. The reason is that
175 -* fprintf is not async-signal-safe. "But," you protest, "SIGFPE is
176 -* not an asynchronous signal! It's always handled by the same thread
177 -* that executed the fpop that provoked it." That's true, but a prob-
178 -* lem arises because (i) base conversion in fprintf can cause a fp
179 -* exception and (ii) my signal handler acquires a mutex lock before
180 -* sending output to the log file (so that outputs for entries from
181 -* different threads aren't interspersed). Therefore, if the code
182 -* were to use fprintf, a deadlock could occur as follows:
183 -*
184 -* Thread A Thread B
185 -*
186 -* Incurs a fp exception, Calls fprintf,
187 -* acquires log_lock acquires file rmutex lock
188 -*
189 -* Calls fprintf, Incurs a fp exception,
190 -* waits for file rmutex lock waits for log_lock
191 -*
192 -* (I could just verify that fprintf doesn't hold the rmutex lock while
193 -* it's doing the base conversion, but since efficiency is of little
194 -* concern here, I opted for the safe and dumb route.)
195 -*/
196 -
197 -static void print_stack(int fd, char *addr, struct frame *fp)
189 + * Warning: cleverness ahead
190 + *
191 + * In the following code, the use of sprintf+write rather than fprintf
192 + * to send output to the log file is intentional. The reason is that
193 + * fprintf is not async-signal-safe. "But," you protest, "SIGFPE is
194 + * not an asynchronous signal! It's always handled by the same thread
195 + * that executed the fpop that provoked it." That's true, but a prob-
196 + * lem arises because (i) base conversion in fprintf can cause a fp
197 + * exception and (ii) my signal handler acquires a mutex lock before
198 + * sending output to the log file (so that outputs for entries from
199 + * different threads aren't interspersed). Therefore, if the code
200 + * were to use fprintf, a deadlock could occur as follows:
201 + *
202 + * Thread A Thread B
203 + *
204 + * Incurs a fp exception, Calls fprintf,
205 + * acquires log_lock acquires file rmutex lock
206 + *
207 + * Calls fprintf, Incurs a fp exception,
208 + * waits for file rmutex lock waits for log_lock
209 + *
210 + * (I could just verify that fprintf doesn't hold the rmutex lock while
211 + * it's doing the base conversion, but since efficiency is of little
212 + * concern here, I opted for the safe and dumb route.)
213 + */
214 +static void
215 +print_stack(int fd, char *addr, struct frame *fp)
198 216 {
199 - int i;
200 - char *name, buf[30];
217 + int i;
218 + char *name, buf[30];
201 219
202 220 for (i = 0; i < log_depth && addr != NULL; i++) {
203 221 if (__fex_sym(addr, &name) != NULL) {
204 222 write(fd, buf, sprintf(buf, " 0x%0" PDIG "lx ",
205 223 (long)addr));
206 224 write(fd, name, strlen(name));
207 225 write(fd, "\n", 1);
208 - if (!strcmp(name, "main"))
226 +
227 + if (strcmp(name, "main") == 0)
209 228 break;
210 229 } else {
211 230 write(fd, buf, sprintf(buf, " 0x%0" PDIG "lx\n",
212 231 (long)addr));
213 232 }
233 +
214 234 if (fp == NULL)
215 235 break;
236 +
216 237 addr = (char *)fp->fr_savpc;
217 238 fp = FRAMEP(fp->fr_savfp);
218 239 }
219 240 }
220 241
221 -void fex_log_entry(const char *msg)
242 +void
243 +fex_log_entry(const char *msg)
222 244 {
223 - ucontext_t uc;
224 - struct frame *fp;
225 - char *stk;
226 - int fd;
245 + ucontext_t uc;
246 + struct frame *fp;
247 + char *stk;
248 + int fd;
227 249
228 250 /* if logging is disabled, just return */
229 251 mutex_lock(&log_lock);
252 +
230 253 if (log_fp == NULL) {
231 254 mutex_unlock(&log_lock);
232 255 return;
233 256 }
234 257
235 - /* get the frame pointer from the current context and
236 - pop our own frame */
258 + /*
259 + * get the frame pointer from the current context and
260 + * pop our own frame
261 + */
237 262 getcontext(&uc);
238 263 #if defined(__sparc) || defined(__amd64)
239 264 fp = FRAMEP(uc.uc_mcontext.gregs[REG_SP]);
240 -#elif defined(__i386) /* !defined(__amd64) */
265 +#elif defined(__i386) /* !defined(__amd64) */
241 266 fp = FRAMEP(uc.uc_mcontext.gregs[EBP]);
242 267 #else
243 268 #error Unknown architecture
244 269 #endif
270 +
245 271 if (fp == NULL) {
246 272 mutex_unlock(&log_lock);
247 273 return;
248 274 }
275 +
249 276 stk = (char *)fp->fr_savpc;
250 277 fp = FRAMEP(fp->fr_savfp);
251 278
252 279 /* if we've already logged this message here, don't make an entry */
253 280 if (check_exc_list(stk, (unsigned long)msg, stk, fp)) {
254 281 mutex_unlock(&log_lock);
255 282 return;
256 283 }
257 284
258 285 /* make an entry */
259 286 fd = fileno(log_fp);
260 287 write(fd, "fex_log_entry: ", 15);
261 288 write(fd, msg, strlen(msg));
262 289 write(fd, "\n", 1);
263 290 __fex_sym_init();
264 291 print_stack(fd, stk, fp);
265 292 mutex_unlock(&log_lock);
266 293 }
267 294
268 295 static const char *exception[FEX_NUM_EXC] = {
269 - "inexact result",
270 - "division by zero",
271 - "underflow",
272 - "overflow",
273 - "invalid operation (0/0)",
274 - "invalid operation (inf/inf)",
275 - "invalid operation (inf-inf)",
276 - "invalid operation (0*inf)",
277 - "invalid operation (sqrt)",
278 - "invalid operation (snan)",
279 - "invalid operation (int)",
280 - "invalid operation (cmp)"
296 + "inexact result", "division by zero", "underflow", "overflow",
297 + "invalid operation (0/0)", "invalid operation (inf/inf)",
298 + "invalid operation (inf-inf)", "invalid operation (0*inf)",
299 + "invalid operation (sqrt)", "invalid operation (snan)",
300 + "invalid operation (int)", "invalid operation (cmp)"
281 301 };
282 302
283 303 void
284 -__fex_mklog(ucontext_t *uap, char *addr, int f, enum fex_exception e,
285 - int m, void *p)
304 +__fex_mklog(ucontext_t *uap, char *addr, int f, enum fex_exception e, int m,
305 + void *p)
286 306 {
287 - struct frame *fp;
288 - char *stk, *name, buf[30];
289 - int fd;
307 + struct frame *fp;
308 + char *stk, *name, buf[30];
309 + int fd;
290 310
291 311 /* if logging is disabled, just return */
292 312 mutex_lock(&log_lock);
313 +
293 314 if (log_fp == NULL) {
294 315 mutex_unlock(&log_lock);
295 316 return;
296 317 }
297 318
298 319 /* get stack info */
299 320 #if defined(__sparc)
300 - stk = (char*)uap->uc_mcontext.gregs[REG_PC];
321 + stk = (char *)uap->uc_mcontext.gregs[REG_PC];
301 322 fp = FRAMEP(uap->uc_mcontext.gregs[REG_SP]);
302 323 #elif defined(__amd64)
303 - stk = (char*)uap->uc_mcontext.gregs[REG_PC];
324 + stk = (char *)uap->uc_mcontext.gregs[REG_PC];
304 325 fp = FRAMEP(uap->uc_mcontext.gregs[REG_RBP]);
305 -#elif defined(__i386) /* !defined(__amd64) */
306 - stk = (char*)uap->uc_mcontext.gregs[PC];
326 +#elif defined(__i386) /* !defined(__amd64) */
327 + stk = (char *)uap->uc_mcontext.gregs[PC];
307 328 fp = FRAMEP(uap->uc_mcontext.gregs[EBP]);
308 329 #else
309 330 #error Unknown architecture
310 331 #endif
311 332
312 - /* if the handling mode is the default and this exception's
313 - flag is already raised, don't make an entry */
333 + /*
334 + * if the handling mode is the default and this exception's
335 + * flag is already raised, don't make an entry
336 + */
314 337 if (m == FEX_NONSTOP) {
315 338 switch (e) {
316 339 case fex_inexact:
340 +
317 341 if (f & FE_INEXACT) {
318 342 mutex_unlock(&log_lock);
319 343 return;
320 344 }
345 +
321 346 break;
322 347 case fex_underflow:
348 +
323 349 if (f & FE_UNDERFLOW) {
324 350 mutex_unlock(&log_lock);
325 351 return;
326 352 }
353 +
327 354 break;
328 355 case fex_overflow:
356 +
329 357 if (f & FE_OVERFLOW) {
330 358 mutex_unlock(&log_lock);
331 359 return;
332 360 }
361 +
333 362 break;
334 363 case fex_division:
364 +
335 365 if (f & FE_DIVBYZERO) {
336 366 mutex_unlock(&log_lock);
337 367 return;
338 368 }
369 +
339 370 break;
340 371 default:
372 +
341 373 if (f & FE_INVALID) {
342 374 mutex_unlock(&log_lock);
343 375 return;
344 376 }
377 +
345 378 break;
346 379 }
347 380 }
348 381
349 - /* if we've already logged this exception at this address,
350 - don't make an entry */
382 + /*
383 + * if we've already logged this exception at this address,
384 + * don't make an entry
385 + */
351 386 if (check_exc_list(addr, (unsigned long)e, stk, fp)) {
352 387 mutex_unlock(&log_lock);
353 388 return;
354 389 }
355 390
356 391 /* make an entry */
357 392 fd = fileno(log_fp);
358 393 write(fd, "Floating point ", 15);
359 394 write(fd, exception[e], strlen(exception[e]));
360 395 write(fd, buf, sprintf(buf, " at 0x%0" PDIG "lx", (long)addr));
361 396 __fex_sym_init();
397 +
362 398 if (__fex_sym(addr, &name) != NULL) {
363 399 write(fd, " ", 1);
364 400 write(fd, name, strlen(name));
365 401 }
402 +
366 403 switch (m) {
367 404 case FEX_NONSTOP:
368 405 write(fd, ", nonstop mode\n", 15);
369 406 break;
370 407
371 408 case FEX_ABORT:
372 409 write(fd, ", abort\n", 8);
373 410 break;
374 411
375 412 case FEX_NOHANDLER:
413 +
376 414 if (p == (void *)SIG_DFL) {
377 415 write(fd, ", handler: SIG_DFL\n", 19);
378 416 break;
379 - }
380 - else if (p == (void *)SIG_IGN) {
417 + } else if (p == (void *)SIG_IGN) {
381 418 write(fd, ", handler: SIG_IGN\n", 19);
382 419 break;
383 420 }
384 - /* fall through*/
421 +
422 + /* FALLTHROUGH */
385 423 default:
386 424 write(fd, ", handler: ", 11);
425 +
387 426 if (__fex_sym((char *)p, &name) != NULL) {
388 427 write(fd, name, strlen(name));
389 428 write(fd, "\n", 1);
390 429 } else {
391 430 write(fd, buf, sprintf(buf, "0x%0" PDIG "lx\n",
392 431 (long)p));
393 432 }
433 +
394 434 break;
395 435 }
436 +
396 437 print_stack(fd, stk, fp);
397 438 mutex_unlock(&log_lock);
398 439 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX