From: Ihor Solodrai <ihor.solodrai@linux.dev>
To: "Alexis Lothoré (eBPF Foundation)" <alexis.lothore@bootlin.com>,
dwarves@vger.kernel.org
Cc: Alan Maguire <alan.maguire@oracle.com>,
Arnaldo Carvalho de Melo <acme@redhat.com>,
ebpf@linuxfoundation.org,
Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
Bastien Curutchet <bastien.curutchet@bootlin.com>
Subject: Re: [PATCH] pahole: do not return an error when printing only a specific class
Date: Tue, 22 Jul 2025 16:42:03 -0700 [thread overview]
Message-ID: <e1afba7b-93f9-4ed3-9cd5-ef4ff4bebb70@linux.dev> (raw)
In-Reply-To: <20250716-lsk__abort-v1-1-586f31a9d97d@bootlin.com>
On 7/16/25 2:04 AM, Alexis Lothoré (eBPF Foundation) wrote:
> When trying to print a specific class layout with recent pahole
> versions, we get an error right after the expected class print:
>
> $ ./build/pahole -C test_bin_struct_packed -F dwarf tests/bin/test_bin
> struct test_bin_struct_packed {
> char a; /* 0 1 */
> short int b; /* 1 2 */
> int c; /* 3 4 */
> long long unsigned int d; /* 7 8 */
>
> /* size: 15, cachelines: 1, members: 4 */
> /* last cacheline: 15 bytes */
> } __attribute__((__packed__));
>
> pahole: /home/alexis/src/pahole/tests/bin/test_bin: Invalid argument
>
> This error is due to pahole_stealer returning LSK__STOP_LOADING when
> dealing with a single class and when it is done. This LSK__STOP_LOADING
> is then propagated to dwarf_loader__worker_thread and interpreted as an
> error (and turned into a DWARF_CB_ABORT). The main issue is that this
> LSK__STOP_LOADING value is sometimes generated by actual issues during
> pahole stealing, sometimes by "nominal" execution.
>
> Add a new LSK__ABORT status to distinguish between those nominal and
> faulty cases. Return an error only when pahole_stealer returns
> LSK__ABORT.
>
> Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
> ---
> See [1] for original discussions about the issue
>
> [1] https://lore.kernel.org/dwarves/DB5VWHU0N27I.3ETC4G47KB9Q@bootlin.com/
Hi Alexis, thank you for working on this.
The change looks good to me, just one comment.
> ---
> dwarf_loader.c | 6 ++++--
> dwarves.h | 1 +
> pahole.c | 21 +++++++++++----------
> 3 files changed, 16 insertions(+), 12 deletions(-)
>
> diff --git a/dwarf_loader.c b/dwarf_loader.c
> index ef00cdf308166732fc0938f2eecd56d314d3354f..4e1e19c9d828e111d78012feda4c8baa0d716378 100644
> --- a/dwarf_loader.c
> +++ b/dwarf_loader.c
> @@ -3277,6 +3277,8 @@ static int cus__steal_now(struct cus *cus, struct cu *cu, struct conf_load *conf
> break;
> case LSK__KEEPIT:
> break;
> + case LSK__ABORT:
> + break;
> }
> return lsk;
> }
> @@ -3679,7 +3681,7 @@ static void *dwarf_loader__worker_thread(void *arg)
> break;
>
> case JOB_STEAL:
> - if (cus__steal_now(dcus->cus, job->cu, dcus->conf) == LSK__STOP_LOADING)
> + if (cus__steal_now(dcus->cus, job->cu, dcus->conf) == LSK__ABORT)
> goto out_abort;
> cus_queue__inc_next_cu_id();
> /* re-enqueue JOB_DECODE so that next CU is decoded from DWARF */
> @@ -3872,7 +3874,7 @@ static int cus__merge_and_process_cu(struct cus *cus, struct conf_load *conf,
> goto out_abort;
>
> cu__finalize(cu, cus, conf);
> - if (cus__steal_now(cus, cu, conf) == LSK__STOP_LOADING)
> + if (cus__steal_now(cus, cu, conf) == LSK__ABORT)
> goto out_abort;
I think we should handle both LSK__STOP_LOADING and LSK__ABORT here,
otherwise the worker will keep loading DWARF (which is most of the
pahole's work) and passing cu-s to the stealer function.
I guess in many cases it'll complete without errors, but it's just
unnecessary work.
Maybe add a check for LSK__STOP_LOADING here with goto_ok?
>
> return 0;
> diff --git a/dwarves.h b/dwarves.h
> index 883852f4b60a36d73bce4568cbacd8ef3cff97ea..5df1cdad9be36212bd6548e86180860daffa3f63 100644
> --- a/dwarves.h
> +++ b/dwarves.h
> @@ -43,6 +43,7 @@ enum load_steal_kind {
> LSK__KEEPIT,
> LSK__DELETE,
> LSK__STOP_LOADING,
> + LSK__ABORT,
> };
>
> /*
> diff --git a/pahole.c b/pahole.c
> index 333e71ab65924d2c64771be7d40f768f02e9a0f0..66448fc430c19e5137a8467026d35d2ba3125e4c 100644
> --- a/pahole.c
> +++ b/pahole.c
> @@ -3165,13 +3165,13 @@ static enum load_steal_kind pahole_stealer__btf_encode(struct cu *cu, struct con
>
> if (!btf_encoder) {
> fprintf(stderr, "Error creating BTF encoder.\n");
> - return LSK__STOP_LOADING;
> + return LSK__ABORT;
> }
>
> err = btf_encoder__encode_cu(btf_encoder, cu, conf_load);
> if (err < 0) {
> fprintf(stderr, "Error while encoding BTF.\n");
> - return LSK__STOP_LOADING;
> + return LSK__ABORT;
> }
>
> return LSK__DELETE;
> @@ -3230,7 +3230,7 @@ static enum load_steal_kind pahole_stealer(struct cu *cu, struct conf_load *conf
> *
> * FIXME: Disabled, should use Oracle's libctf
> */
> - goto dump_and_stop;
> + goto dump_and_abort;
> }
> #endif
> if (class_name == NULL) {
> @@ -3281,7 +3281,7 @@ static enum load_steal_kind pahole_stealer(struct cu *cu, struct conf_load *conf
>
> if (prototype->nr_args != 0 && !tag__is_struct(class)) {
> fprintf(stderr, "pahole: attributes are only supported with 'class' and 'struct' types\n");
> - goto dump_and_stop;
> + goto dump_and_abort;
> }
>
> struct type *type = tag__type(class);
> @@ -3291,7 +3291,7 @@ static enum load_steal_kind pahole_stealer(struct cu *cu, struct conf_load *conf
> if (type->sizeof_member == NULL) {
> fprintf(stderr, "pahole: the sizeof member '%s' wasn't found in the '%s' type\n",
> prototype->size, prototype->name);
> - goto dump_and_stop;
> + goto dump_and_abort;
> }
> }
>
> @@ -3300,7 +3300,7 @@ static enum load_steal_kind pahole_stealer(struct cu *cu, struct conf_load *conf
> if (type->type_member == NULL) {
> fprintf(stderr, "pahole: the type member '%s' wasn't found in the '%s' type\n",
> prototype->type, prototype->name);
> - goto dump_and_stop;
> + goto dump_and_abort;
> }
> }
>
> @@ -3315,7 +3315,7 @@ static enum load_steal_kind pahole_stealer(struct cu *cu, struct conf_load *conf
> if (type->filter == NULL) {
> fprintf(stderr, "pahole: invalid filter '%s' for '%s'\n",
> prototype->filter, prototype->name);
> - goto dump_and_stop;
> + goto dump_and_abort;
> }
> }
>
> @@ -3386,15 +3386,16 @@ static enum load_steal_kind pahole_stealer(struct cu *cu, struct conf_load *conf
> /*
> * If we found all the entries in --class_name, stop
> */
> - if (list_empty(&class_names)) {
> -dump_and_stop:
> + if (list_empty(&class_names))
> ret = LSK__STOP_LOADING;
> - }
> dump_it:
> if (first_obj_only)
> ret = LSK__STOP_LOADING;
> filter_it:
> return ret;
> +dump_and_abort:
> + ret = LSK__ABORT;
> + return ret;
> }
>
> static int prototypes__add(struct list_head *prototypes, const char *entry)
>
> ---
> base-commit: 9845339bd09f9889dd741ed94f71eb92008dcdfc
> change-id: 20250716-lsk__abort-2b517860af28
>
> Best regards,
next prev parent reply other threads:[~2025-07-22 23:42 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-16 9:04 [PATCH] pahole: do not return an error when printing only a specific class Alexis Lothoré (eBPF Foundation)
2025-07-22 23:42 ` Ihor Solodrai [this message]
2025-07-23 8:39 ` Alexis Lothoré
2025-07-23 10:03 ` Alan Maguire
2025-07-23 15:37 ` Ihor Solodrai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e1afba7b-93f9-4ed3-9cd5-ef4ff4bebb70@linux.dev \
--to=ihor.solodrai@linux.dev \
--cc=acme@redhat.com \
--cc=alan.maguire@oracle.com \
--cc=alexis.lothore@bootlin.com \
--cc=bastien.curutchet@bootlin.com \
--cc=dwarves@vger.kernel.org \
--cc=ebpf@linuxfoundation.org \
--cc=thomas.petazzoni@bootlin.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.