Re: [PATCH 0/3] Differentiate embedded flexible arrays from flexible ones

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Arnaldo,

On Tue, Oct 08, 2024 at 04:52:06PM -0300, Arnaldo Carvalho de Melo wrote:
> From: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
> 
> Hi Willy, Gustavo,
> 
> 	Now it has even a regression test, this now have what I think is
> needed, take a look at the output of:
> 
>    pahole --with_embedded_flexible_arrays > \
> 	 http://vger.kernel.org/~acme/pahole--with_embedded_flexible_array-6.10.11-200.fc40.x86_64.c

First, thanks for this great work! Please note that above it's
"--with_embedded_flexible_array" (without the trailing 's').

I'm seeing that it seems to catch entries added for padding as well:

  struct mem_cgroup {
  ...
        long unsigned int          move_lock_flags;      /*  1480     8 */

        /* XXX 48 bytes hole, try to pack */

        /* --- cacheline 24 boundary (1536 bytes) --- */
        struct cacheline_padding   _pad1_;               /*  1536     0 */

        /* XXX last struct has a flexible array */

I think that we could avoid emitting it if the entire struct or union is
of size zero, as I don't think we'd be using variable length arrays in
a structure of a single field which is that one anyway.

I also tried to catch this case that we discussed about, which is almost
always wrong: fma at the end of a struct, followed by padding in the
container struct, suggesting that the caller meant for the fma to map
to the next field and failed. But it didn't match it when combined
with "--padding_ge 1".

  $ cat pad1.c
  struct foo {
          void *ptr;
          int number;
          char array[];
  } foo;
  
  struct bar {
          int number;
          struct foo foo;
          char storage[16];
  } bar;
  
  int main(void)
  {
          return 0;
  }

  $ gcc -g pad1.c
  $ ../pahole/build/pahole --with_embedded_flexible_array --padding_ge 1 -E ./a.out 
  $
  $ ../pahole/build/pahole --with_embedded_flexible_array -E ./a.out 
  struct bar {
          int                        number;                                               /*     0     4 */
  
          /* XXX 4 bytes hole, try to pack */
  
          struct foo {
                  void *             ptr;                                                  /*     8     8 */
                  int                number;                                               /*    16     4 */
                  char               array[];                                              /*    20     0 */
          } foo; /*     8    16 */
  
          /* XXX last struct has a flexible array, 4 bytes of padding */
  
          char                       storage[16];                                          /*    24    16 */
  
          /* size: 40, cachelines: 1, members: 3 */
          /* sum members: 36, holes: 1, sum holes: 4 */
          /* paddings: 1, sum paddings: 4 */
          /* flexible array members: end: 1 */
          /* last cacheline: 40 bytes */
  };

I think I can reliably spot it by grepping for 'flexible.*padding' but
that removes some of its beauty and efficiency :-)

Maybe it's a different case and it would need a different option, such
as --with_padded_embedded_flexible_array ?

> And go on searching for 'flexible' :-)

Regardless of the status of the points above, that's still really awesome
and an amazing time-saver! Thanks a lot!

> 	Now I'm flexibly moving to other final issues to release pahole 1.28.

Since you're speaking about final issues, I noticed this:
  - forgetting to pass -g to gcc yields:

    $ ../pahole/build/pahole --with_embedded_flexible_array -E ./a.out
    libbpf: failed to find '.BTF' ELF section in ./a.out
    pahole: file './a.out' has no supported type information.

    For me that was not clear, I thought I faced an incompatibility
    related to bpf or something, plus my working binaries don't seem
    to have such a '.BTF' section either. Maybe just asking "were debug
    symbols omitted?" would be clearer.

  - on my laptop, starting 'pahole' segfaults. I traced it to trying to
    open(NULL) after failing to find vmlinux:

    $ strace ./build/pahole
    ...
    access("/sys/kernel/btf/vmlinux", R_OK) = -1 ENOENT (No such file or directory)
    uname({sysname="Linux", nodename="wtap.local", ...}) = 0
    openat(AT_FDCWD, "/sys/kernel/notes", O_RDONLY) = 3
    read(3, "\4\0\0\0\24\0\0\0\3\0\0\0", 12) = 12
    read(3, "GNU\0", 4)                     = 4
    read(3, "\350N\202\23\31g9\302VB(\17u\251\245\"O Xq", 20) = 20
    close(3)                                = 0
    openat(AT_FDCWD, "vmlinux", O_RDONLY)   = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/boot/vmlinux", O_RDONLY) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/boot/vmlinux-6.1.91", O_RDONLY) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/usr/lib/debug/boot/vmlinux-6.1.91", O_RDONLY) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/lib/modules/6.1.91/build/vmlinux", O_RDONLY) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/usr/lib/debug/lib/modules/6.1.91/vmlinux", O_RDONLY) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, "/usr/lib/debug/boot/vmlinux-6.1.91.debug", O_RDONLY) = -1 ENOENT (No such file or directory)
    openat(AT_FDCWD, NULL, O_RDONLY)        = -1 EFAULT (Bad address)
    --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} ---
    +++ killed by SIGSEGV +++

    I've bisected it to this recent commit:

      commit c08046f98a3f84881133f9172f6bb417add61879
      Author: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
      Date:   Wed Aug 28 16:19:17 2024 -0300

          core: Add function to return the path to the running kernel vmlinux

Hoping this helps!
Willy




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux