# HG changeset patch # User fparain # Date 1329143084 28800 # Node ID 1bb2838e2fc1c6093ea03ec08121b496bf477573 # Parent 094138495da4cfd1462670e65bc7bab4c0ed0123# Parent 54d3535a6dd3239c7128428b4e19147fe82d37ac Merge diff -r 094138495da4 -r 1bb2838e2fc1 agent/src/os/linux/Makefile --- a/agent/src/os/linux/Makefile Fri Feb 10 11:46:20 2012 -0800 +++ b/agent/src/os/linux/Makefile Mon Feb 13 06:24:44 2012 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ LIBS = -lthread_db -CFLAGS = -c -fPIC -g -D_GNU_SOURCE -D$(ARCH) $(INCLUDES) +CFLAGS = -c -fPIC -g -D_GNU_SOURCE -D$(ARCH) $(INCLUDES) -D_FILE_OFFSET_BITS=64 LIBSA = $(ARCH)/libsaproc.so diff -r 094138495da4 -r 1bb2838e2fc1 agent/src/os/linux/libproc_impl.c --- a/agent/src/os/linux/libproc_impl.c Fri Feb 10 11:46:20 2012 -0800 +++ b/agent/src/os/linux/libproc_impl.c Mon Feb 13 06:24:44 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,10 +50,6 @@ char alt_path[PATH_MAX + 1]; init_alt_root(); - fd = open(name, O_RDONLY); - if (fd >= 0) { - return fd; - } if (alt_root_len > 0) { strcpy(alt_path, alt_root); @@ -73,6 +69,11 @@ return fd; } } + } else { + fd = open(name, O_RDONLY); + if (fd >= 0) { + return fd; + } } return -1; diff -r 094138495da4 -r 1bb2838e2fc1 make/linux/makefiles/saproc.make --- a/make/linux/makefiles/saproc.make Fri Feb 10 11:46:20 2012 -0800 +++ b/make/linux/makefiles/saproc.make Mon Feb 13 06:24:44 2012 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -75,6 +75,7 @@ fi @echo Making SA debugger back-end... $(QUIETLY) $(CC) -D$(BUILDARCH) -D_GNU_SOURCE \ + -D_FILE_OFFSET_BITS=64 \ $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \ -I$(SASRCDIR) \ -I$(GENERATED) \ diff -r 094138495da4 -r 1bb2838e2fc1 src/os/bsd/vm/decoder_machO.hpp --- a/src/os/bsd/vm/decoder_machO.hpp Fri Feb 10 11:46:20 2012 -0800 +++ b/src/os/bsd/vm/decoder_machO.hpp Mon Feb 13 06:24:44 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,8 +29,9 @@ #include "utilities/decoder.hpp" -// Just a placehold for now -class MachODecoder: public NullDecoder { +// Just a placehold for now, a real implementation should derive +// from AbstractDecoder +class MachODecoder : public NullDecoder { public: MachODecoder() { } ~MachODecoder() { } diff -r 094138495da4 -r 1bb2838e2fc1 src/os/windows/vm/decoder_windows.hpp --- a/src/os/windows/vm/decoder_windows.hpp Fri Feb 10 11:46:20 2012 -0800 +++ b/src/os/windows/vm/decoder_windows.hpp Mon Feb 13 06:24:44 2012 -0800 @@ -36,7 +36,7 @@ typedef BOOL (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64); typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD); -class WindowsDecoder: public NullDecoder { +class WindowsDecoder : public AbstractDecoder { public: WindowsDecoder(); diff -r 094138495da4 -r 1bb2838e2fc1 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Fri Feb 10 11:46:20 2012 -0800 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Feb 13 06:24:44 2012 -0800 @@ -284,6 +284,7 @@ template(run_method_name, "run") \ template(exit_method_name, "exit") \ template(add_method_name, "add") \ + template(remove_method_name, "remove") \ template(parent_name, "parent") \ template(threads_name, "threads") \ template(groups_name, "groups") \ diff -r 094138495da4 -r 1bb2838e2fc1 src/share/vm/utilities/decoder.cpp --- a/src/share/vm/utilities/decoder.cpp Fri Feb 10 11:46:20 2012 -0800 +++ b/src/share/vm/utilities/decoder.cpp Mon Feb 13 06:24:44 2012 -0800 @@ -25,7 +25,9 @@ #include "precompiled.hpp" #include "prims/jvm.h" #include "runtime/mutexLocker.hpp" +#include "runtime/os.hpp" #include "utilities/decoder.hpp" +#include "utilities/vmError.hpp" #if defined(_WINDOWS) #include "decoder_windows.hpp" @@ -35,74 +37,94 @@ #include "decoder_elf.hpp" #endif -NullDecoder* Decoder::_decoder = NULL; -NullDecoder Decoder::_do_nothing_decoder; -Mutex* Decoder::_decoder_lock = new Mutex(Mutex::safepoint, - "DecoderLock"); +AbstractDecoder* Decoder::_shared_decoder = NULL; +AbstractDecoder* Decoder::_error_handler_decoder = NULL; +NullDecoder Decoder::_do_nothing_decoder; +Mutex* Decoder::_shared_decoder_lock = new Mutex(Mutex::native, + "SharedDecoderLock"); -// _decoder_lock should already acquired before enter this method -NullDecoder* Decoder::get_decoder() { - assert(_decoder_lock != NULL && _decoder_lock->owned_by_self(), +AbstractDecoder* Decoder::get_shared_instance() { + assert(_shared_decoder_lock != NULL && _shared_decoder_lock->owned_by_self(), "Require DecoderLock to enter"); - if (_decoder != NULL) { - return _decoder; + if (_shared_decoder == NULL) { + _shared_decoder = create_decoder(); } + return _shared_decoder; +} - // Decoder is a secondary service. Although, it is good to have, - // but we can live without it. +AbstractDecoder* Decoder::get_error_handler_instance() { + if (_error_handler_decoder == NULL) { + _error_handler_decoder = create_decoder(); + } + return _error_handler_decoder; +} + + +AbstractDecoder* Decoder::create_decoder() { + AbstractDecoder* decoder; #if defined(_WINDOWS) - _decoder = new (std::nothrow) WindowsDecoder(); + decoder = new (std::nothrow) WindowsDecoder(); #elif defined (__APPLE__) - _decoder = new (std::nothrow)MachODecoder(); + decoder = new (std::nothrow)MachODecoder(); #else - _decoder = new (std::nothrow)ElfDecoder(); + decoder = new (std::nothrow)ElfDecoder(); #endif - if (_decoder == NULL || _decoder->has_error()) { - if (_decoder != NULL) { - delete _decoder; + if (decoder == NULL || decoder->has_error()) { + if (decoder != NULL) { + delete decoder; } - _decoder = &_do_nothing_decoder; + decoder = &_do_nothing_decoder; } - return _decoder; + return decoder; } bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) { - assert(_decoder_lock != NULL, "Just check"); - MutexLockerEx locker(_decoder_lock, true); - NullDecoder* decoder = get_decoder(); + assert(_shared_decoder_lock != NULL, "Just check"); + bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid; + MutexLockerEx locker(error_handling_thread ? NULL : _shared_decoder_lock, true); + AbstractDecoder* decoder = error_handling_thread ? + get_error_handler_instance(): get_shared_instance(); assert(decoder != NULL, "null decoder"); return decoder->decode(addr, buf, buflen, offset, modulepath); } bool Decoder::demangle(const char* symbol, char* buf, int buflen) { - assert(_decoder_lock != NULL, "Just check"); - MutexLockerEx locker(_decoder_lock, true); - NullDecoder* decoder = get_decoder(); + assert(_shared_decoder_lock != NULL, "Just check"); + bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid; + MutexLockerEx locker(error_handling_thread ? NULL : _shared_decoder_lock, true); + AbstractDecoder* decoder = error_handling_thread ? + get_error_handler_instance(): get_shared_instance(); assert(decoder != NULL, "null decoder"); return decoder->demangle(symbol, buf, buflen); } bool Decoder::can_decode_C_frame_in_vm() { - assert(_decoder_lock != NULL, "Just check"); - MutexLockerEx locker(_decoder_lock, true); - NullDecoder* decoder = get_decoder(); + assert(_shared_decoder_lock != NULL, "Just check"); + bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid; + MutexLockerEx locker(error_handling_thread ? NULL : _shared_decoder_lock, true); + AbstractDecoder* decoder = error_handling_thread ? + get_error_handler_instance(): get_shared_instance(); assert(decoder != NULL, "null decoder"); return decoder->can_decode_C_frame_in_vm(); } -// shutdown real decoder and replace it with -// _do_nothing_decoder +/* + * Shutdown shared decoder and replace it with + * _do_nothing_decoder. Do nothing with error handler + * instance, since the JVM is going down. + */ void Decoder::shutdown() { - assert(_decoder_lock != NULL, "Just check"); - MutexLockerEx locker(_decoder_lock, true); + assert(_shared_decoder_lock != NULL, "Just check"); + MutexLockerEx locker(_shared_decoder_lock, true); - if (_decoder != NULL && _decoder != &_do_nothing_decoder) { - delete _decoder; + if (_shared_decoder != NULL && + _shared_decoder != &_do_nothing_decoder) { + delete _shared_decoder; } - _decoder = &_do_nothing_decoder; + _shared_decoder = &_do_nothing_decoder; } diff -r 094138495da4 -r 1bb2838e2fc1 src/share/vm/utilities/decoder.hpp --- a/src/share/vm/utilities/decoder.hpp Fri Feb 10 11:46:20 2012 -0800 +++ b/src/share/vm/utilities/decoder.hpp Mon Feb 13 06:24:44 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ #include "memory/allocation.hpp" #include "runtime/mutex.hpp" -class NullDecoder: public CHeapObj { +class AbstractDecoder : public CHeapObj { public: // status code for decoding native C frame enum decoder_status { @@ -43,6 +43,34 @@ helper_init_error // SymInitialize failed (Windows only) }; + // decode an pc address to corresponding function name and an offset from the beginning of + // the function + virtual bool decode(address pc, char* buf, int buflen, int* offset, + const char* modulepath = NULL) = 0; + // demangle a C++ symbol + virtual bool demangle(const char* symbol, char* buf, int buflen) = 0; + // if the decoder can decode symbols in vm + virtual bool can_decode_C_frame_in_vm() const = 0; + + virtual decoder_status status() const { + return _decoder_status; + } + + virtual bool has_error() const { + return is_error(_decoder_status); + } + + static bool is_error(decoder_status status) { + return (status > 0); + } + +protected: + decoder_status _decoder_status; +}; + +// Do nothing decoder +class NullDecoder : public AbstractDecoder { +public: NullDecoder() { _decoder_status = not_available; } @@ -61,40 +89,34 @@ virtual bool can_decode_C_frame_in_vm() const { return false; } - - virtual decoder_status status() const { - return _decoder_status; - } - - virtual bool has_error() const { - return is_error(_decoder_status); - } - - static bool is_error(decoder_status status) { - return (status > 0); - } - -protected: - decoder_status _decoder_status; }; -class Decoder: AllStatic { +class Decoder : AllStatic { public: static bool decode(address pc, char* buf, int buflen, int* offset, const char* modulepath = NULL); static bool demangle(const char* symbol, char* buf, int buflen); static bool can_decode_C_frame_in_vm(); + // shutdown shared instance static void shutdown(); protected: - static NullDecoder* get_decoder(); + // shared decoder instance, _shared_instance_lock is needed + static AbstractDecoder* get_shared_instance(); + // a private instance for error handler. Error handler can be + // triggered almost everywhere, including signal handler, where + // no lock can be taken. So the shared decoder can not be used + // in this scenario. + static AbstractDecoder* get_error_handler_instance(); + static AbstractDecoder* create_decoder(); private: - static NullDecoder* _decoder; - static NullDecoder _do_nothing_decoder; + static AbstractDecoder* _shared_decoder; + static AbstractDecoder* _error_handler_decoder; + static NullDecoder _do_nothing_decoder; protected: - static Mutex* _decoder_lock; + static Mutex* _shared_decoder_lock; }; #endif // SHARE_VM_UTILITIES_DECODER_HPP diff -r 094138495da4 -r 1bb2838e2fc1 src/share/vm/utilities/decoder_elf.hpp --- a/src/share/vm/utilities/decoder_elf.hpp Fri Feb 10 11:46:20 2012 -0800 +++ b/src/share/vm/utilities/decoder_elf.hpp Mon Feb 13 06:24:44 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ #include "utilities/decoder.hpp" #include "utilities/elfFile.hpp" -class ElfDecoder: public NullDecoder { +class ElfDecoder : public AbstractDecoder { public: ElfDecoder() { diff -r 094138495da4 -r 1bb2838e2fc1 src/share/vm/utilities/preserveException.cpp --- a/src/share/vm/utilities/preserveException.cpp Fri Feb 10 11:46:20 2012 -0800 +++ b/src/share/vm/utilities/preserveException.cpp Mon Feb 13 06:24:44 2012 -0800 @@ -32,9 +32,9 @@ thread = Thread::current(); _thread = thread; _preserved_exception_oop = Handle(thread, _thread->pending_exception()); - _thread->clear_pending_exception(); // Needed to avoid infinite recursion _preserved_exception_line = _thread->exception_line(); _preserved_exception_file = _thread->exception_file(); + _thread->clear_pending_exception(); // Needed to avoid infinite recursion } diff -r 094138495da4 -r 1bb2838e2fc1 src/share/vm/utilities/vmError.hpp --- a/src/share/vm/utilities/vmError.hpp Fri Feb 10 11:46:20 2012 -0800 +++ b/src/share/vm/utilities/vmError.hpp Mon Feb 13 06:24:44 2012 -0800 @@ -27,11 +27,12 @@ #include "utilities/globalDefinitions.hpp" - +class Decoder; class VM_ReportJavaOutOfMemory; class VMError : public StackObj { friend class VM_ReportJavaOutOfMemory; + friend class Decoder; enum ErrorType { internal_error = 0xe0000000,