blob: b83ffb3df23176851056c8a3c534b84a8e5c23e5 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * - Neither the name of Sun Microsystems nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "hprof.h"
33
34/* The error handling logic. */
35
36/*
37 * Most hprof error processing and error functions are kept here, along with
38 * termination functions and signal handling (used in debug version only).
39 *
40 */
41
42#include <signal.h>
43
44static int p = 1; /* Used with pause=y|n option */
45
46/* Private functions */
47
48static void
49error_message(const char * format, ...)
50{
51 va_list ap;
52
53 va_start(ap, format);
54 (void)vfprintf(stderr, format, ap);
55 va_end(ap);
56}
57
58static void
59error_abort(void)
60{
61 /* Important to remove existing signal handler */
62 (void)signal(SIGABRT, NULL);
63 error_message("HPROF DUMPING CORE\n");
64 abort(); /* Sends SIGABRT signal, usually also caught by libjvm */
65}
66
67static void
68signal_handler(int sig)
69{
70 /* Caught a signal, most likely a SIGABRT */
71 error_message("HPROF SIGNAL %d TERMINATED PROCESS\n", sig);
72 error_abort();
73}
74
75static void
76setup_signal_handler(int sig)
77{
78 /* Only if debug version or debug=y */
79 if ( gdata->debug ) {
80 (void)signal(sig, (void(*)(int))(void*)&signal_handler);
81 }
82}
83
84static void
85terminate_everything(jint exit_code)
86{
87 if ( exit_code > 0 ) {
88 /* Could be a fatal error or assert error or a sanity error */
89 error_message("HPROF TERMINATED PROCESS\n");
90 if ( gdata->coredump || gdata->debug ) {
91 /* Core dump here by request */
92 error_abort();
93 }
94 }
95 /* Terminate the process */
96 error_exit_process(exit_code);
97}
98
99/* External functions */
100
101void
102error_setup(void)
103{
104 setup_signal_handler(SIGABRT);
105}
106
107void
108error_do_pause(void)
109{
110 int pid = md_getpid();
111 int timeleft = 600; /* 10 minutes max */
112 int interval = 10; /* 10 second message check */
113
114 /*LINTED*/
115 error_message("\nHPROF pause for PID %d\n", (int)pid);
116 while ( p && timeleft > 0 ) {
117 md_sleep(interval); /* 'assign p=0' to stop pause loop */
118 timeleft -= interval;
119 }
120 if ( timeleft <= 0 ) {
121 error_message("\n HPROF pause got tired of waiting and gave up.\n");
122 }
123}
124
125void
126error_exit_process(int exit_code)
127{
128 exit(exit_code);
129}
130
131static const char *
132source_basename(const char *file)
133{
134 const char *p;
135
136 if ( file == NULL ) {
137 return "UnknownSourceFile";
138 }
139 p = strrchr(file, '/');
140 if ( p == NULL ) {
141 p = strrchr(file, '\\');
142 }
143 if ( p == NULL ) {
144 p = file;
145 } else {
146 p++; /* go past / */
147 }
148 return p;
149}
150
151void
152error_assert(const char *condition, const char *file, int line)
153{
154 error_message("ASSERTION FAILURE: %s [%s:%d]\n", condition,
155 source_basename(file), line);
156 error_abort();
157}
158
159void
160error_handler(jboolean fatal, jvmtiError error,
161 const char *message, const char *file, int line)
162{
163 char *error_name;
164
165 if ( message==NULL ) {
166 message = "";
167 }
168 if ( error != JVMTI_ERROR_NONE ) {
169 error_name = getErrorName(error);
170 if ( error_name == NULL ) {
171 error_name = "?";
172 }
173 error_message("HPROF ERROR: %s (JVMTI Error %s(%d)) [%s:%d]\n",
174 message, error_name, error,
175 source_basename(file), line);
176 } else {
177 error_message("HPROF ERROR: %s [%s:%d]\n", message,
178 source_basename(file), line);
179 }
180 if ( fatal || gdata->errorexit ) {
181 /* If it's fatal, or the user wants termination on any error, die */
182 terminate_everything(9);
183 }
184}
185
186void
187debug_message(const char * format, ...)
188{
189 va_list ap;
190
191 va_start(ap, format);
192 (void)vfprintf(stderr, format, ap);
193 va_end(ap);
194}
195
196void
197verbose_message(const char * format, ...)
198{
199 if ( gdata->verbose ) {
200 va_list ap;
201
202 va_start(ap, format);
203 (void)vfprintf(stderr, format, ap);
204 va_end(ap);
205 }
206}