From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5486 invoked by alias); 11 Feb 2014 22:00:29 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 5457 invoked by uid 89); 11 Feb 2014 22:00:26 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.2 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-vc0-f177.google.com Received: from mail-vc0-f177.google.com (HELO mail-vc0-f177.google.com) (209.85.220.177) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Tue, 11 Feb 2014 22:00:24 +0000 Received: by mail-vc0-f177.google.com with SMTP id if11so6293593vcb.22 for ; Tue, 11 Feb 2014 14:00:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=UxUrxHzxa0kSEZ1gMclUaigLP/LExg4xsP7U0Yyi0Jk=; b=md0I3n/5LWfDqDciZIXqZs6IG7CvK5nZH79Vb764PvkHdv65jMPmEod44N27KU7L8Y nE9vKZARu0MpLtkzZlzfyFi/1VLoktD7zCnsO73AbVHrSbqabkrR9elA6+NmjZGj/O3+ Nd06cDhsiW6RjR7FcGmAfOQ2CcjAxQ0J/35FJpN3hTJJz2clEt+ef6yj13H92li7zlw3 MRg77LDaQFew/vtqzopAAyjmJL+1PuWZ+GqRTJ2bSeFokFQ1/T72/05DFG9Rp1jYX4gs HmrBCc8dWqDMo9uP50Mcx3boZ2z8Hs7J8MXoJmxZFb6/TYCIwN/AO7iPdCinCqMXCDpp Ke9g== X-Gm-Message-State: ALoCoQlXLE6mA/Sobg7jQWGZFgEZwb8jy4ZbVd1JK4oda0qzI1260gNYb4euSdGG1562Q4UpIpFp0aMLFWMIGybYToDO+jX5f0sWW6a3lNsMeDC7+2RtJafIw1qG9TRHq739cpeyYUOYcqFygQk02SkqoiSxwNDuPP16Ze5kZBBxVQcT3zP8WFDgfbTcBhJIurZ+rzxS/2CgC/3Cn3CgYhHHPCVghs8bVg== MIME-Version: 1.0 X-Received: by 10.52.30.230 with SMTP id v6mr25123242vdh.6.1392156022219; Tue, 11 Feb 2014 14:00:22 -0800 (PST) Received: by 10.52.51.234 with HTTP; Tue, 11 Feb 2014 14:00:22 -0800 (PST) In-Reply-To: References: <20131226183618.D264CA18A0@sasha2.mtv.corp.google.com> <52F5D773.5050203@codesourcery.com> Date: Tue, 11 Feb 2014 22:00:00 -0000 Message-ID: Subject: Re: [RFC][PATCH] Allow JIT unwinder provide symbol information From: Doug Evans To: Alexander Smundak Cc: Yao Qi , gdb-patches Content-Type: text/plain; charset=UTF-8 X-IsSubscribed: yes X-SW-Source: 2014-02/txt/msg00367.txt.bz2 On Sun, Feb 9, 2014 at 6:16 PM, Alexander Smundak wrote: > On Fri, Feb 7, 2014 at 11:06 PM, Yao Qi wrote: >> On 12/27/2013 02:36 AM, Sasha Smundak wrote: >>> The change proposed in this RFC is part of the effort to support >>> debugging applications containing Java code executed with the help of >>> Java interpreter/ just-in-time (JIT) compiler. Here's the fragment of >>> the backtrace of an application being debugged by the GDB modified to >>> provide such support: >>> >>> #8 0x00007fffea743b03 in JNIEnv_::CallVoidMethod (this=0x7ffff001f220, obj=0x7ffff665d810, methodID=0x7ffff019d6d0) at <...>/jdk/include/jni.h:1054 >>> #9 0x00007fffea7439c2 in Java_Util_callObjectMethod (env=0x7ffff001f220, myclass=0x7ffff665d840, target_object=0x7ffff665d810, method_name=0x7ffff665d818) at <...>/testjni.cc:48 >>> #10 0x00007fffed05ef7b in Util.callObjectMethod+0x15b[C] (java.lang.Object=???) at Util.java:-1 >>> #11 0x00007fffed061188 in Myclass.method1+0x68[C] (this=@f665d2a8) at Myclass.java:18 >>> #12 0x00007fffed005f98 in Myclass.main#I ([]=[...]) at Myclass.java:48 >>> #13 0x00007fffed000438 in () >>> >>> I.e., Myclass.main() calls Myclass.method1() calls >>> Util.callObjectMethod(), which is implemented as a C function >>> Java_Util_callObjectMethod(). Myclass.main() is interpreted, while >>> Myclass.method1() is JIT-compiled. >> >> IWBN to show how GDB behaves without this patch. > > Here's what GDB shows without the plugin: > (gdb) where > #0 Java_gdbtest_Util_breakpoint (env=0x7ffff0009220, > myclass=0x7ffff649c258) at <...>/testjni.cc:24 > #1 0x00007fffea013306 in ?? () > #2 0x00007ffff649c468 in ?? () > #3 0x00007ffff649c208 in ?? () > #4 0x000000060569ef48 in ?? () > #5 0x00007ffff649c260 in ?? () > #6 0x000000060569f638 in ?? () > #7 0x0000000000000000 in ?? () > > and this is what is shows with the plugin: > (gdb) jit-reader-load java.so > (gdb) where > #0 Java_gdbtest_Util_breakpoint (env=0x7ffff0009220, > myclass=0x7ffff649c258) at <...>/testjni.cc:24 > #1 0x00007fffea013306 in gdbtest.Util.breakpoint#I () at Util.java:-1 > #2 0x00007fffea0667f4 in gdbtest.Interpreted.inner+0x54[C] (this=?) > at Interpreted.java:31 > #3 0x00007fffea0004e7 in () > #4 0x00007ffff6bb6988 in JavaCalls::call_helper (result= out>, m=, args=, > __the_thread__=) > at <...>/hotspot/src/share/vm/runtime/javaCalls.cpp:422 > #5 0x00007ffff6bb59d8 in JavaCalls::call (result=, > method=..., args=0x0, __the_thread__=0x0) > at <...>/hotspot/src/share/vm/runtime/javaCalls.cpp:320 > #6 0x00007ffff6bc579d in jni_invoke_nonstatic (env=, > result=0x7ffff649c620, receiver=, call_type= out>, > method_id=, args=0x7ffff649c5c0, > __the_thread__=0x7ffff0009000) > at <...>/hotspot/src/share/vm/prims/jni.cpp:1414 > #7 0x00007ffff6bd1586 in jni_CallVoidMethodV(JNIEnv *, jobject, > jmethodID, typedef __va_list_tag __va_list_tag *) (env=0x7ffff0009220, > obj=, methodID=0x7ffff0079848, args=) > at <...>/hotspot/src/share/vm/prims/jni.cpp:1958 > #8 0x00007fffe181ab03 in JNIEnv_::CallVoidMethod > (this=0x7ffff0009220, obj=0x7ffff649c7e0, methodID=0x7ffff0079848) > at <...>/jdk/include/jni.h:1054 > #9 0x00007fffe181a9c2 in Java_gdbtest_Util_callObjectMethod > (env=0x7ffff0009220, myclass=0x7ffff649c810, > target_object=0x7ffff649c7e0, > method_name=0x7ffff649c7e8) at <...>/testjni.cc:48 > #10 0x00007fffea06043b in gdbtest.Util.callObjectMethod+0x15b[C] > (java.lang.Object=???) at Util.java:-1 > #11 0x00007fffea066508 in gdbtest.Interpreted.method1+0x68[C] (this=?) > at Interpreted.java:18 > #12 0x00007fffea006058 in gdbtest.Interpreted.main#I ([]=[...]) at > Interpreted.java:48 > #13 0x00007fffea0004e7 in () > #14 0x00007ffff6bb6988 in JavaCalls::call_helper (result= out>, m=, args=, > __the_thread__=) > at <...>/hotspot/src/share/vm/runtime/javaCalls.cpp:422 > #15 0x00007ffff6bb59d8 in JavaCalls::call (result=, > method=..., args=0x0, __the_thread__=0x0) > at <...>/hotspot/src/share/vm/runtime/javaCalls.cpp:320 > #16 0x00007ffff6bc6501 in jni_invoke_static (env=, > result=0x7ffff649cc90, receiver=, call_type= out>, > method_id=, args=0x7ffff649cc10, > __the_thread__=0x7ffff0009000) > at <...>/hotspot/src/share/vm/prims/jni.cpp:1338 > #17 0x00007ffff6bd3008 in jni_CallStaticVoidMethod > (env=0x7ffff0009220, cls=, methodID=0x7ffff0079840) > at <...>/hotspot/src/share/vm/prims/jni.cpp:2541 > #18 0x00007ffff7fdc7a4 in JavaMain (_args=) at > ../../../src/share/bin/java.c:522 > #19 0x00007ffff7bc314e in start_thread () from > /usr/grte/v3/lib64/libpthread.so.0 > #20 0x00007ffff763569d in clone () from /usr/grte/v3/lib64/libc.so.6 > #21 0x0000000000000000 in ?? () > > (I've replaced absolute paths with <...>). > Note that unaided GDB is unable to unwind the stack correctly as JVM > does not always save the frame pointer at the expected place and > does not supply explicit unwind info. > >>> ... Second, when JVM runs Java code in the >>> interpreted mode, the code address in the frame points to the >>> interpreter code, which is not what should be displayed. >> >> That is a separate problem, IMO. GDB JIT interface was designed to deal >> with JIT'ed code. In interpreted mode, it is reasonable to me >> that GDB shows the interpreter code in backtrace, because JVM is just a >> typical executable, which is being debugged via GDB. I don't know how >> does your patch help to this problem. > Consider this traceback (obtained with the same code running in JVM > with JIT disabled): > > #0 Java_gdbtest_Util_breakpoint ... > #1 0x00007fffea013306 in gdbtest.Util.breakpoint#I () at Util.java:-1 > #2 0x00007fffea006058 in gdbtest.Interpreted.inner#I (this=@58cd65e0) > at Interpreted.java:31 > #3 0x00007fffea0004e7 in () > #4 0x00007ffff6bb6988 in JavaCalls::call_helper (...) > #5 0x00007ffff6bb59d8 in JavaCalls::call (...) > #6 0x00007ffff6bc579d in jni_invoke_nonstatic (...) > #7 0x00007ffff6bd1586 in jni_CallVoidMethodV(...) > #8 0x00007fffe181ab03 in JNIEnv_::CallVoidMethod (...) > #9 0x00007fffe181a9c2 in Java_gdbtest_Util_callObjectMethod (...) > #10 0x00007fffea013306 in gdbtest.Util.callObjectMethod#I () > #11 0x00007fffea006058 in gdbtest.Interpreted.method1#I () > #12 0x00007fffea006058 in gdbtest.Interpreted.main#I (...) > #13 0x00007fffea0004e7 in () > ... > Notice that the frames #2, #11, #12 have the same PC, which is the location of > the place in the interpreter where it executes 'call method' instruction. > The JIT plugin in this case additionally shows the location of the call in the > Java source code, which is more useful. Thanks for the examples! >>> >>> The solution proposed here is to add a "symbol provider" function to >>> the unwinder interface and modify the code displaying frames to get >>> the symbol information associated with the frame (function name, >>> source location, arguments) from the frame's unwinder if it has >>> symbol provider and use the current logic as a fallback strategy. >> >> IMHO, it is not a good idea to add "symbol provider" to the unwinder, as >> it is unrelated to unwinding. Unwinder's job is to compute the 'next' >> frame_info, given one frame_info. Displaying the function name and >> source file of a frame_info is out the scope of its responsibilities. >> >> It is fine to register "symbol provider" to interpret frames of JIT'ed >> code to function name, source file, and so forth, but I feel >> uncomfortable to add "symbol provider" to the unwinder, at least to >> 'struct frame_unwind'. > I agree it would be more appropriate to rename 'frame_unwind' > to 'frame_handler'. However, it's just a refactoring that can be done > separately. Agreed.