jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_error.c
changeset 32234 421773f441c6
parent 32208 13203adcd002
parent 32233 d97dc26de1d7
child 32235 26648f472fe5
equal deleted inserted replaced
32208:13203adcd002 32234:421773f441c6
     1 /*
       
     2  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. 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 Oracle 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 /*
       
    33  * This source code is provided to illustrate the usage of a given feature
       
    34  * or technique and has been deliberately simplified. Additional steps
       
    35  * required for a production-quality application, such as security checks,
       
    36  * input validation and proper error handling, might not be present in
       
    37  * this sample code.
       
    38  */
       
    39 
       
    40 
       
    41 #include "hprof.h"
       
    42 
       
    43 /* The error handling logic. */
       
    44 
       
    45 /*
       
    46  * Most hprof error processing and error functions are kept here, along with
       
    47  *   termination functions and signal handling (used in debug version only).
       
    48  *
       
    49  */
       
    50 
       
    51 #include <signal.h>
       
    52 
       
    53 static int p = 1; /* Used with pause=y|n option */
       
    54 
       
    55 /* Private functions */
       
    56 
       
    57 static void
       
    58 error_message(const char * format, ...)
       
    59 {
       
    60     va_list ap;
       
    61 
       
    62     va_start(ap, format);
       
    63     (void)vfprintf(stderr, format, ap);
       
    64     va_end(ap);
       
    65 }
       
    66 
       
    67 static void
       
    68 error_abort(void)
       
    69 {
       
    70     /* Important to remove existing signal handler */
       
    71     (void)signal(SIGABRT, NULL);
       
    72     error_message("HPROF DUMPING CORE\n");
       
    73     abort();        /* Sends SIGABRT signal, usually also caught by libjvm */
       
    74 }
       
    75 
       
    76 static void
       
    77 signal_handler(int sig)
       
    78 {
       
    79     /* Caught a signal, most likely a SIGABRT */
       
    80     error_message("HPROF SIGNAL %d TERMINATED PROCESS\n", sig);
       
    81     error_abort();
       
    82 }
       
    83 
       
    84 static void
       
    85 setup_signal_handler(int sig)
       
    86 {
       
    87     /* Only if debug version or debug=y */
       
    88     if ( gdata->debug ) {
       
    89         (void)signal(sig, (void(*)(int))(void*)&signal_handler);
       
    90     }
       
    91 }
       
    92 
       
    93 static void
       
    94 terminate_everything(jint exit_code)
       
    95 {
       
    96     if ( exit_code > 0 ) {
       
    97         /* Could be a fatal error or assert error or a sanity error */
       
    98         error_message("HPROF TERMINATED PROCESS\n");
       
    99         if ( gdata->coredump || gdata->debug ) {
       
   100             /* Core dump here by request */
       
   101             error_abort();
       
   102         }
       
   103     }
       
   104     /* Terminate the process */
       
   105     error_exit_process(exit_code);
       
   106 }
       
   107 
       
   108 /* External functions */
       
   109 
       
   110 void
       
   111 error_setup(void)
       
   112 {
       
   113     setup_signal_handler(SIGABRT);
       
   114 }
       
   115 
       
   116 void
       
   117 error_do_pause(void)
       
   118 {
       
   119     int pid = md_getpid();
       
   120     int timeleft = 600; /* 10 minutes max */
       
   121     int interval = 10;  /* 10 second message check */
       
   122 
       
   123     /*LINTED*/
       
   124     error_message("\nHPROF pause for PID %d\n", (int)pid);
       
   125     while ( p && timeleft > 0 ) {
       
   126         md_sleep(interval); /* 'assign p=0' to stop pause loop */
       
   127         timeleft -= interval;
       
   128     }
       
   129     if ( timeleft <= 0 ) {
       
   130         error_message("\n HPROF pause got tired of waiting and gave up.\n");
       
   131     }
       
   132 }
       
   133 
       
   134 void
       
   135 error_exit_process(int exit_code)
       
   136 {
       
   137     exit(exit_code);
       
   138 }
       
   139 
       
   140 static const char *
       
   141 source_basename(const char *file)
       
   142 {
       
   143     const char *p;
       
   144 
       
   145     if ( file == NULL ) {
       
   146         return "UnknownSourceFile";
       
   147     }
       
   148     p = strrchr(file, '/');
       
   149     if ( p == NULL ) {
       
   150         p = strrchr(file, '\\');
       
   151     }
       
   152     if ( p == NULL ) {
       
   153         p = file;
       
   154     } else {
       
   155         p++; /* go past / */
       
   156     }
       
   157     return p;
       
   158 }
       
   159 
       
   160 void
       
   161 error_assert(const char *condition, const char *file, int line)
       
   162 {
       
   163     error_message("ASSERTION FAILURE: %s [%s:%d]\n", condition,
       
   164         source_basename(file), line);
       
   165     error_abort();
       
   166 }
       
   167 
       
   168 void
       
   169 error_handler(jboolean fatal, jvmtiError error,
       
   170                 const char *message, const char *file, int line)
       
   171 {
       
   172     char *error_name;
       
   173 
       
   174     if ( message==NULL ) {
       
   175         message = "";
       
   176     }
       
   177     if ( error != JVMTI_ERROR_NONE ) {
       
   178         error_name = getErrorName(error);
       
   179         if ( error_name == NULL ) {
       
   180             error_name = "?";
       
   181         }
       
   182         error_message("HPROF ERROR: %s (JVMTI Error %s(%d)) [%s:%d]\n",
       
   183                             message, error_name, error,
       
   184                             source_basename(file), line);
       
   185     } else {
       
   186         error_message("HPROF ERROR: %s [%s:%d]\n", message,
       
   187                             source_basename(file), line);
       
   188     }
       
   189     if ( fatal || gdata->errorexit ) {
       
   190         /* If it's fatal, or the user wants termination on any error, die */
       
   191         terminate_everything(9);
       
   192     }
       
   193 }
       
   194 
       
   195 void
       
   196 debug_message(const char * format, ...)
       
   197 {
       
   198     va_list ap;
       
   199 
       
   200     va_start(ap, format);
       
   201     (void)vfprintf(stderr, format, ap);
       
   202     va_end(ap);
       
   203 }
       
   204 
       
   205 void
       
   206 verbose_message(const char * format, ...)
       
   207 {
       
   208     if ( gdata->verbose ) {
       
   209         va_list ap;
       
   210 
       
   211         va_start(ap, format);
       
   212         (void)vfprintf(stderr, format, ap);
       
   213         va_end(ap);
       
   214     }
       
   215 }