From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8891121ADD3; Thu, 24 Apr 2025 20:16:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745525789; cv=none; b=o76gKTPBD/SYAWPqhYu123S1rVntJlLbQeU96uK8GTBplwdlbEp+x7p5lfhB7LM+8b6TklP1U2XnR4MVHOoS/XbbGAgza9oKuoG2qHLD0ISI1nSryqqpnfIfW2eQUds1LHKhhrlXKCJdoaIz1muPNAPHOHOa69OoE56D6z/Q/VE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1745525789; c=relaxed/simple; bh=EU70MImtkP/SrBRzMUmlp9R7NfTJ1mK3wDaWyhsT0r0=; h=Message-ID:Date:From:To:Cc:Subject:References:MIME-Version: Content-Type; b=LGkKeyrHhQIt/aj55d1bpBh0Rml0Ep4BoiUNiedxnCk0XyxYNDiOn2w5WL28HdzctZzXvkt1Q8Uge5ZysiMjVLckZa8B5uFxfpU1B3LnvLv3XFfx12NdkHqIcM6nvs+NO/dXEuA9apenrVmdzeQU8r5aX8h7E3pCt0TxIFbuThU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id F40C8C4CEFB; Thu, 24 Apr 2025 20:16:28 +0000 (UTC) Received: from rostedt by gandalf with local (Exim 4.98) (envelope-from ) id 1u831d-0000000H3xC-1F73; Thu, 24 Apr 2025 16:18:25 -0400 Message-ID: <20250424201825.147499572@goodmis.org> User-Agent: quilt/0.68 Date: Thu, 24 Apr 2025 16:15:21 -0400 From: Steven Rostedt To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org Cc: Masami Hiramatsu , Mark Rutland , Mathieu Desnoyers , Andrew Morton , Josh Poimboeuf , x86@kernel.org, Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Indu Bhagat , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Ian Rogers , Adrian Hunter , linux-perf-users@vger.kernel.org, Mark Brown , linux-toolchains@vger.kernel.org, Jordan Rome , Sam James , Andrii Nakryiko , Jens Remus , Florian Weimer , Andy Lutomirski , Weinan Liu , Blake Jones , Beau Belgrave , "Jose E. Marchesi" , Alexander Aring Subject: [PATCH v5 10/12] unwind_user/sframe: Show file name in debug output References: <20250424201511.921245242@goodmis.org> Precedence: bulk X-Mailing-List: linux-perf-users@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 From: Josh Poimboeuf When debugging sframe issues, the error messages aren't all that helpful without knowing what file a corresponding .sframe section belongs to. Prefix debug output strings with the file name. Signed-off-by: Josh Poimboeuf Signed-off-by: Steven Rostedt (Google) --- Changes from v4: https://lore.kernel.org/all/7bfb7ffad5fe384fe3dbe6c8ca985f35b98b48bb.1737511963.git.jpoimboe@kernel.org/ - Added Josh's fix up include/linux/sframe.h | 4 +++- kernel/unwind/sframe.c | 23 ++++++++++-------- kernel/unwind/sframe_debug.h | 45 +++++++++++++++++++++++++++++++----- 3 files changed, 56 insertions(+), 16 deletions(-) diff --git a/include/linux/sframe.h b/include/linux/sframe.h index 9a72209696f9..b79c5ec09229 100644 --- a/include/linux/sframe.h +++ b/include/linux/sframe.h @@ -10,7 +10,9 @@ struct sframe_section { struct rcu_head rcu; - +#ifdef CONFIG_DYNAMIC_DEBUG + const char *filename; +#endif unsigned long sframe_start; unsigned long sframe_end; unsigned long text_start; diff --git a/kernel/unwind/sframe.c b/kernel/unwind/sframe.c index 66b920441692..f463123f9afe 100644 --- a/kernel/unwind/sframe.c +++ b/kernel/unwind/sframe.c @@ -295,14 +295,17 @@ int sframe_find(unsigned long ip, struct unwind_user_frame *frame) end: user_read_access_end(); - if (ret == -EFAULT) + if (ret == -EFAULT) { + dbg_sec("removing bad .sframe section\n"); WARN_ON_ONCE(sframe_remove_section(sec->sframe_start)); + } return ret; } static void free_section(struct sframe_section *sec) { + dbg_free(sec); kfree(sec); } @@ -313,7 +316,7 @@ static int sframe_read_header(struct sframe_section *sec) unsigned int num_fdes; if (copy_from_user(&shdr, (void __user *)sec->sframe_start, sizeof(shdr))) { - dbg("header usercopy failed\n"); + dbg_sec("header usercopy failed\n"); return -EFAULT; } @@ -321,18 +324,18 @@ static int sframe_read_header(struct sframe_section *sec) shdr.preamble.version != SFRAME_VERSION_2 || !(shdr.preamble.flags & SFRAME_F_FDE_SORTED) || shdr.auxhdr_len) { - dbg("bad/unsupported sframe header\n"); + dbg_sec("bad/unsupported sframe header\n"); return -EINVAL; } if (!shdr.num_fdes || !shdr.num_fres) { - dbg("no fde/fre entries\n"); + dbg_sec("no fde/fre entries\n"); return -EINVAL; } header_end = sec->sframe_start + SFRAME_HEADER_SIZE(shdr); if (header_end >= sec->sframe_end) { - dbg("header doesn't fit in section\n"); + dbg_sec("header doesn't fit in section\n"); return -EINVAL; } @@ -344,7 +347,7 @@ static int sframe_read_header(struct sframe_section *sec) fres_end = fres_start + shdr.fre_len; if (fres_start < fdes_end || fres_end > sec->sframe_end) { - dbg("inconsistent fde/fre offsets\n"); + dbg_sec("inconsistent fde/fre offsets\n"); return -EINVAL; } @@ -400,6 +403,8 @@ int sframe_add_section(unsigned long sframe_start, unsigned long sframe_end, sec->text_start = text_start; sec->text_end = text_end; + dbg_init(sec); + ret = sframe_read_header(sec); if (ret) { dbg_print_header(sec); @@ -408,8 +413,8 @@ int sframe_add_section(unsigned long sframe_start, unsigned long sframe_end, ret = mtree_insert_range(sframe_mt, sec->text_start, sec->text_end, sec, GFP_KERNEL); if (ret) { - dbg("mtree_insert_range failed: text=%lx-%lx\n", - sec->text_start, sec->text_end); + dbg_sec("mtree_insert_range failed: text=%lx-%lx\n", + sec->text_start, sec->text_end); goto err_free; } @@ -431,7 +436,7 @@ static int __sframe_remove_section(struct mm_struct *mm, struct sframe_section *sec) { if (!mtree_erase(&mm->sframe_mt, sec->text_start)) { - dbg("mtree_erase failed: text=%lx\n", sec->text_start); + dbg_sec("mtree_erase failed: text=%lx\n", sec->text_start); return -EINVAL; } diff --git a/kernel/unwind/sframe_debug.h b/kernel/unwind/sframe_debug.h index 055c8c8fae24..7794bf0bd78c 100644 --- a/kernel/unwind/sframe_debug.h +++ b/kernel/unwind/sframe_debug.h @@ -10,26 +10,59 @@ #define dbg(fmt, ...) \ pr_debug("%s (%d): " fmt, current->comm, current->pid, ##__VA_ARGS__) +#define dbg_sec(fmt, ...) \ + dbg("%s: " fmt, sec->filename, ##__VA_ARGS__) + static __always_inline void dbg_print_header(struct sframe_section *sec) { unsigned long fdes_end; fdes_end = sec->fdes_start + (sec->num_fdes * sizeof(struct sframe_fde)); - dbg("SEC: sframe:0x%lx-0x%lx text:0x%lx-0x%lx " - "fdes:0x%lx-0x%lx fres:0x%lx-0x%lx " - "ra_off:%d fp_off:%d\n", - sec->sframe_start, sec->sframe_end, sec->text_start, sec->text_end, - sec->fdes_start, fdes_end, sec->fres_start, sec->fres_end, - sec->ra_off, sec->fp_off); + dbg_sec("SEC: sframe:0x%lx-0x%lx text:0x%lx-0x%lx " + "fdes:0x%lx-0x%lx fres:0x%lx-0x%lx " + "ra_off:%d fp_off:%d\n", + sec->sframe_start, sec->sframe_end, sec->text_start, sec->text_end, + sec->fdes_start, fdes_end, sec->fres_start, sec->fres_end, + sec->ra_off, sec->fp_off); +} + +static inline void dbg_init(struct sframe_section *sec) +{ + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + + guard(mmap_read_lock)(mm); + vma = vma_lookup(mm, sec->sframe_start); + if (!vma) + sec->filename = kstrdup("(vma gone???)", GFP_KERNEL); + else if (vma->vm_file) + sec->filename = kstrdup_quotable_file(vma->vm_file, GFP_KERNEL); + else if (vma->vm_ops && vma->vm_ops->name) + sec->filename = kstrdup(vma->vm_ops->name(vma), GFP_KERNEL); + else if (arch_vma_name(vma)) + sec->filename = kstrdup(arch_vma_name(vma), GFP_KERNEL); + else if (!vma->vm_mm) + sec->filename = kstrdup("(vdso)", GFP_KERNEL); + else + sec->filename = kstrdup("(anonymous)", GFP_KERNEL); +} + +static inline void dbg_free(struct sframe_section *sec) +{ + kfree(sec->filename); } #else /* !CONFIG_DYNAMIC_DEBUG */ #define dbg(args...) no_printk(args) +#define dbg_sec(args... ) no_printk(args) static inline void dbg_print_header(struct sframe_section *sec) {} +static inline void dbg_init(struct sframe_section *sec) {} +static inline void dbg_free(struct sframe_section *sec) {} + #endif /* !CONFIG_DYNAMIC_DEBUG */ #endif /* _SFRAME_DEBUG_H */ -- 2.47.2