Bug 1297832

Summary: crash is confused by __aligned__ attribute on a member of a structure
Product: Red Hat Enterprise Linux 7 Reporter: Jerome Marchand <jmarchan>
Component: crashAssignee: Dave Anderson <anderson>
Status: CLOSED NOTABUG QA Contact: Kernel General QE <kernel-general-qe>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 7.2   
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-01-12 15:45:31 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Jerome Marchand 2016-01-12 15:00:12 UTC
Description of problem:

The use of an __aligned__ attribute on a member of a structure seems to confuse crash which shows am incorrect size for the structure.
According to gcc documentation, an aligned attribute to a member of a structure force the alignment of the member and the structure itself.

Version-Release number of selected component (if applicable):


How reproducible:
Always.

Steps to Reproduce:
Display such a structure (e.g. crypto_tfm) in crash.

Actual results:

crash> struct -xo crypto_tfm
struct crypto_tfm {
   [0x0] u32 crt_flags;
         union {
             struct ablkcipher_tfm ablkcipher;
             struct aead_tfm aead;
             struct blkcipher_tfm blkcipher;
             struct cipher_tfm cipher;
             struct hash_tfm hash;
             struct compress_tfm compress;
             struct rng_tfm rng;
   [0x8] } crt_u;
  [0x48] void (*exit)(struct crypto_tfm *);
  [0x50] struct crypto_alg *__crt_alg;
  [0x58] void *__crt_ctx[];
}
SIZE: 0x58

Analyse of the asm of some code that access __crt_ctx (the aligned member) shows that its offset is indeed 0x58. The size is therefore wrong.

Expected results:

crash shows the right size (in this case I guess 0x60).

struct crypto_tfm {
   [0x0] u32 crt_flags;
         union {
             struct ablkcipher_tfm ablkcipher;
             struct aead_tfm aead;
             struct blkcipher_tfm blkcipher;
             struct cipher_tfm cipher;
             struct hash_tfm hash;
             struct compress_tfm compress;
             struct rng_tfm rng;
   [0x8] } crt_u;
  [0x48] void (*exit)(struct crypto_tfm *);
  [0x50] struct crypto_alg *__crt_alg;
  [0x58] void *__crt_ctx[];
}
SIZE: 0x60

Additional info:

Comment 2 Dave Anderson 2016-01-12 15:20:38 UTC
Crash is simply reporting the size that the embedded gdb module returns:

crash> struct -o crypto_tfm
struct crypto_tfm {
   [0] u32 crt_flags;
       union {
           struct ablkcipher_tfm ablkcipher;
           struct aead_tfm aead;
           struct blkcipher_tfm blkcipher;
           struct cipher_tfm cipher;
           struct hash_tfm hash;
           struct compress_tfm compress;
           struct rng_tfm rng;
   [8] } crt_u;
  [72] void (*exit)(struct crypto_tfm *);
  [80] struct crypto_alg *__crt_alg;
  [88] void *__crt_ctx[];
}
SIZE: 88
crash> q


$ gdb vmlinux
GNU gdb (GDB) Fedora (7.4.50.20120120-54.fc17)
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/dumps/3.10.0-305.el7.x86_64_OOM_kill_cgroup_1257117/vmlinux...done.
(gdb) print sizeof(struct crypto_tfm)
$1 = 88
(gdb) 


I wonder if it's more to do with the fact that it's declared as an
empty array?

Comment 3 Dave Anderson 2016-01-12 15:38:29 UTC
> I wonder if it's more to do with the fact that it's declared as an
> empty array?

$ cat junk.c

#include <stdio.h>

struct simple {
	long a, b;
};

struct flexible {
	long a, b;
	void *__crt_ctx[];
};

main()
{
	printf("%d\n", sizeof(struct simple));
	printf("%d\n", sizeof(struct flexible));
}


$ cc -o junk junk.c
$ ./junk
16
16
$

Comment 4 Dave Anderson 2016-01-12 15:39:22 UTC
I'm not going to touch this...