[Crash-utility] HEAD'S UP -- problem with kernels built with gcc-4.6.0

Dave Anderson anderson at redhat.com
Mon May 9 14:10:37 UTC 2011



----- Original Message -----
> As a heads-up to those of you who are working with kernels
> that were compiled with the new gcc-4.6.0.
> 
> I had thought that gcc-4.6.0 was painful only as far as compiling
> the crash utility was concerned, where there were a bunch of new
> "error: variable <variable> set but not used [-Werror=unused-but-set-variable]
> messages that I fixed in crash-5.1.2 and -5.1.3. And you may be aware that
> that those for-the-most-part useless warnings recently caused an LKML shitstorm
> w/respect to building kernels.
> 
> But it's worse than that -- there is a problem with crash's embedded gdb
> determining the member offsets of the (large) pglist_data structure if
> the kernel was compiled with gcc-4.6.0. This is not specific to the
> gdb-7.0 version that is built into crash, but with all gdb
> versions as far as I can tell, certainly with gdb-7.2-48.el6
> and gdb-7.2.50.20110328-31.fc15.
> 
> The problem is most clearly seen with "struct -o pglist_data", which
> dumps the structure, showing the offset of each member.
> 
> For comparison, here is the output from a (good) 2.6.38-rc4 kernel
> that was compiled with gcc-4.5.1:
> 
> crash> help -k | grep gcc_version
> gcc_version: 4.5.1
> crash> struct -o pglist_data
> struct pglist_data {
>       [0x0] struct zone node_zones[4];
>    [0x1c00] struct zonelist node_zonelists[2];
>   [0x13e40] int nr_zones;
>   [0x13e44] spinlock_t node_size_lock;
>   [0x13e48] long unsigned int node_start_pfn;
>   [0x13e50] long unsigned int node_present_pages;
>   [0x13e58] long unsigned int node_spanned_pages;
>   [0x13e60] int node_id;
>   [0x13e68] wait_queue_head_t kswapd_wait;
>   [0x13e80] struct task_struct *kswapd;
>   [0x13e88] int kswapd_max_order;
>   [0x13e8c] enum zone_type classzone_idx;
> }
> SIZE: 0x13f00
> crash>
> 
> While here is the output from a 2.6.38.2-9.fc15 kernel that
> was compiled with gcc-4.6.0:
> 
> crash> help -k | grep gcc_version
> gcc_version: 4.6.0
> crash> struct -o pglist_data
> struct pglist_data {
>       [0x0] struct zone node_zones[4];
>    [0x1c00] struct zonelist node_zonelists[2];
>       [0x0] int nr_zones;
>       [0x0] spinlock_t node_size_lock;
>       [0x0] long unsigned int node_start_pfn;
>       [0x0] long unsigned int node_present_pages;
>       [0x0] long unsigned int node_spanned_pages;
>       [0x0] int node_id;
>       [0x0] wait_queue_head_t kswapd_wait;
>       [0x0] struct task_struct *kswapd;
>       [0x0] int kswapd_max_order;
>       [0x0] enum zone_type classzone_idx;
> }
> SIZE: 0x13f00
> crash>

... [ snip ] ...

> 
> I filed a bugzilla with gdb, although it may likely be a bug with
> the debuginfo data created by gcc-4.6.0. We'll see what happens...

As it turns out, it's due to new gcc-4.6.0 behavior that gdb has
never seen before.  This is Tom Tromey's explanation: 

------------------------------------------------------------------------

  The DWARF is definitely correct, but (IMO) odd, e.g.:

   [  4428]      member
                 name                 (strp) "nr_zones"
                 decl_file            (data1) 47
                 decl_line            (data2) 615
                 type                 (ref4) [    ed]
                 data_member_location (data4) location list [ 13e40]

  The earlier version doesn't have a location list here, just a constant:

   [  447e]      member
                 name                 (strp) "nr_zones"
                 decl_file            (data1) 47
                 decl_line            (data2) 615
                 type                 (ref4) [    c7]
                 data_member_location (sdata) 13e40

  The bug is that gdb gives up on this kind of member location.

-------------------------------------------------------------------------

I'm testing a patch from Tom, which thankfully prevents having to insert
a kludge workaround.  

Dave




More information about the Crash-utility mailing list