zgu@2364: /* zgu@3544: * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. zgu@2364: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. zgu@2364: * zgu@2364: * This code is free software; you can redistribute it and/or modify it zgu@2364: * under the terms of the GNU General Public License version 2 only, as zgu@2364: * published by the Free Software Foundation. zgu@2364: * zgu@2364: * This code is distributed in the hope that it will be useful, but WITHOUT zgu@2364: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or zgu@2364: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License zgu@2364: * version 2 for more details (a copy is included in the LICENSE file that zgu@2364: * accompanied this code). zgu@2364: * zgu@2364: * You should have received a copy of the GNU General Public License version zgu@2364: * 2 along with this work; if not, write to the Free Software Foundation, zgu@2364: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. zgu@2364: * zgu@2364: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA zgu@2364: * or visit www.oracle.com if you need additional information or have any zgu@2364: * questions. zgu@2364: * zgu@2364: */ zgu@2364: zgu@2364: zgu@3430: #ifndef SHARE_VM_UTILITIES_DECODER_HPP zgu@3430: #define SHARE_VM_UTILITIES_DECODER_HPP zgu@2364: zgu@2364: #include "memory/allocation.hpp" zgu@3430: #include "runtime/mutex.hpp" zgu@2364: zgu@3900: class AbstractDecoder : public CHeapObj { zgu@3430: public: zgu@2364: // status code for decoding native C frame zgu@2364: enum decoder_status { zgu@3430: not_available = -10, // real decoder is not available zgu@3430: no_error = 0, // successfully decoded frames zgu@2364: out_of_memory, // out of memory zgu@2364: file_invalid, // invalid elf file zgu@2364: file_not_found, // could not found symbol file (on windows), such as jvm.pdb or jvm.map zgu@2364: helper_not_found, // could not load dbghelp.dll (Windows only) zgu@2364: helper_func_error, // decoding functions not found (Windows only) zgu@3430: helper_init_error // SymInitialize failed (Windows only) zgu@2364: }; zgu@2364: zgu@3544: // decode an pc address to corresponding function name and an offset from the beginning of zgu@3544: // the function zgu@3544: virtual bool decode(address pc, char* buf, int buflen, int* offset, zgu@3544: const char* modulepath = NULL) = 0; zgu@3961: virtual bool decode(address pc, char* buf, int buflen, int* offset, const void* base) = 0; zgu@3961: zgu@3544: // demangle a C++ symbol zgu@3544: virtual bool demangle(const char* symbol, char* buf, int buflen) = 0; zgu@3544: // if the decoder can decode symbols in vm zgu@3544: virtual bool can_decode_C_frame_in_vm() const = 0; zgu@3544: zgu@3544: virtual decoder_status status() const { zgu@3544: return _decoder_status; zgu@3544: } zgu@3544: zgu@3544: virtual bool has_error() const { zgu@3544: return is_error(_decoder_status); zgu@3544: } zgu@3544: zgu@3544: static bool is_error(decoder_status status) { zgu@3544: return (status > 0); zgu@3544: } zgu@3544: zgu@3544: protected: zgu@3544: decoder_status _decoder_status; zgu@3544: }; zgu@3544: zgu@3544: // Do nothing decoder zgu@3544: class NullDecoder : public AbstractDecoder { zgu@3544: public: zgu@3430: NullDecoder() { zgu@3430: _decoder_status = not_available; zgu@3430: } zgu@2364: zgu@3430: ~NullDecoder() {}; zgu@3430: zgu@3430: virtual bool decode(address pc, char* buf, int buflen, int* offset, zgu@3430: const char* modulepath = NULL) { zgu@3430: return false; zgu@3430: } zgu@3430: zgu@3961: virtual bool decode(address pc, char* buf, int buflen, int* offset, const void* base) { zgu@3961: return false; zgu@3961: } zgu@3961: zgu@3430: virtual bool demangle(const char* symbol, char* buf, int buflen) { zgu@3430: return false; zgu@3430: } zgu@3430: zgu@3430: virtual bool can_decode_C_frame_in_vm() const { zgu@3430: return false; zgu@3430: } zgu@3430: }; zgu@3430: zgu@3430: zgu@3544: class Decoder : AllStatic { zgu@3430: public: zgu@3430: static bool decode(address pc, char* buf, int buflen, int* offset, const char* modulepath = NULL); zgu@3961: static bool decode(address pc, char* buf, int buflen, int* offset, const void* base); zgu@3430: static bool demangle(const char* symbol, char* buf, int buflen); zgu@2364: static bool can_decode_C_frame_in_vm(); zgu@2364: zgu@3544: // shutdown shared instance zgu@3430: static void shutdown(); zgu@3430: protected: zgu@3544: // shared decoder instance, _shared_instance_lock is needed zgu@3544: static AbstractDecoder* get_shared_instance(); zgu@3544: // a private instance for error handler. Error handler can be zgu@3544: // triggered almost everywhere, including signal handler, where zgu@3544: // no lock can be taken. So the shared decoder can not be used zgu@3544: // in this scenario. zgu@3544: static AbstractDecoder* get_error_handler_instance(); zgu@2364: zgu@3544: static AbstractDecoder* create_decoder(); zgu@3430: private: zgu@3544: static AbstractDecoder* _shared_decoder; zgu@3544: static AbstractDecoder* _error_handler_decoder; zgu@3544: static NullDecoder _do_nothing_decoder; zgu@2364: zgu@3430: protected: zgu@3544: static Mutex* _shared_decoder_lock; zgu@2364: }; zgu@2364: zgu@3430: #endif // SHARE_VM_UTILITIES_DECODER_HPP