From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 888963858D1E for ; Wed, 20 Mar 2024 14:13:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 888963858D1E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 888963858D1E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1710944025; cv=none; b=whCt8+6lQvN4IEw7UzcxT3YA45fwBN7CAS0HWXKgKAlTbjx62pPwT1uysY+MoxJb/KayRx4NJWbGZjKLzA6IOFs1wlxfEv7vCGPqsERYNWQmu9dELM6oM9MTtjvHo3tlcwvUVhdfSHMyDTmhiWOvuOuEd8m6fmufYF16op+iFrA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1710944025; c=relaxed/simple; bh=Y7zRWBPi/SAXJ9egHPWDAC8kBGyqNfmBgE8a26cYzrU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=SB7SsQvsBql7Pd7Cee7c/TdB+BYZfL/+rXObJJNkKG4POQTLv1GVgOMjM1HvghUilwfs2ikbu4rEz9UmzzOupoFh+yXazg4LsbCMAyV5E/7VsjAYclFI0h6b/T4xgi3bFlP7EIkfGYykRAe7CFz2pixLBOfHLkcOSE0w3XxMIis= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1710944017; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Aa7IxPz9An2OdgYCpLJfV6aArQ6AZ3nf55UvU/Lamn4=; b=aQqdHEKdDhZrV78t5dFu5s0Kt/m8ljhZ17ly6yL9hBHpK3PRFdt4BuJdufz2wcVZNLP2qo aEzqR1kMEa1XUiOwOm7yaQMpRqCtcLyx9auDkIKPPlvh1FJOzw3d9pCWE7Jv8YIlJQ+120 w2+Ed0UHyjt9Wk0knSDsLsuC8+18VS0= Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-464-PVw5I6kFOee5Q5Xd-u_5Zg-1; Wed, 20 Mar 2024 10:13:34 -0400 X-MC-Unique: PVw5I6kFOee5Q5Xd-u_5Zg-1 Received: by mail-ej1-f72.google.com with SMTP id a640c23a62f3a-a46f5f2896dso45166766b.3 for ; Wed, 20 Mar 2024 07:13:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710944013; x=1711548813; h=content-transfer-encoding:mime-version:message-id:date:references :in-reply-to:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jh1DLmfEvE5xL9MZuWvufv0w3t+zngDSYdSRXNKXCd0=; b=FkeuP9m6Fo2L1g8zbA3d4VWqzwm9XgV3R6LbGxyp0Zsx8Utq4ccoA+heBwmxAsPXDv UZfkEVOR9a0Mpb4YEdsMhk00aXYAPOZZV+7cSUktZ3Wm/0vqOGbozazooDI8c3n574JF UZwOmTtidkK7XP4FMeEbCQsEq3wJsqb39GzJCxUihFZL+7dWX9Hr8808ws2YYngczX5v jc7cERntkkaQawpRWllq9dP9N0WIrACu6yDInqCvRDfYp8ZNfiDv0jxipTbw6gbDDmAf riL7R9cKeWsAJ9Anc75HNWLjxKhuQQz2WKoL6F3MGf3PkGkrJ7qpmraIgHkcmRa4/eSR S4MA== X-Forwarded-Encrypted: i=1; AJvYcCWiVvjh62TQ/qJoe2/LeJc0qoFVDXPfBM5wRO9C6LovM0zAajKX8JuAryX5YiBAij0QKf4y2BQVF0QvE0y0rYEB7EXUyJf/4lu3Dg== X-Gm-Message-State: AOJu0YyvGY3+y4eJgmNJ5J0aRXMuGBejxM8hmT+JkVS7ww31AmEqim9I 0oDkw4BMrD7Bm1TyeZdy9jaV8eR4qbNpALvelTN/sjVBYZhUilOsWOzOePVI/RnQCIYggUSy3Z4 zO28rd5rvovK/t8I6MGCf1f7g2bScmxO5IfM3eMYrDTyf0NQB05KC7Zju0DluCxLOTfk= X-Received: by 2002:a17:907:940c:b0:a46:ea52:3ed2 with SMTP id dk12-20020a170907940c00b00a46ea523ed2mr3112765ejc.44.1710944012699; Wed, 20 Mar 2024 07:13:32 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEqhPkYd1qJIOx1CYeKGy4Je0Zx0e/q3BPjPx2LR9UwGJ4pFr9ZePOJ7OG92zdIABiPONxgNg== X-Received: by 2002:a17:907:940c:b0:a46:ea52:3ed2 with SMTP id dk12-20020a170907940c00b00a46ea523ed2mr3112742ejc.44.1710944012117; Wed, 20 Mar 2024 07:13:32 -0700 (PDT) Received: from localhost (185.223.159.143.dyn.plus.net. [143.159.223.185]) by smtp.gmail.com with ESMTPSA id en6-20020a17090728c600b00a465a012cf1sm7436683ejc.18.2024.03.20.07.13.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Mar 2024 07:13:31 -0700 (PDT) From: Andrew Burgess To: =?utf-8?Q?R=C3=A9mi?= Bernon , gdb-patches@sourceware.org Cc: =?utf-8?Q?R=C3=A9mi?= Bernon Subject: Re: [PATCH] gdb/python: Allow SIGTRAMP_FRAME python unwinders to be created. In-Reply-To: <20240214215916.2655301-1-rbernon@codeweavers.com> References: <20240214215916.2655301-1-rbernon@codeweavers.com> Date: Wed, 20 Mar 2024 14:13:30 +0000 Message-ID: <87h6h1t2id.fsf@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: R=C3=A9mi Bernon writes: > Wine now executes Win32 code on a separate stack for its Unix code. It > switches from one stack to another on through specific functions, and > without any custom unwinders, debugging Wine in Gdb will only let you > see the frames of either the Win32 side, or the Unix side. > > The Win32 and Unix call stacks are actually interleaved, with Unix code > sometimes calling back into Win32. Using a custom Python frame unwinder > we can provide Gdb with the information it needs to join both toghether > and show a complete interleaved call stack. However, Gdb will often stop > unwinding as it will see the frames from one stack as inner the frames > from the other stack. > > This allows to write custom unwinders to produce SIGTRAMP_FRAME typed > frames, which bypasses this restriction and will show the Win32 / Unix > gate as a signal frame. > --- > gdb/python/lib/gdb/__init__.py | 8 ++++---- > gdb/python/lib/gdb/unwinder.py | 7 ++++++- > gdb/python/py-unwind.c | 16 +++++++++++++++- As Guinevere pointed out, this will really need a test case. But also you'll need to update the documentation. > 3 files changed, 25 insertions(+), 6 deletions(-) > > diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__= .py > index b3124369fe8..d9226440cbc 100644 > --- a/gdb/python/lib/gdb/__init__.py > +++ b/gdb/python/lib/gdb/__init__.py > @@ -86,7 +86,7 @@ frame_filters =3D {} > frame_unwinders =3D [] > =20 > =20 > -def _execute_unwinders(pending_frame): > +def _execute_unwinders(pending_frame, frame_type): There are lots of different frame types, but in the C++ code we only invoke for NORMAL_FRAME and SIGTRAMP_FRAME, yet a user could register an unwinder for e.g. INLINE_FRAME, and that'll never be used. So at a minimum I think we need additional error checking when unwinders are registered. Also, there's the 'info unwinder' command which would need updating to display the unwinder type I think. I wonder if instead of giving frames a type, if we could have GDB ask the unwinder if it should perform a more-inner check, and the Python unwinders could just say no. Guinevere has some patches that C++-ify the unwinders, so this might make it easier to add new methods, which might make doing something like this easier. I think there's only two places where the more-inner check is performed, so I'd be interested to see what drawbacks there might be to this approach. > """Internal function called from GDB to execute all unwinders. > =20 > Runs each currently enabled unwinder until it finds the one that > @@ -105,19 +105,19 @@ def _execute_unwinders(pending_frame): > """ > for objfile in objfiles(): > for unwinder in objfile.frame_unwinders: > - if unwinder.enabled: > + if unwinder.enabled and unwinder.frame_type =3D=3D frame_typ= e: > unwind_info =3D unwinder(pending_frame) > if unwind_info is not None: > return (unwind_info, unwinder.name) > =20 > for unwinder in current_progspace().frame_unwinders: > - if unwinder.enabled: > + if unwinder.enabled and unwinder.frame_type =3D=3D frame_type: > unwind_info =3D unwinder(pending_frame) > if unwind_info is not None: > return (unwind_info, unwinder.name) > =20 > for unwinder in frame_unwinders: > - if unwinder.enabled: > + if unwinder.enabled and unwinder.frame_type =3D=3D frame_type: > unwind_info =3D unwinder(pending_frame) > if unwind_info is not None: > return (unwind_info, unwinder.name) > diff --git a/gdb/python/lib/gdb/unwinder.py b/gdb/python/lib/gdb/unwinder= .py > index 140b84d3374..7e23a662a32 100644 > --- a/gdb/python/lib/gdb/unwinder.py > +++ b/gdb/python/lib/gdb/unwinder.py > @@ -29,7 +29,7 @@ class Unwinder(object): > enabled: A boolean indicating whether the unwinder is enabled. > """ > =20 > - def __init__(self, name): > + def __init__(self, name, frame_type=3Dgdb.NORMAL_FRAME): > """Constructor. > =20 > Args: > @@ -39,9 +39,14 @@ class Unwinder(object): > if not isinstance(name, str): > raise TypeError("incorrect type for name: %s" % type(name)) > =20 > + self._frame_type =3D frame_type > self._name =3D name > self._enabled =3D True > =20 > + @property > + def frame_type(self): > + return self._frame_type > + > @property > def name(self): > return self._name > diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c > index 1856e41e2a1..2d36c43d342 100644 > --- a/gdb/python/py-unwind.c > +++ b/gdb/python/py-unwind.c > @@ -844,7 +844,8 @@ pyuw_sniffer (const struct frame_unwind *self, frame_= info_ptr this_frame, > /* A (gdb.UnwindInfo, str) tuple, or None. */ > gdbpy_ref<> pyo_execute_ret > (PyObject_CallFunctionObjArgs (pyo_execute.get (), > -=09=09=09=09 pyo_pending_frame.get (), NULL)); > +=09=09=09=09 pyo_pending_frame.get (), > +=09=09=09=09 PyLong_FromLong(self->type), NULL)); Nit: missing a space after PyLong_FromLong before the '('. Thanks, Andrew > if (pyo_execute_ret =3D=3D nullptr) > { > /* If the unwinder is cancelled due to a Ctrl-C, then propagate > @@ -965,6 +966,19 @@ pyuw_on_new_gdbarch (struct gdbarch *newarch) > unwinder->sniffer =3D pyuw_sniffer; > unwinder->dealloc_cache =3D pyuw_dealloc_cache; > frame_unwind_prepend_unwinder (newarch, unwinder); > + > + struct frame_unwind *unwinder_signals > +=09 =3D GDBARCH_OBSTACK_ZALLOC (newarch, struct frame_unwind); > + > + unwinder_signals->name =3D "python-sigtramp"; > + unwinder_signals->type =3D SIGTRAMP_FRAME; > + unwinder_signals->stop_reason =3D default_frame_unwind_stop_reason= ; > + unwinder_signals->this_id =3D pyuw_this_id; > + unwinder_signals->prev_register =3D pyuw_prev_register; > + unwinder_signals->unwind_data =3D (const struct frame_data *) newa= rch; > + unwinder_signals->sniffer =3D pyuw_sniffer; > + unwinder_signals->dealloc_cache =3D pyuw_dealloc_cache; > + frame_unwind_prepend_unwinder (newarch, unwinder_signals); > data->unwinder_registered =3D 1; > } > } > --=20 > 2.43.0