Main Page | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

jvmutil.c

Go to the documentation of this file.
00001 /*!
00002  * @file jvmutil.c
00003  *
00004  * @brief Utilities for operating the JVM on this
00005  * real machine implementation.
00006  *
00007  *
00008  * @section Control
00009  *
00010  * \$URL: https://svn.apache.org/path/name/jvmutil.c $ \$Id: jvmutil.c 0 09/28/2005 dlydick $
00011  *
00012  * Copyright 2005 The Apache Software Foundation
00013  * or its licensors, as applicable.
00014  *
00015  * Licensed under the Apache License, Version 2.0 ("the License");
00016  * you may not use this file except in compliance with the License.
00017  * You may obtain a copy of the License at
00018  *
00019  *     http://www.apache.org/licenses/LICENSE-2.0
00020  *
00021  * Unless required by applicable law or agreed to in writing,
00022  * software distributed under the License is distributed on an
00023  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
00024  * either express or implied.
00025  *
00026  * See the License for the specific language governing permissions
00027  * and limitations under the License.
00028  *
00029  * @version \$LastChangedRevision: 0 $
00030  *
00031  * @date \$LastChangedDate: 09/28/2005 $
00032  *
00033  * @author \$LastChangedBy: dlydick $
00034  *         Original code contributed by Daniel Lydick on 09/28/2005.
00035  *
00036  * @section Reference
00037  *
00038  */
00039 
00040 #include "arch.h"
00041 ARCH_COPYRIGHT_APACHE(jvmutil, c, "$URL: https://svn.apache.org/path/name/jvmutil.c $ $Id: jvmutil.c 0 09/28/2005 dlydick $");
00042 
00043 
00044 #include "jvmcfg.h" 
00045 #include "cfmacros.h" 
00046 #include "classfile.h" 
00047 #include "attribute.h" 
00048 #include "jvm.h" 
00049 #include "linkage.h" 
00050 #include "util.h" 
00051 
00052 
00053 /*!
00054  * @name Debug message verbosity utilities for sysDbgMsg().
00055  *
00056  * @brief Set and get an integer value that determines the number of 
00057  * debug messages that get displayed by sysDbgMsg().
00058  *
00059  * When sysDbgMsg() is inserted into the code of a function,
00060  * a verbosity level is its first parameter.  The higher the
00061  * number, the more verbose the debug output becomes, up to
00062  * level @link #DML10 DMLMAX@endlink.  The lower
00063  * the number, the less it is displayed at run time, down to
00064  * @link #DML1 DMLMIN@endlink.  At level @link #DML0 DMLOFF@endlink,
00065  * only @e vital diagnostic messages are displayed.  The rest are
00066  * suppressed.
00067  *
00068  * This value is heuristically applied by the developer as to the
00069  * importance of that information in various development and
00070  * testing situations.
00071  *
00072  * The importance of the situation defaults to
00073  * @link #DMLDEFAULT DMLDEFAULT@endlink at compile time and may
00074  * be changed at run time with the
00075  * @link #JVMCFG_DEBUGMSGLEVEL_FULL_PARM -Xdebug_level@endlink
00076  * command line parameter.
00077  *
00078  * @see jvm_debug_level_enum
00079  *
00080  * @see sysDbgMsg()
00081  *
00082  */
00083 
00084 /*@{ */ /* Begin grouped definitions */
00085 
00086 /*!
00087  * @brief Set current debug message level
00088  *
00089  *
00090  * @param  level     New level to set.
00091  *
00092  * @returns @link #rvoid rvoid@endlink
00093  *
00094  */
00095 
00096 rvoid jvmutil_set_dml(jvm_debug_level_enum level)
00097 {
00098     pjvm->debug_message_level = level;
00099 
00100 } /* END of jvmutil_set_dml() */
00101 
00102 
00103 /*!
00104  * @brief Get current debug message level
00105  *
00106  *
00107  * @b Parameters: @link #rvoid rvoid@endlink
00108  *
00109  *
00110  *       @returns current debug message verbosity
00111  *
00112  */
00113 jvm_debug_level_enum jvmutil_get_dml()
00114 {
00115     return(pjvm->debug_message_level);
00116 
00117 } /* END of jvmutil_get_dml() */
00118 
00119 /*@} */ /* End of grouped definitions */
00120 
00121 
00122 /*!
00123  * @name Stack dump utilities.
00124  *
00125  * @brief Print contents of a thread's stack to standard error.
00126  *
00127  * Several forms are available that provide various amounts of stack
00128  * frame detail.  The most verbose also shows local variables
00129  * in the stack frame.
00130  *
00131  * @attention These routines are @e not intended as a replacement
00132  * for the normal routine
00133  * <b><code>java.lang.Throwable.printStackTrace()</code></b> !!!
00134  *
00135  * @param  thridx      Thread table index of thread to show
00136  *
00137  * @param  pheader     Null-terminated header string.  If no header is
00138  *                     desired, pass a @link #rnull rnull@endlink
00139  *                     pointer here.
00140  *
00141  * @param  showdetails If @link #rtrue rtrue@endlink, show frame
00142  *                     details, else less verbose.
00143  *
00144  * @param  showlocals  If @link #rtrue rtrue@endlink, show local
00145  *                     variables also, but only if @b showdetails is
00146  *                     also @link #rtrue rtrue@endlink.
00147  *
00148  *
00149  * @returns @link #rvoid rvoid@endlink
00150  *
00151  *
00152  * @todo  This function needs unit testing.
00153  *
00154  * @todo  Add line numbers to output.  Sample output might look like
00155  *        this (when line numbers are added):
00156  *
00157  * @verbatim
00158  * Exception in thread "main" java.lang.NullPointerException
00159         at Testit.sub1(Testit.java:9)
00160         at Testit.main(Testit.java:23)
00161    @endverbatim
00162  *
00163  */
00164 
00165 /*@{ */ /* Begin grouped definitions */
00166 
00167 /*!
00168  * @brief Common function to perform final output from all
00169  * stack print utilities.
00170  *
00171  */
00172 static rvoid jvmutil_print_stack_common(jvm_thread_index  thridx,
00173                                         rchar            *pheader,
00174                                         rboolean          showdetails,
00175                                         rboolean          showlocals)
00176 {
00177     /* Print header if one is passed in, else skip */
00178     if (rnull != pheader)
00179     {
00180         fprintfLocalStderr("%s\n", pheader);
00181     }
00182 
00183     /*
00184      * Read down through all frames until bottom of stack.
00185      * The very last stack frame holds a null FP.
00186      */
00187 
00188     jvm_sp fp = FIRST_STACK_FRAME(thridx);
00189 
00190     while (!CHECK_FINAL_STACK_FRAME_GENERIC(thridx, fp))
00191     {
00192         jvm_class_index clsidx =
00193             STACK(thridx,
00194                   GET_FP(thridx) + JVMREG_STACK_PC_CLSIDX_OFFSET);
00195 
00196         ClassFile *pcfs = CLASS_OBJECT_LINKAGE(clsidx)->pcfs;
00197 
00198         jvm_method_index mthidx =
00199             STACK(thridx,
00200                   GET_FP(thridx) + JVMREG_STACK_PC_MTHIDX_OFFSET);
00201 
00202         rint star_len_cls = CP1_NAME_STRLEN(CONSTANT_Class_info,
00203                                             pcfs,
00204                                             pcfs->this_class,
00205                                             name_index);
00206 
00207         rint star_len_mth = CP1_NAME_STRLEN(CONSTANT_Class_info,
00208                                             pcfs,
00209                                             mthidx,
00210                                             name_index);
00211 
00212         jvm_attribute_index atridx =
00213             attribute_find_in_class_by_enum(clsidx,
00214                                        LOCAL_SOURCEFILE_ATTRIBUTE);
00215 
00216         jvm_constant_pool_index cpidx;
00217         rint star_len_src;
00218         rchar *srcname;
00219 
00220         if (jvm_attribute_index_bad == atridx)
00221         {
00222             cpidx = CONSTANT_CP_DEFAULT_INDEX;
00223 
00224             star_len_src = 7; /* Length of "unknown" */
00225 
00226             srcname = "unknown";
00227         }
00228         else
00229         {
00230             cpidx = ((SourceFile_attribute *)
00231                        &pcfs->attributes[atridx]->ai)->sourcefile_index;
00232 
00233             star_len_src = CP_THIS_STRLEN(pcfs, cpidx);
00234 
00235             srcname = PTR_CP_THIS_STRNAME(pcfs, cpidx);
00236         }
00237 
00238         /* Least verbosity, called from jvmutil_print_stack() */
00239          fprintfLocalStderr("     at %*.*s%c%*.*s(%*.*s:%d)\n",
00240 
00241                  star_len_cls, star_len_cls,
00242                  PTR_CP1_NAME_STRNAME(CONSTANT_Class_info,
00243                                       pcfs,
00244                                       pcfs->this_class,
00245                                       name_index),
00246 
00247                  CLASSNAME_EXTERNAL_DELIMITER_CHAR,
00248 
00249                  star_len_mth, star_len_mth,
00250                  PTR_CP1_NAME_STRNAME(CONSTANT_Class_info,
00251                                       pcfs,
00252                                       mthidx,
00253                                       name_index),
00254 
00255                  star_len_src, star_len_src,
00256                  srcname,
00257                  0 /*! @todo  Get line numbers */);
00258 
00259         /*
00260          * Fill in frame details and local variables
00261          */
00262         if (rtrue == showdetails)
00263         {
00264             /*! @todo Show details of stack frame */
00265 
00266             if (rtrue == showlocals)
00267             {
00268                 /*! @todo Show local variables in stack frame */
00269             }
00270         }
00271 
00272         /* Look at next stack frame */
00273         fp = NEXT_STACK_FRAME_GENERIC(thridx, fp);
00274     }
00275 
00276 } /* END of jvmutil_print_stack_common() */
00277 
00278 
00279 /*!
00280  * @brief Print basic stack frame summary only.
00281  *
00282  */
00283 rvoid jvmutil_print_stack(jvm_thread_index thridx, rchar *pheader)
00284 {
00285     jvmutil_print_stack_common(thridx, pheader, rfalse, rfalse);
00286 
00287 } /* END of jvmutil_print_stack() */
00288 
00289 
00290 /*!
00291  * @brief Print stack frame with some details.
00292  *
00293  */
00294 rvoid jvmutil_print_stack_details(jvm_thread_index  thridx,
00295                                   rchar            *pheader)
00296 {
00297     jvmutil_print_stack_common(thridx, pheader, rtrue, rfalse);
00298 
00299 } /* END of jvmutil_print_stack_details() */
00300 
00301 
00302 /*!
00303  * @brief Print stack frame with details and local variables.
00304  *
00305  */
00306 rvoid jvmutil_print_stack_locals(jvm_thread_index  thridx,
00307                                  rchar            *pheader)
00308 {
00309     jvmutil_print_stack_common(thridx, pheader, rtrue, rtrue);
00310 
00311 } /* END of jvmutil_print_stack_locals() */
00312 
00313 
00314 /*!
00315  * @brief Common print basic stack frame summary showing error type.
00316  *
00317  */
00318 static rvoid jvmutil_print_errtype_stack(jvm_thread_index  thridx,
00319                                          rchar            *errtype)
00320 {
00321     rchar *pheader = HEAP_GET_DATA(JVMCFG_STDIO_BFR, rfalse);
00322 
00323     jvm_class_index clsidx =
00324         STACK(thridx, GET_FP(thridx) + JVMREG_STACK_PC_CLSIDX_OFFSET);
00325 
00326     ClassFile *pcfs = CLASS_OBJECT_LINKAGE(clsidx)->pcfs;
00327 
00328     rint star_len = CP1_NAME_STRLEN(CONSTANT_Class_info,
00329                                     pcfs,
00330                                     pcfs->this_class,
00331                                     name_index);
00332 
00333     sprintfLocal(pheader,
00334                  "%s in thread \"s\" *.*%s",
00335                  errtype,
00336                  THREAD(thridx).name,
00337                  star_len, star_len,
00338                  PTR_CP1_NAME_STRNAME(CONSTANT_Class_info,
00339                                       pcfs,
00340                                       pcfs->this_class,
00341                                       name_index));
00342 
00343     jvmutil_print_stack(thridx, pheader);
00344 
00345     HEAP_FREE_DATA(pheader);
00346 
00347     return;
00348 
00349 } /* END of jvmutil_print_errtype_stack() */
00350 
00351 
00352 /*!
00353  * @brief Print basic stack frame summary reporting an error versus
00354  * an exception.
00355  *
00356  */
00357 rvoid jvmutil_print_error_stack(jvm_thread_index thridx)
00358 {
00359     jvmutil_print_errtype_stack(thridx, "Error");
00360 
00361 } /* END of jvmutil_print_error_stack() */
00362 
00363 
00364 /*!
00365  * @brief Print basic stack frame summary reporting an exception versus
00366  * an error.
00367  *
00368  */
00369 rvoid jvmutil_print_exception_stack(jvm_thread_index thridx)
00370 {
00371     jvmutil_print_errtype_stack(thridx, "Exception");
00372 
00373 } /* END of jvmutil_print_exception_stack() */
00374 
00375 /*@} */ /* End of grouped definitions */
00376 
00377 
00378 /* EOF */
00379 

Generated on Fri Sep 30 18:59:31 2005 by  doxygen 1.4.4