src/hotspot/share/utilities/decoder.hpp
changeset 47216 71c04702a3d5
parent 47086 2b35673f6297
child 47666 19219ec3f176
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 1997, 2015, 2017, Oracle and/or its affiliates. All rights reserved.
       
     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  */
       
    24 
       
    25 
       
    26 #ifndef SHARE_VM_UTILITIES_DECODER_HPP
       
    27 #define SHARE_VM_UTILITIES_DECODER_HPP
       
    28 
       
    29 #include "memory/allocation.hpp"
       
    30 #include "runtime/mutex.hpp"
       
    31 #include "runtime/mutexLocker.hpp"
       
    32 #include "utilities/ostream.hpp"
       
    33 
       
    34 class AbstractDecoder : public CHeapObj<mtInternal> {
       
    35 public:
       
    36   virtual ~AbstractDecoder() {}
       
    37 
       
    38   // status code for decoding native C frame
       
    39   enum decoder_status {
       
    40          not_available = -10,  // real decoder is not available
       
    41          no_error = 0,         // successfully decoded frames
       
    42          out_of_memory,        // out of memory
       
    43          file_invalid,         // invalid elf file
       
    44          file_not_found,       // could not found symbol file (on windows), such as jvm.pdb or jvm.map
       
    45          helper_func_error,    // decoding functions not found (Windows only)
       
    46          helper_init_error     // SymInitialize failed (Windows only)
       
    47   };
       
    48 
       
    49   // decode an pc address to corresponding function name and an offset from the beginning of
       
    50   // the function
       
    51   //
       
    52   // Note: the 'base' variant does not demangle names. The
       
    53   // demangling that was done systematically in the 'modulepath' variant
       
    54   // is now optional.
       
    55   virtual bool decode(address pc, char* buf, int buflen, int* offset,
       
    56                       const char* modulepath = NULL, bool demangle = true) = 0;
       
    57   virtual bool decode(address pc, char* buf, int buflen, int* offset, const void* base) = 0;
       
    58 
       
    59   // demangle a C++ symbol
       
    60   virtual bool demangle(const char* symbol, char* buf, int buflen) = 0;
       
    61   // if the decoder can decode symbols in vm
       
    62   virtual bool can_decode_C_frame_in_vm() const = 0;
       
    63 
       
    64   virtual decoder_status status() const {
       
    65     return _decoder_status;
       
    66   }
       
    67 
       
    68   virtual bool has_error() const {
       
    69     return is_error(_decoder_status);
       
    70   }
       
    71 
       
    72   static bool is_error(decoder_status status) {
       
    73     return (status > 0);
       
    74   }
       
    75 
       
    76 protected:
       
    77   decoder_status  _decoder_status;
       
    78 };
       
    79 
       
    80 // Do nothing decoder
       
    81 class NullDecoder : public AbstractDecoder {
       
    82 public:
       
    83   NullDecoder() {
       
    84     _decoder_status = not_available;
       
    85   }
       
    86 
       
    87   virtual ~NullDecoder() {};
       
    88 
       
    89   virtual bool decode(address pc, char* buf, int buflen, int* offset,
       
    90                       const char* modulepath, bool demangle) {
       
    91     return false;
       
    92   }
       
    93 
       
    94   virtual bool decode(address pc, char* buf, int buflen, int* offset, const void* base) {
       
    95     return false;
       
    96   }
       
    97 
       
    98   virtual bool demangle(const char* symbol, char* buf, int buflen) {
       
    99     return false;
       
   100   }
       
   101 
       
   102   virtual bool can_decode_C_frame_in_vm() const {
       
   103     return false;
       
   104   }
       
   105 };
       
   106 
       
   107 
       
   108 class Decoder : AllStatic {
       
   109 public:
       
   110   static bool decode(address pc, char* buf, int buflen, int* offset, const char* modulepath = NULL, bool demangle = true);
       
   111   static bool decode(address pc, char* buf, int buflen, int* offset, bool demangle) {
       
   112     return decode(pc, buf, buflen, offset, (const char*) NULL, demangle);
       
   113   }
       
   114   static bool decode(address pc, char* buf, int buflen, int* offset, const void* base);
       
   115   static bool demangle(const char* symbol, char* buf, int buflen);
       
   116   static bool can_decode_C_frame_in_vm();
       
   117 
       
   118   // shutdown shared instance
       
   119   static void shutdown();
       
   120 
       
   121   static void print_state_on(outputStream* st);
       
   122 
       
   123 protected:
       
   124   // shared decoder instance, _shared_instance_lock is needed
       
   125   static AbstractDecoder* get_shared_instance();
       
   126   // a private instance for error handler. Error handler can be
       
   127   // triggered almost everywhere, including signal handler, where
       
   128   // no lock can be taken. So the shared decoder can not be used
       
   129   // in this scenario.
       
   130   static AbstractDecoder* get_error_handler_instance();
       
   131 
       
   132   static AbstractDecoder* create_decoder();
       
   133 private:
       
   134   static AbstractDecoder*     _shared_decoder;
       
   135   static AbstractDecoder*     _error_handler_decoder;
       
   136   static NullDecoder          _do_nothing_decoder;
       
   137 
       
   138 protected:
       
   139   static Mutex*               _shared_decoder_lock;
       
   140   static Mutex* shared_decoder_lock();
       
   141 
       
   142   friend class DecoderLocker;
       
   143 };
       
   144 
       
   145 class DecoderLocker : public MutexLockerEx {
       
   146   AbstractDecoder* _decoder;
       
   147   inline bool is_first_error_thread();
       
   148 public:
       
   149   DecoderLocker();
       
   150   AbstractDecoder* decoder() {
       
   151     return _decoder;
       
   152   }
       
   153 };
       
   154 
       
   155 #endif // SHARE_VM_UTILITIES_DECODER_HPP