Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8185712

[windows] Improve native symbol decoder

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P4
    • 10
    • 9, 10
    • hotspot
    • None
    • b31
    • windows

    Description

      On Windows, native symbol name resolution has some bugs and shortcomings which reduce the chance to get useful callstacks when crashing.

      Native symbol resolution on windows is done via the group of "SymXX" APIs exported from dbghelp.dll. Currently this is done via a layer of abstraction in decoder.cpp, and a "WindowsDecoder" class in decoder_windows.cpp. This class will be instantianted twice, once for the error handler writing the hs-err file, once for other threads. So there can exist two instances of this class, and both can be used concurrently.

      This layer has a number of bugs:

      1) Functions from dbghelp.dll are not threadsafe; calls to them must be synchronized. But dbghelp.dll could be used by the two live WindowsDecoder objects in parallel from different threads. In addition to that, dbghelp.dll functions are used from within os_windows.cpp, when writing minidumps. (Note: this part of the issue was split off and fixed as an own patch, see JDK-8186349.)

      2) the SymXX APIs need to be initialized by a call to SymInitialize(). This can only happen once. But the two WindowsDecoder objects each call SymInitialize from their respective WindowsDecoder::initialize() methods. The second object to do this will fail and hence not work.

      3) There are initialization dependencies, which is not good in code tied to the error handler.
        - when building the pdb search path (WindowsDecoder::initialize), Arguments::get_java_home() is used to deduce the jdk bin directory containing the jdk shared objects. This will crash if invoked before the system properties are set.
        - Decoder::decode() calls (via the Monitor lock) Thread::current(), which may assert if no current Thread is set.

      4) WindowsDecoder::initialize(), pdb search path assemblage: this code uses a number of buffers, which may be both too small for corner cass and too large for the footprint in error situations (they are allocated on the stack).

      5) WindowsDecoder::decode(): We call SymGetSymFromAddr64() using an output buffer of size MAX_PATH - which makes no sense at all, as we are retrieving a symbol name, not a file name. Truncation is not handled. This is actually dangerous, because SymGetSymFromAddr64() handles truncations sloppily, it will return success and fill the output buffer completely, so on truncation the symbol name will not be zero terminated.

      Not really bugs, but possible improvements or simplifications:

      a) Setting the search path could both be simplified and made more useful if, instead of just adding the jdk-specific directories to the search path, we would add each directory of each loaded DLL to the search path. As a common practice is to deliver pdb files alongside the binaries, this way we would have a high chance of picking up pdb files for third party libraries too. So if a third party library crashes, we see its symbols in the callstack.

      b) Dlls can be loaded and unloaded, and it would be nice to have an updated pdb search path - e.g. in case a late-loaded third party JNI library crashes.

      c) It would be nice to have file name and line number in the callstack, too.

      Attachments

        Issue Links

          Activity

            People

              stuefe Thomas Stuefe
              stuefe Thomas Stuefe
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: