From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11686 invoked by alias); 19 Feb 2015 02:32:59 -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 11673 invoked by uid 89); 19 Feb 2015 02:32:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mail-ob0-f174.google.com Received: from mail-ob0-f174.google.com (HELO mail-ob0-f174.google.com) (209.85.214.174) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 19 Feb 2015 02:32:56 +0000 Received: by mail-ob0-f174.google.com with SMTP id wo20so9585839obc.5 for ; Wed, 18 Feb 2015 18:32:54 -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=9tVIj8V4vu41B+XEcGPBz+aH7T5ObbXX17TDUSqSDYM=; b=eo2KGlmWEFcYgwdVI5KHIC4sTs7mkIJqQ094zQeHVGjMvupFvNY2c1CsgZNtyeCMVS RTcBuy1pPdfwqZZlbCso1GKEbsqJnkIz71GNAXB7irplaam6bNeA2za1GQ9bvwq41a5i qf09tWcxd7qQnNKY7LpV+6+z9AipKv/sg/BRXllA5WN74dgUqwRWz6hI+iVNZWxZrSvt qSeIZw7j4HSpIbFGrQUTHNgF2bTYjdKwGlkHBAGRe86LdYGO6QEhGApn95fENsrCsoZ1 O/2IzaCTCaqqy18EQj7jhB9eaKiuN020h6d2EQp8doBbg7VQqZIjBAp2E0OwSv+EHkch DCLg== X-Gm-Message-State: ALoCoQmdBRndlxsVkGmTMRK9ckc899/jG1qyfyJBx5AlwXC3xMyfHzwb0eL+QgZYl0c+Bewesn1V MIME-Version: 1.0 X-Received: by 10.60.16.230 with SMTP id j6mr1548598oed.8.1424313174719; Wed, 18 Feb 2015 18:32:54 -0800 (PST) Received: by 10.182.225.195 with HTTP; Wed, 18 Feb 2015 18:32:54 -0800 (PST) In-Reply-To: References: <21714.40641.510825.30998@ruffy2.mtv.corp.google.com> Date: Thu, 19 Feb 2015 02:32:00 -0000 Message-ID: Subject: Re: [RFC] [PATCH] Provide the ability to write the frame unwinder in Python From: Alexander Smundak To: Doug Evans Cc: gdb-patches Content-Type: text/plain; charset=UTF-8 X-SW-Source: 2015-02/txt/msg00512.txt.bz2 Ping. On Thu, Feb 12, 2015 at 9:58 AM, Alexander Smundak wrote: > On Wed, Feb 4, 2015 at 2:35 PM, Doug Evans wrote: >> High level comments: >> >> Is it possible to see the code, and example usage, of a real-life use-case >> of this? That will help folks not familiar with this project to understand >> the problem we are trying to solve. > The case in question is Java Virtual Machine. It is a JIT compiler for Java, > and it is part of the OpenJDK (Java Development Kit). It compiles Java > methods on the fly, and the emitted code omits frame pointers (e.g., on > x86_64 platform RBP is used as a general purpose register rather than > as frame pointer). And, the emitted code does not have unwind info > expected by GDB, so standard sniffers fail and the traceback stops when > it encounters a frame for the JIT-compiled code. > If we know how JVM works, we know where to find the descriptors of the > currently compiled code, and once we locate the descriptor for a given PC, > we can extract the frame size, and unwind the frame. > It's easier to have a custom sniffer than to make JVM maintain DWARF > unwind info. Besides, most of the code for the sniffer is reused by the > corresponding frame decorator. > The full implementation of the combined sniffer/frame filter for OpenJDK > is about 2500 lines and will eventually become part of it. I am waiting for > this GDB patch to be reviewed before I can present it to be reviewed by > the JDK community :-) > >> I'm still not sure what kind of performance cost we're looking at here as >> it scales up, I can imagine most times there'll be no Python sniffers, >> or at most one or two. But it would be good to collect some perf data >> (e.g., install 1,10,100 no-op sniffers and see if there's any measurable >> difference in backtrace performance). > I ran a test that walks a 100-frame stack calling 100 Python sniffers > per frame, and it executes (throught the dejagnu checker) in 500ms on > Xeon E5-1650 0 @ 3.20GHz. > Please let me know if you would like it to be added to gdb/testsuite. > >> Exposing frame id implementation details (sp,pc,special), and the >> form of how to do that, is something the community needs to decide on. >> I think we can come up with something suitable, though perhaps not >> the current form. > > The revised patch is attached. The important differences are as follows: > * A sniffer is now an object, using the pattern similar to xmethods > and pretty printers. > * Register values are properly types (that is, based on a register type) > > I am still not certain whether it's worth changing SnifferInfo.read_register to > have registers retrieved by name rather than by its number. Perhaps > adding gdb.Architecture.register_name_to_number method will be > a reasonable tradeoff? > > The documentation is obviously unfinished (to be done once the design > issues are resolved), and what exists needs to be put into proper > English. > > Here's take two: > > gdb/ChangeLog: > 2015-02-28 Sasha Smundak > > * Makefile.in (SUBDIR_PYTHON_OBJS): Add py-unwind.o. > (SUBDIR_PYTHON_SRCS): Add py-unwind.c. > (py-unwind.o): New recipe. > * NEWS: mention Python frame unwinding. > * data-directory/Makefile.in (PYTHON_FILE_LIST): Add sniffers.py. > * doc/python.texi (Writing a Frame Unwinder in Python): Add > section. > * python/lib/gdb/__init__.py (packages): Add frame_sniffers list. > * python/lib/gdb/command/sniffers.py: New file, implements GDB > commands to list/enable/disable Python sniffers. > * python/lib/gdb/function/sniffers.py: New file, implements > execute_sniffers function. > * python/lib/gdb/sniffer.py: New file, contains Sniffer class and > register_sniffer function. > * python/py-objfile.c (objfile_object): Add frame_sniffers field. > (objfpy_dealloc): Decrement frame_sniffers reference count. > (objfpy_initialize): Create frame_sniffers list. > (objfpy_get_frame_sniffers): Implement Objfile.frame_sniffers > getter. > (objfpy_set_frame_sniffers): Implement Objfile.frame_sniffers > setter. > (objfile_getset): Add frame_sniffers attribute to Objfile. > * python/py-progspace.c (pspace_object): Add frame_sniffers field. > (pspy_dealloc): Decrement frame_sniffers reference count. > (pspy_initialize): Create frame_sniffers list. > (pspy_get_frame_sniffers): Implement gdb.Progspace.frame_sniffers > getter. > (pspy_set_frame_sniffers): Implement gdb.Progspace.frame_sniffers > setter. > (pspy_getset): Add frame_sniffers attribute to gdb.Progspace. > * python/py-unwind.c: New file, implements Python frame sniffers > interface. > * python/python-internal.h (pspy_get_name_sniffers): New prototype. > (objpy_get_frame_sniffers): New prototype. > (gdbpy_initialize_unwind): New prototype. > * python/python.c (gdbpy_apply_type_printers): Call > gdbpy_initialize_unwind. > > gdb/testsuite/ChangeLog: > 2014-02-30 Sasha Smundak > > * gdb.python/py-unwind-maint.c: Test program for py-unwind-maint. > * gdb.python/py-unwind-maint.exp: Tests sniffer-related GDB > commands. > * gdb.python/py-unwind-maint.py: Pythons sniffers for the test. > * gdb.python/py-unwind.c: Test program for the py-unwind test. > * gdb.python/py-unwind.exp: Python frame sniffers test. > * gdb.python/py-unwind.py: Frame sniffer in Python tested by > py-unwind test.