From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31050 invoked by alias); 10 Feb 2014 02:16:44 -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 31030 invoked by uid 89); 10 Feb 2014 02:16:42 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 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-ob0-f179.google.com Received: from mail-ob0-f179.google.com (HELO mail-ob0-f179.google.com) (209.85.214.179) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Mon, 10 Feb 2014 02:16:41 +0000 Received: by mail-ob0-f179.google.com with SMTP id wo20so6632837obc.10 for ; Sun, 09 Feb 2014 18:16:38 -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=uTR2LDJwQYdSXMTAjlSU062bCi8nkFWDh1x2zKfgIoU=; b=UiAMg5opkvCHxGiT+Bwm5BVctNfccVNP+D0/r0c3FqXMjRQs6sF4V3mv4omEB2ctpu PFnvzz5nIhZ/29Ee4DcGd9mm1MopMq+dMtQHFHzRFNx/IVprRHISBHKEdeGKNXKCCsRB h0M4EgOtFm03UOqQKLTaHbqmf21xRlDfphBW10r1rcM0kPuuKlne3AE8PUZD4EMbvPfE +DmcXCyKpHQbVbtP2zAmLOce9hjzFrnlZblCTBUyac1Co7RJu20Y1ilLToo+9I02xzw2 BkTXjuxCZ3pkyVR5GwHVKN7FGy5DpU7hthBIVmEplIkfFTh2img5g/cwoSxiCxsykmTk Ow7A== X-Gm-Message-State: ALoCoQnKzkCgiOVGF7zQQT1Ivpop/EpCvDC+8xZzAL3i9+5qcbnodjwSSe2LRbNYEdWgwfcmUbwPicI/lU2IGEZwabalzrNrt3si1soMDRcrwaQDVM0ahkbyl9dq0bufsWBPPeR2Khb0lW+SPQ1eT+FfwAbadjKtEcVhszPCdT0QCw/iGlSu2Nc24HhAd5ZIF4OQ1QZ+Jjju3KfK0IYGIYTLZ/nJUyvaFw== MIME-Version: 1.0 X-Received: by 10.182.34.196 with SMTP id b4mr13659027obj.13.1391998598673; Sun, 09 Feb 2014 18:16:38 -0800 (PST) Received: by 10.182.84.131 with HTTP; Sun, 9 Feb 2014 18:16:38 -0800 (PST) In-Reply-To: <52F5D773.5050203@codesourcery.com> References: <20131226183618.D264CA18A0@sasha2.mtv.corp.google.com> <52F5D773.5050203@codesourcery.com> Date: Mon, 10 Feb 2014 02:16:00 -0000 Message-ID: Subject: Re: [RFC][PATCH] Allow JIT unwinder provide symbol information From: Alexander Smundak To: Yao Qi Cc: gdb-patches@sourceware.org Content-Type: text/plain; charset=UTF-8 X-SW-Source: 2014-02/txt/msg00268.txt.bz2 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=, 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=, 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=, 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=, 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. >> >> 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.