From patchwork Tue Oct 15 15:26:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serhei Makarov X-Patchwork-Id: 98961 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E08CE3857C5D for ; Tue, 15 Oct 2024 15:29:14 +0000 (GMT) X-Original-To: elfutils-devel@sourceware.org Delivered-To: elfutils-devel@sourceware.org Received: from fout-a4-smtp.messagingengine.com (fout-a4-smtp.messagingengine.com [103.168.172.147]) by sourceware.org (Postfix) with ESMTPS id ADCF33858C41 for ; Tue, 15 Oct 2024 15:29:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org ADCF33858C41 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=serhei.io Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=serhei.io ARC-Filter: OpenARC Filter v1.0.0 sourceware.org ADCF33858C41 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=103.168.172.147 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1729006145; cv=none; b=tdOwkBOU+HLp0y4pdUdViboRU7EuyMDwmq9oRQ/JblFClRHga8SdEDGi99v+ZNBEG/yTKlE2yNmthE9wUo96TV5Qj2QHJpK4qcz/gu6+jz0dvlpAyTlaYLTmWOZlnxSgZh9QW83nGq3uqfUglLfuEiRx0IjDyo68xnIql+qF5XI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1729006145; c=relaxed/simple; bh=XtVGtho98cy/DEM0p3VOYYPmWx2NQDRhwPRH8h+jdMo=; h=DKIM-Signature:DKIM-Signature:MIME-Version:Date:From:To: Message-Id:Subject; b=Hf7heL35WsI6ypY3jF30ncCx9+PepY1w3ULhyKgLI8WZnrMHikbBSmit81jo9mBlE9dUAIG18PGQzZNuLcbQ7F3dlIzVys0iHaDGl4qd9RIMuSqnMDLsLh7oHKb7yCV73RxZ0lgBX9qAjRVzRl95RGJWI+3/vwka/u0zSXf2YTU= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from phl-compute-07.internal (phl-compute-07.phl.internal [10.202.2.47]) by mailfout.phl.internal (Postfix) with ESMTP id 81ADD138021C for ; Tue, 15 Oct 2024 11:29:01 -0400 (EDT) Received: from phl-imap-10 ([10.202.2.85]) by phl-compute-07.internal (MEProxy); Tue, 15 Oct 2024 11:29:01 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=serhei.io; h=cc :content-transfer-encoding:content-type:content-type:date:date :from:from:in-reply-to:message-id:mime-version:reply-to:subject :subject:to:to; s=fm2; t=1729006141; x=1729092541; bh=bXlNXMof3y AlS/rURuoTPgjchzahtkxDLa/T8hzApgM=; b=IpYHtsFmQtVSezqWZ+7FI0RHdM T9mK/O5WilkuANeTcx85vMFyEb77618WFrImwZiXpeTbpvoTyWlOvavMHYEws0ix HdAItntzfeR56TiBVwkodSoXieolFJup7YOX5rf9KoVE9PXc31wi+vukJmf0ohQU Nvr3a4fa33wrFdK7TToZL3vlV923SY7G43MQFsrzKbnOrzHd89nzpRitg3E52g13 0xZNRV6shtx0UKf5hs9Wuy9qq1muI6yO1sGWXhDpMCyIOh6jUXJDWO5krnv8fXT9 4MvxiIs6ECdrLG6zhTmEk6KtRtYjeFbk7FX5Pex5CmRLjRsd4PC8kUG9EGCw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:message-id:mime-version:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; t=1729006141; x=1729092541; bh=bXlNXMof3yAlS/rURuoTPgjchzah tkxDLa/T8hzApgM=; b=Olky9oLRWFQlab7I8Gg/K1BBNsf0uphmfzz0E6nRyyyv nal4pdknpnVhYBe+lYVsvug3Pq9YniE0Ut+U4KASkxqkBspZvZR0ZQxyTNAloP5P g+EwYX0XJjpBf9S3D5h9VN+AxJs2gGjrpVu9f8vg9VxD3ZPbCsCRusWYPLrEyxZg uQzX6oIWGQ2EVYcHzIBJ5grYCHWq5hcNNLe7ngWu3tTLzY/tAsXDz3WRNfFrQlW1 p8jVKk+a73y9FNfBIJGiBrP+LU6HsndEyZavZkSlchaE0YFp2fjPxopgLOfuk6BN +K5jhQr/YEq7kAMYsBMGgaMTytC/IdbLyfOVZocAKw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeftddrvdegjedgkeekucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucenucfjughrpefoggffhf fvkffutgfgsehtjeertdertddtnecuhfhrohhmpedfufgvrhhhvghiucforghkrghrohhv fdcuoehsvghrhhgvihesshgvrhhhvghirdhioheqnecuggftrfgrthhtvghrnhepgeevve ehudeuudetleeuudefteekleefhedvjeefkeevtddvueeugeegvdevudeinecuvehluhhs thgvrhfuihiivgepvdenucfrrghrrghmpehmrghilhhfrhhomhepshgvrhhhvghisehsvg hrhhgvihdrihhopdhnsggprhgtphhtthhopedupdhmohguvgepshhmthhpohhuthdprhgt phhtthhopegvlhhfuhhtihhlshdquggvvhgvlhesshhouhhrtggvfigrrhgvrdhorhhg X-ME-Proxy: Feedback-ID: i572946fc:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 4B8673C0066; Tue, 15 Oct 2024 11:29:01 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface MIME-Version: 1.0 Date: Tue, 15 Oct 2024 11:26:30 -0400 From: "Serhei Makarov" To: elfutils-devel@sourceware.org Message-Id: <4313311c-5df8-4f78-a7ca-bccbede8a20a@app.fastmail.com> Subject: [PATCH 4/4] eu-stacktrace: add unwind origin diagnostics to eu-stack X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, JMQ_SPF_NEUTRAL, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: elfutils-devel@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Elfutils-devel mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: elfutils-devel-bounces~patchwork=sourceware.org@sourceware.org Since we obtain diagnostics about unwind method, another logical place to show them is in eu-stack. This requires an additional pseudo-unwind type DWFL_UNWOUND_INLINE to clarify what happens with entries for inlined functions (which eu-stacktrace does not display) based on the same Dwfl_Frame. * libdwfl/libdwfl.h (Dwfl_Unwound_Source): Add DWFL_UNWOUND_INLINE. * libdwfl/dwfl_frame.c (dwfl_unwound_source_str): Handle DWFL_UNWOUND_INLINE. * src/stack.c (show_unwound_source): New global variable. (struct frame): Add unwound_source field. (frame_callback): Copy over unwound_source from Dwfl_Frame. (print_frame): Take unwound_source argument and print it. (print_inline_frames): Take unwound_source argument and pass it on, except for subsequent frames where DWFL_UNWOUND_INLINE is assumed. (print_frames): Take unwound_source field from struct frame and pass it on. (parse_opt): Add --cfi-type,-c option to set show_unwound_source. (main): Ditto. * tests/run-stack-i-test.sh: Add testcase for --cfi-type. Signed-off-by: Serhei Makarov --- libdwfl/dwfl_frame.c | 2 ++ libdwfl/libdwfl.h | 1 + src/stack.c | 31 ++++++++++++++++++++++++------- tests/run-stack-i-test.sh | 15 ++++++++++++++- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/libdwfl/dwfl_frame.c b/libdwfl/dwfl_frame.c index 2e6c6de8..3659420a 100644 --- a/libdwfl/dwfl_frame.c +++ b/libdwfl/dwfl_frame.c @@ -265,6 +265,8 @@ dwfl_unwound_source_str (Dwfl_Unwound_Source unwound_source) return "none"; case DWFL_UNWOUND_INITIAL_FRAME: return "initial"; + case DWFL_UNWOUND_INLINE: + return "inline"; case DWFL_UNWOUND_EH_CFI: return "eh_frame"; case DWFL_UNWOUND_DWARF_CFI: diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h index ffd951db..21cb7d8d 100644 --- a/libdwfl/libdwfl.h +++ b/libdwfl/libdwfl.h @@ -53,6 +53,7 @@ typedef struct Dwfl_Frame Dwfl_Frame; typedef enum { DWFL_UNWOUND_NONE = 0, DWFL_UNWOUND_INITIAL_FRAME, + DWFL_UNWOUND_INLINE, /* XXX used for src/stack.c print_inline_frames() */ DWFL_UNWOUND_EH_CFI, DWFL_UNWOUND_DWARF_CFI, DWFL_UNWOUND_EBL, diff --git a/src/stack.c b/src/stack.c index eb87f5f1..baee9cae 100644 --- a/src/stack.c +++ b/src/stack.c @@ -1,5 +1,5 @@ /* Unwinding of frames like gstack/pstack. - Copyright (C) 2013-2014 Red Hat, Inc. + Copyright (C) 2013-2014, 2024 Red Hat, Inc. This file is part of elfutils. This file is free software; you can redistribute it and/or modify @@ -44,6 +44,7 @@ ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT; static bool show_activation = false; static bool show_module = false; static bool show_build_id = false; +static bool show_unwound_source = false; static bool show_source = false; static bool show_one_tid = false; static bool show_quiet = false; @@ -58,6 +59,7 @@ struct frame { Dwarf_Addr pc; bool isactivation; + Dwfl_Unwound_Source unwound_source; }; struct frames @@ -180,6 +182,7 @@ frame_callback (Dwfl_Frame *state, void *arg) { struct frames *frames = (struct frames *) arg; int nr = frames->frames; + frames->frame[nr].unwound_source = dwfl_frame_unwound_source (state); if (! dwfl_frame_pc (state, &frames->frame[nr].pc, &frames->frame[nr].isactivation)) return -1; @@ -221,7 +224,7 @@ static void print_frame (int nr, Dwarf_Addr pc, bool isactivation, Dwarf_Addr pc_adjusted, Dwfl_Module *mod, const char *symname, Dwarf_Die *cudie, - Dwarf_Die *die) + Dwarf_Die *die, Dwfl_Unwound_Source unwound_source) { int width = get_addr_width (mod); printf ("#%-2u 0x%0*" PRIx64, nr, width, (uint64_t) pc); @@ -271,6 +274,11 @@ print_frame (int nr, Dwarf_Addr pc, bool isactivation, } } + if (show_unwound_source) + { + printf (" [%s]", dwfl_unwound_source_str (unwound_source)); + } + if (show_source) { int line, col; @@ -323,7 +331,8 @@ print_frame (int nr, Dwarf_Addr pc, bool isactivation, static void print_inline_frames (int *nr, Dwarf_Addr pc, bool isactivation, Dwarf_Addr pc_adjusted, Dwfl_Module *mod, - const char *symname, Dwarf_Die *cudie, Dwarf_Die *die) + const char *symname, Dwarf_Die *cudie, Dwarf_Die *die, + Dwfl_Unwound_Source unwound_source) { Dwarf_Die *scopes = NULL; int nscopes = dwarf_getscopes_die (die, &scopes); @@ -333,7 +342,7 @@ print_inline_frames (int *nr, Dwarf_Addr pc, bool isactivation, the name. This is the actual source location where it happened. */ print_frame ((*nr)++, pc, isactivation, pc_adjusted, mod, symname, - NULL, NULL); + NULL, NULL, unwound_source); /* last_scope is the source location where the next frame/function call was done. */ @@ -349,7 +358,8 @@ print_inline_frames (int *nr, Dwarf_Addr pc, bool isactivation, symname = die_name (scope); print_frame ((*nr)++, pc, isactivation, pc_adjusted, mod, symname, - cudie, last_scope); + cudie, last_scope, + i > 1 ? DWFL_UNWOUND_INLINE : unwound_source); /* Found the "top-level" in which everything was inlined? */ if (tag == DW_TAG_subprogram) @@ -375,6 +385,7 @@ print_frames (struct frames *frames, pid_t tid, int dwflerr, const char *what) Dwarf_Addr pc = frames->frame[nr].pc; bool isactivation = frames->frame[nr].isactivation; Dwarf_Addr pc_adjusted = pc - (isactivation ? 0 : 1); + Dwfl_Unwound_Source unwound_source = frames->frame[nr].unwound_source; /* Get PC->SYMNAME. */ Dwfl_Module *mod = dwfl_addrmodule (dwfl, pc_adjusted); @@ -417,10 +428,10 @@ print_frames (struct frames *frames, pid_t tid, int dwflerr, const char *what) if (show_inlines && die != NULL) print_inline_frames (&frame_nr, pc, isactivation, pc_adjusted, mod, - symname, cudie, die); + symname, cudie, die, unwound_source); else print_frame (frame_nr++, pc, isactivation, pc_adjusted, mod, symname, - NULL, NULL); + NULL, NULL, unwound_source); } if (frames->frames > 0 && frame_nr == maxframes) @@ -535,6 +546,10 @@ parse_opt (int key, char *arg __attribute__ ((unused)), show_build_id = true; break; + case 'c': + show_unwound_source = true; + break; + case 'q': show_quiet = true; break; @@ -676,6 +691,8 @@ main (int argc, char **argv) N_("Show raw function symbol names, do not try to demangle names"), 0 }, { "build-id", 'b', NULL, 0, N_("Show module build-id, load address and pc offset"), 0 }, + { "cfi-type", 'c', NULL, 0, + N_("Show the backtrace method for each frame (eh_frame, dwarf, inline, or ebl)"), 0 }, { NULL, '1', NULL, 0, N_("Show the backtrace of only one thread"), 0 }, { NULL, 'n', "MAXFRAMES", 0, diff --git a/tests/run-stack-i-test.sh b/tests/run-stack-i-test.sh index 3722ab09..bc46d9d5 100755 --- a/tests/run-stack-i-test.sh +++ b/tests/run-stack-i-test.sh @@ -1,5 +1,5 @@ #! /bin/sh -# Copyright (C) 2014, 2015 Red Hat, Inc. +# Copyright (C) 2014, 2015, 2024 Red Hat, Inc. # This file is part of elfutils. # # This file is free software; you can redistribute it and/or modify @@ -73,6 +73,19 @@ TID 13654: $STACKCMD: tid 13654: shown max number of frames (6, use -n 0 for unlimited) EOF +# With --cfi-type we also see what unwind method was used for each frame: +testrun_compare ${abs_top_builddir}/src/stack -r -n 6 -c -i -e testfiledwarfinlines --core testfiledwarfinlines.core<