Skip to contentSkip to conversation

i386: enable REGPARM by default

PATCH In review Adrian Bunk 8 participants 13 messages Jun 24, 2005 – Jun 29, 2005 Driver core

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 i386: enable REGPARM by default

This patch should _not_ go into Linus' tree.

At some time in the future, we want to unconditionally enable REGPARM on i386.

Let's give it a bit broader testing coverage among -mm users.

This patch:
- removes the dependency of REGPARM on EXPERIMENTAL
- let REGPARM default to y

This patch assumes that people who use -mm are willing to test some more experimental features.

After this patch, REGPARM is still a config option users can disable.

---

This patch was already sent on:
- 30 May 2005
- 15 May 2005

arch/i386/Kconfig renamed from arch/i386/Kconfig.old +2 -3
@@ -911,9 +911,8 @@
 	default y
 
 config REGPARM
-	bool "Use register arguments (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
-	default n
+	bool "Use register arguments"
+	default y
 	help
 	Compile the kernel with -mregparm=3. This uses a different ABI
 	and passes the first three arguments of a function call in registers.
#1 lore raw
Quoted 4 lines · Adrian Bunk

This patch:
- removes the dependency of REGPARM on EXPERIMENTAL
- let REGPARM default to y

hm, a compromise.

One other concern I have with this is that I expect -mregparm will make kgdb (and now crashdump) less useful. When incoming args are on the stack you have a good chance of being able to see what their value is by walking the stack slots.

When the incoming args are in registers I'd expect that it would be a lot harder (or impossible) to work out their value.

Have the kdump guys thought about (or encountered) this?

#2 lore raw

fre 2005-06-24 klockan 13:28 -0700 skrev Andrew Morton:

Quoted 13 lines
Quoted 4 lines · Adrian Bunk

This patch:
- removes the dependency of REGPARM on EXPERIMENTAL
- let REGPARM default to y

hm, a compromise.

One other concern I have with this is that I expect -mregparm will make kgdb (and now crashdump) less useful. When incoming args are on the stack you have a good chance of being able to see what their value is by walking the stack slots.

Quoted 4 lines

When the incoming args are in registers I'd expect that it would be a lot harder (or impossible) to work out their value.

Have the kdump guys thought about (or encountered) this?

Hmmm. I played a bit with this. Without regparm there is some argument output although not correct. For example the argument 'ptr' to b_first should have been 0xbeef. both x=0 and y=299264 are incorrect. Not sure why, have to look into that.

#0 b_second (pid=1, ptr=0xbeef, x=0, y=299264) at arch/i386/kernel/process.c:180
#1 0xc0100ce8 in b_first (pid=1, ptr=0x1) at arch/i386/kernel/process.c:188 -------------- (only the above is interesting)

#2  0xc0100d66 in cpu_idle () at arch/i386/kernel/process.c:221
#3  0xc010027b in rest_init () at init/main.c:393
#4  0xc033e838 in start_kernel () at init/main.c:534
#5  0xc0100199 in is386 () at arch/i386/kernel/head.S:327

Now with regparm. Suprisingly enough only y=0 is now errenous and the rest are correct (double-checked, have to look into this aswell).

#0 b_second (pid=1, ptr=0xbeef, x=65297, y=0) at
arch/i386/kernel/process.c:180
#1 0xc0100c87 in b_first (pid=1, ptr=0xbeef) at
arch/i386/kernel/process.c:188
-------------- (only the above is interesting)

#2  0xc0100d01 in cpu_idle () at arch/i386/kernel/process.c:221
#3  0xc010026d in rest_init () at init/main.c:393
#4  0xc03247d1 in start_kernel () at init/main.c:534
#5  0xc0100199 in is386 () at arch/i386/kernel/head.S:327

This was at first glance but is interesting.

Adrian, why do we want REGPARM on by default? Performance? I haven't seen any figures

#3 lore raw
In reply to Andrew Morton
Quoted 13 lines · Andrew Morton
Quoted 4 lines · Adrian Bunk

This patch:
- removes the dependency of REGPARM on EXPERIMENTAL
- let REGPARM default to y

hm, a compromise.

One other concern I have with this is that I expect -mregparm will make kgdb (and now crashdump) less useful. When incoming args are on the stack you have a good chance of being able to see what their value is by walking the stack slots.

Quoted 5 lines

When the incoming args are in registers I'd expect that it would be a lot harder (or impossible) to work out their value.

Have the kdump guys thought about (or encountered) this?

[copying to [email protected]]

I too played a little bit with this (gdb stack trace outputs without REGPARM and with REGPARM). Following are stack traces of both the cases.

REGPARM Disabled
----------------
(gdb) bt
#0 0xc0113d22 in crash_get_current_regs (regs=0xedf33e6c)

    at arch/i386/kernel/crash.c:102
#1  0xc0113d9d in crash_save_self (saved_regs=0xedf33e6c)
    at arch/i386/kernel/crash.c:134
#2  0xc013d19a in crash_kexec (regs=0x2) at kernel/kexec.c:1059
#3  0xc011c999 in panic (fmt=0x2 <Address 0x2 out of bounds>)
    at kernel/panic.c:86
#4  0xc014086a in func2 (a=2, b=0x2, c=100 'd') at kernel/ksysfs.c:36
#5  0xc01408a5 in func1 (a=20, b=0xc044cae8, c=100 'd') at kernel/ksysfs.c:42
#6  0xc01408f8 in stack_debug_show (subsys=0xc044cb00,
    page=0x2 <Address 0x2 out of bounds>) at kernel/ksysfs.c:59
#7  0xc0198e3f in subsys_attr_show (kobj=0xc044cb18, attr=0x2,
    page=0x2 <Address 0x2 out of bounds>) at fs/sysfs/file.c:30
#8  0xc0198ed8 in fill_read_buffer (dentry=0x1, buffer=0xee33db20)
    at fs/sysfs/file.c:86
#9  0xc0198fe7 in sysfs_read_file (file=0x1,
    buf=0x2 <Address 0x2 out of bounds>, count=2, ppos=0x2)
    at fs/sysfs/file.c:153
#10 0xc0160599 in vfs_read (file=0xef3d8880,
    buf=0x804d858 <Address 0x804d858 out of bounds>, count=4096,
    pos=0xedf33fa4) at fs/read_write.c:238
#11 0xc0160871 in sys_read (fd=2, buf=0x2 <Address 0x2 out of bounds>,
count=2)
    at fs/read_write.c:321

Here all the function arguments does not seem to be right. I introduced func1 and func2 and value of parameters is partially correct. (Right values are a=20, b=0xecab5f18,, c='d').

Time to talk to gdb folks.

With REGPARM Enabled
--------------------
(gdb) bt
#0 0xc0112a20 in crash_get_current_regs (regs=0xee661e94)

    at arch/i386/kernel/crash.c:102
#1  0xc0112a89 in crash_save_self (saved_regs=0x0)
    at arch/i386/kernel/crash.c:134

#2 0xc0138be2 in crash_kexec (regs=0x5400) at kernel/kexec.c:1059 #3 0xc011adeb in panic (fmt=0xc03b7499 "Vivek: Invoked panic\n")
at kernel/panic.c:86
#4 0xc013beab in func2 (a=-295297388, b=0x5400, c=-108 '\224')
at kernel/ksysfs.c:36
#5 0xc013bedb in func1 (a=-1069483288, b=0x14, c=-108 '\224')
at kernel/ksysfs.c:42
#6 0xc013bf36 in stack_debug_show (subsys=0xee661e94, page=0xede0f000 "")
at kernel/ksysfs.c:60
#7 0xc018d31c in subsys_attr_show (kobj=0xee661e94, attr=0x5400,

    page=0xede0f000 "") at fs/sysfs/file.c:30
#8  0xc018d38e in fill_read_buffer (dentry=0xee661e94, buffer=0xefd32360)
    at fs/sysfs/file.c:86
#9  0xc018d481 in sysfs_read_file (file=0xee0909c0,
    buf=0x804d858 <Address 0x804d858 out of bounds>, count=4096,
    ppos=0xee661e94) at fs/sysfs/file.c:153
#10 0xc0159260 in vfs_read (file=0xee0909c0,
    buf=0x804d858 <Address 0x804d858 out of bounds>, count=4096,
    pos=0xee661fa4) at fs/read_write.c:238
#11 0xc01594e9 in sys_read (fd=3999669908,
    buf=0x804d858 <Address 0x804d858 out of bounds>, count=4096)
    at fs/read_write.c:321

Here all the arguments of func1 and func2 are bad. Looks like REGPARM might worsen the output.

Will look more into this.

Thanks
Vivek

#4 lore raw
Quoted 14 lines · Vivek Goyal
Quoted 13 lines · Andrew Morton
Quoted 4 lines · Adrian Bunk

This patch:
- removes the dependency of REGPARM on EXPERIMENTAL
- let REGPARM default to y

hm, a compromise.

One other concern I have with this is that I expect -mregparm will make kgdb (and now crashdump) less useful. When incoming args are on the stack you have a good chance of being able to see what their value is by walking the stack slots.

Quoted 4 lines
Quoted 4 lines

When the incoming args are in registers I'd expect that it would be a lot harder (or impossible) to work out their value.

Have the kdump guys thought about (or encountered) this?

GDB is more than capable of handling this - if your compiler is saving arguments to the stack and dumping out useful information for the debugger about where it put them. Recent GCC versions are generally pretty good about either saving the argument or clearly telling GDB that it was not saved.

Signature · 2 lines
Daniel Jacobowitz
CodeSourcery, LLC
#5 lore raw
Quoted 18 lines · Daniel Jacobowitz
Quoted 17 lines · Vivek Goyal
Quoted 16 lines · Andrew Morton
Quoted 4 lines · Adrian Bunk

This patch:
- removes the dependency of REGPARM on EXPERIMENTAL
- let REGPARM default to y

hm, a compromise.

One other concern I have with this is that I expect -mregparm will make kgdb (and now crashdump) less useful. When incoming args are on the stack you have a good chance of being able to see what their value is by walking the stack slots.

When the incoming args are in registers I'd expect that it would be a lot harder (or impossible) to work out their value.

Quoted 8 lines
Quoted 1 line
Quoted 1 line

Have the kdump guys thought about (or encountered) this?

GDB is more than capable of handling this - if your compiler is saving arguments to the stack and dumping out useful information for the debugger about where it put them. Recent GCC versions are generally pretty good about either saving the argument or clearly telling GDB that it was not saved.

Thanks. Any idea what might be amiss with my case where I am not seeing proper function parameter values while analyzing kdump generated crash dump with gdb. I am using following gdb and gcc versions.

GNU gdb Red Hat Linux (6.1post-1.20040607.62rh)
gcc (GCC) 3.4.3 20041212 (Red Hat 3.4.3-9.EL4)

Inlined with the mail is a test patch. This patch just invokes func1() and func2() upon reading a sysfs file "debug_stack" and finally calls panic() and boots into a new kernel.

Associated stack traces retrieved from core dump file are available at following link.

http://marc.theaimsgroup.com/?l=linux-kernel&m=111988996408170&w=2

Thanks
Vivek

---

 linux-2.6.12-rc6-mm1-1M-root/kernel/ksysfs.c |   24 ++++++++++++++++++++++++
 1 files changed, 24 insertions(+)
kernel/ksysfs.c renamed from kernel/ksysfs.c~kdump-gdb-stack-debug +24 -0
diff -puN kernel/ksysfs.c~kdump-gdb-stack-debug kernel/ksysfs.c
@@ -30,6 +30,19 @@ static ssize_t hotplug_seqnum_show(struc
 KERNEL_ATTR_RO(hotplug_seqnum);
 #endif
 
+int func2(int a, int *b, char c)
+{
+        printk("a=%d, b=%p, c=%c \n", a, b, c);
+	panic("Vivek: Invoked panic\n");
+	return 0;
+}
+int func1(int a, int *b, char c)
+{
+        printk("a=%d, b=%p, c=%c\n", a, b, c);
+        func2(a, b, c);
+	return 0;
+}
+
 #ifdef CONFIG_KEXEC
 #include <asm/kexec.h>
 
@@ -38,6 +51,16 @@ static ssize_t crash_notes_show(struct s
 	return sprintf(page, "%p\n", (void *)crash_notes);
 }
 KERNEL_ATTR_RO(crash_notes);
+static ssize_t stack_debug_show(struct subsystem *subsys, char *page)
+{
+	int a=20;
+	int *b=&a;
+	char c='d';
+	printk("Vivek: value of b is %p\n", b);
+	func1(a, b, c);
+	return sprintf(page, "%s\n", "Vivek copied");
+}
+KERNEL_ATTR_RO(stack_debug);
 #endif
 
 decl_subsys(kernel, NULL, NULL);
@@ -49,6 +72,7 @@ static struct attribute * kernel_attrs[]
 #endif
 #ifdef CONFIG_KEXEC
 	&crash_notes_attr.attr,
+	&stack_debug_attr.attr,
 #endif
 	NULL
 };

_

#6 lore raw
Quoted 7 lines

Thanks. Any idea what might be amiss with my case where I am not seeing proper function parameter values while analyzing kdump generated crash dump with gdb. I am using following gdb and gcc versions.

GNU gdb Red Hat Linux (6.1post-1.20040607.62rh)
gcc (GCC) 3.4.3 20041212 (Red Hat 3.4.3-9.EL4)

Some more info. I dumped the stack contents and it seems that stack is fine and parameters are intact on stack. So now it seems to be a matter of how gdb is interpreting the stack contents. Any guess, what the problem is? Why func2() and func1() are not showing right parameter values.

Unfortunately I lost the previous dump image and vmlinux. I have taken a fresh dump and reproduced the problem again. So I am reporting all the details again.

- Test Patch
- gdb back trace
- Raw stack dump
- Relevant vmlinux objdump output.

Thanks
Vivek

Following is the test patch I applied on 2.6.12-rc6-mm1.

---

 linux-2.6.12-rc6-mm1-1M-root/kernel/ksysfs.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+)
kernel/ksysfs.c renamed from kernel/ksysfs.c~kdump-gdb-stack-debug +23 -0
diff -puN kernel/ksysfs.c~kdump-gdb-stack-debug kernel/ksysfs.c
@@ -30,6 +30,19 @@ static ssize_t hotplug_seqnum_show(struc
 KERNEL_ATTR_RO(hotplug_seqnum);
 #endif
 
+int func2(int a, int *b, char c)
+{
+	printk("a=%d, b=%p, c=%c \n", a, b, c);
+	panic("Vivek: Invoked panic\n");
+	return 0;
+}
+int func1(int a, int *b, char c)
+{
+	printk("a=%d, b=%p, c=%c\n", a, b, c);
+	func2(a, b, c);
+	return 0;
+}
+
 #ifdef CONFIG_KEXEC
 #include <asm/kexec.h>
 
@@ -38,6 +51,15 @@ static ssize_t crash_notes_show(struct s
 	return sprintf(page, "%p\n", (void *)crash_notes);
 }
 KERNEL_ATTR_RO(crash_notes);
+static ssize_t stack_debug_show(struct subsystem *subsys, char *page)
+{
+	int a=20;
+	int *b=&a;
+	char c='d';
+	func1(a, b, c);
+	return sprintf(page, "%s\n", "copied");
+}
+KERNEL_ATTR_RO(stack_debug);
 #endif
 
 decl_subsys(kernel, NULL, NULL);
@@ -49,6 +71,7 @@ static struct attribute * kernel_attrs[]
 #endif
 #ifdef CONFIG_KEXEC
 	&crash_notes_attr.attr,
+	&stack_debug_attr.attr,
 #endif
 	NULL
 };

Following is the stack trace I received from gdb when it opened kdump generated kernel dump image.

(gdb) bt
#0 0xc0113d22 in crash_get_current_regs (regs=0xec9cfe6c)

    at arch/i386/kernel/crash.c:102
#1  0xc0113d9d in crash_save_self (saved_regs=0xec9cfe6c)
    at arch/i386/kernel/crash.c:134
#2  0xc013d19a in crash_kexec (regs=0x3) at kernel/kexec.c:1059
#3  0xc011c999 in panic (fmt=0x3 <Address 0x3 out of bounds>)
    at kernel/panic.c:86
#4  0xc014086a in func2 (a=3, b=0x3, c=100 'd') at kernel/ksysfs.c:36
#5  0xc01408a5 in func1 (a=20, b=0xc044cae8, c=100 'd') at kernel/ksysfs.c:42
#6  0xc01408f8 in stack_debug_show (subsys=0xc044cb00,
    page=0x3 <Address 0x3 out of bounds>) at kernel/ksysfs.c:59
#7  0xc0198e3f in subsys_attr_show (kobj=0xc044cb18, attr=0x3,
    page=0x3 <Address 0x3 out of bounds>) at fs/sysfs/file.c:30
#8  0xc0198ed8 in fill_read_buffer (dentry=0x1, buffer=0xefd9bda0)
    at fs/sysfs/file.c:86
#9  0xc0198fe7 in sysfs_read_file (file=0x1,
    buf=0x3 <Address 0x3 out of bounds>, count=3, ppos=0x3)
    at fs/sysfs/file.c:153
#10 0xc0160599 in vfs_read (file=0xedafd560,
    buf=0x804d858 <Address 0x804d858 out of bounds>, count=4096,
    pos=0xec9cffa4) at fs/read_write.c:238
#11 0xc0160871 in sys_read (fd=3, buf=0x3 <Address 0x3 out of bounds>, count=3)
    at fs/read_write.c:321

Following is the raw stack dump. I have tried segregating/mapping calls to func1 and func2.

(gdb) info registers

eax            0x3      3
ecx            0xec9cfe6c       -325255572
edx            0x1      1
ebx            0xec9cfe6c       -325255572
esp            0xec9cfe60       0xec9cfe60
ebp            0xc044cae8       0xc044cae8
esi            0x3      3
edi            0x14     20
eip            0xc0113d22       0xc0113d22
eflags         0x46     70
cs             0x60     96
ss             0x68     104
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51

(gdb) x/100x 0xec9cfe60

0xec9cfe60:     0xc0113d9d      0xec9cfe6c      0x00000003      0xec9cfe6c
0xec9cfe70:     0xec9cfe6c      0x00000001      0x00000003      0x00000000
0xec9cfe80:     0xc044c000      0x00000003      0x00000000      0xc0113a75
0xec9cfe90:     0x00000004      0x013ef000      0x01455498      0x00000001
0xec9cfea0:     0x013ef000      0xefc948a0      0xec9cff1c      0x00000014
0xec9cfeb0:     0xc044cae8      0xc013d19a      0xefc948a0      0x00000064
0xec9cfec0:     0xc011c999      0x00000000      0xc054e140      0xc03f3d4e
0xec9cfed0:     0xec9cfee0      0x00000064      0xc014086a      0xc03f3d39
0xec9cfee0:     0x00000014
                0xec9cff1c
                0x00000064
                0xc01408a5      (Call to func2)
0xec9cfef0:     0x00000014      (parameter a)
                0xec9cff1c      (parameter b)
                0x00000064      (parameter c)
                0x00000064
0xec9cff00:     0xc044cb00   
                0xc044cb18  
                0xc04537a0 
                0xc01408f8      (Call to func1)
0xec9cff10:     0x00000014      (parameter a)
                0xec9cff1c      (parameter b)
                0x00000064      (parameter c)
                0x00000014

0xec9cff20: 0xc0198e3f 0xc044cb00 0xeccfc000 0xefd9bda0

Following is objdump output of vmlinux. (Snippet of relevant portion)

c0140836 <func2>:

c0140836:       83 ec 10                sub    $0x10,%esp
c0140839:       0f be 44 24 1c          movsbl 0x1c(%esp),%eax
c014083e:       c7 04 24 26 3d 3f c0    movl   $0xc03f3d26,(%esp)
c0140845:       89 44 24 0c             mov    %eax,0xc(%esp)
c0140849:       8b 44 24 18             mov    0x18(%esp),%eax
c014084d:       89 44 24 08             mov    %eax,0x8(%esp)
c0140851:       8b 44 24 14             mov    0x14(%esp),%eax
c0140855:       89 44 24 04             mov    %eax,0x4(%esp)
c0140859:       e8 b6 c9 fd ff          call   c011d214 <printk>
c014085e:       c7 04 24 39 3d 3f c0    movl   $0xc03f3d39,(%esp)
c0140865:       e8 c5 c0 fd ff          call   c011c92f <panic>

c014086a <func1>:

c014086a:       57                      push   %edi
c014086b:       56                      push   %esi
c014086c:       53                      push   %ebx
c014086d:       83 ec 10                sub    $0x10,%esp
c0140870:       8b 7c 24 20             mov    0x20(%esp),%edi
c0140874:       8b 74 24 24             mov    0x24(%esp),%esi
c0140878:       0f be 5c 24 28          movsbl 0x28(%esp),%ebx
c014087d:       89 5c 24 0c             mov    %ebx,0xc(%esp)
c0140881:       89 74 24 08             mov    %esi,0x8(%esp)
c0140885:       89 7c 24 04             mov    %edi,0x4(%esp)
c0140889:       c7 04 24 4f 3d 3f c0    movl   $0xc03f3d4f,(%esp)
c0140890:       e8 7f c9 fd ff          call   c011d214 <printk>
c0140895:       89 5c 24 08             mov    %ebx,0x8(%esp)
c0140899:       89 74 24 04             mov    %esi,0x4(%esp)
c014089d:       89 3c 24                mov    %edi,(%esp)
c01408a0:       e8 91 ff ff ff          call   c0140836 <func2>
c01408a5:       31 c0                   xor    %eax,%eax
c01408a7:       83 c4 10                add    $0x10,%esp
c01408aa:       5b                      pop    %ebx
c01408ab:       5e                      pop    %esi
c01408ac:       5f                      pop    %edi
c01408ad:       c3                      ret

c01408d1 <stack_debug_show>:

c01408d1:       83 ec 10                sub    $0x10,%esp
c01408d4:       8d 44 24 0c             lea    0xc(%esp),%eax
c01408d8:       c7 44 24 0c 14 00 00    movl   $0x14,0xc(%esp)
c01408df:       00
c01408e0:       c7 44 24 08 64 00 00    movl   $0x64,0x8(%esp)
c01408e7:       00
c01408e8:       89 44 24 04             mov    %eax,0x4(%esp)
c01408ec:       c7 04 24 14 00 00 00    movl   $0x14,(%esp)
c01408f3:       e8 72 ff ff ff          call   c014086a <func1>
c01408f8:       8b 44 24 18             mov    0x18(%esp),%eax
c01408fc:       c7 44 24 08 6d 3d 3f    movl   $0xc03f3d6d,0x8(%esp)
c0140903:       c0
c0140904:       c7 44 24 04 36 67 40    movl   $0xc0406736,0x4(%esp)
c014090b:       c0
c014090c:       89 04 24                mov    %eax,(%esp)
c014090f:       e8 64 94 0c 00          call   c0209d78 <sprintf>
c0140914:       83 c4 10                add    $0x10,%esp
c0140917:       c3                      ret
#7 lore raw

Date: Tue, 28 Jun 2005 16:54:12 +0530
From: Vivek Goyal <[email protected]>

Quoted 7 lines

Thanks. Any idea what might be amiss with my case where I am not seeing proper function parameter values while analyzing kdump generated crash dump with gdb. I am using following gdb and gcc versions.

GNU gdb Red Hat Linux (6.1post-1.20040607.62rh)
gcc (GCC) 3.4.3 20041212 (Red Hat 3.4.3-9.EL4)

Some more info. I dumped the stack contents and it seems that stack is fine and parameters are intact on stack. So now it seems to be a matter of how gdb is interpreting the stack contents. Any guess, what the problem is?

I'd say the problem is with a user building stuff with non-standard "optimizations", probably even stripping his executable, and expecting to be able to debug the result.

Why func2() and func1() are not showing right parameter values.

Repeating what Daniel said before, by using "regparm", function arguments are now passed in registers instead of on the stack. It's extremely unlikely that these function arguments will stay in those registers for ever, especially since you've only got a handfull of them on the i386. So eventually they will be moved to some other register or, more likely, to memory. If the compiler doesn't tell gdb about it, gdb will still think the value is in the register, and display whatever what's there now, which is likely to be the wrong value. There are two ways the compiler can tell gdb where things are:

1. By explicitly specifying the new location. Both DWARF 2 and stabs debugging formats can do this, but AFAIK, GCC won't do this if a register is spilled to the stack.

2. By specifying where registers are saved. Only DWARF 2 can do this.

We've seen cases where the information generated by GCC for 1 or 2 is either incomplete or wrong. There also have been cases where GDB didn't interpret that information correctly. And then some people tend to remove some of the debug information by stripping their code or using broken linker scripts. You'll need to find out where the problem is, but my bet is that its's a problem with GCC since you make it generate non-standard code.

Oh, by the way, don't expect gdb to be able to call "regparm" functions either.

Mark

#8 lore raw
Quoted 15 lines · Mark Kettenis

Date: Tue, 28 Jun 2005 16:54:12 +0530
From: Vivek Goyal <[email protected]>

Quoted 7 lines

Thanks. Any idea what might be amiss with my case where I am not seeing proper function parameter values while analyzing kdump generated crash dump with gdb. I am using following gdb and gcc versions.

GNU gdb Red Hat Linux (6.1post-1.20040607.62rh)
gcc (GCC) 3.4.3 20041212 (Red Hat 3.4.3-9.EL4)

Some more info. I dumped the stack contents and it seems that stack is fine and parameters are intact on stack. So now it seems to be a matter of how gdb is interpreting the stack contents. Any guess, what the problem is?

Quoted 6 lines

I'd say the problem is with a user building stuff with non-standard "optimizations", probably even stripping his executable, and expecting to be able to debug the result.

Why func2() and func1() are not showing right parameter values.

In this case I am building linux kernel with debug info (-g) and -mregparm is not specified. So parameters should be passed on stack. Following is the effective command line to build kernel/sysfs.c. I am not sure if any of the below mentioned options are going to affect the gdb results.

gcc -m32 -Wp,-MD,kernel/.ksysfs.o.d -nostdinc -isystem /usr/lib/gcc/i386-redhat-linux/3.4.3/include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fomit-frame-pointer -g -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=i686 -mtune=pentium4 -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=ksysfs -DKBUILD_MODNAME=ksysfs -c -o kernel/ksysfs.o kernel/ksysfs.c

Quoted 5 lines

Repeating what Daniel said before, by using "regparm", function arguments are now passed in registers instead of on the stack. It's extremely unlikely that these function arguments will stay in those registers for ever, especially since you've only got a handfull of them on the i386.

Sorry for the confusion. In the last mail all the results were reported with REGPARM disabled. I wanted to make sure that first normal case works fine and then discuss the REGPARM case later.

Quoted 12 lines

So eventually they will be moved to some other
register or, more likely, to memory. If the compiler doesn't tell gdb about it, gdb will still think the value is in the register, and display whatever what's there now, which is likely to be the wrong value. There are two ways the compiler can tell gdb where things are:

1. By explicitly specifying the new location. Both DWARF 2 and stabs debugging formats can do this, but AFAIK, GCC won't do this if a register is spilled to the stack.

2. By specifying where registers are saved. Only DWARF 2 can do this.

Quoted 7 lines

We've seen cases where the information generated by GCC for 1 or 2 is either incomplete or wrong. There also have been cases where GDB didn't interpret that information correctly. And then some people tend to remove some of the debug information by stripping their code or using broken linker scripts. You'll need to find out where the problem is, but my bet is that its's a problem with GCC since you make it generate non-standard code.

Ok. I will try to figure out where the problem is. Time to jump into gcc and gdb code. :-)

Thanks
Vivek

#9 lore raw
Quoted 35 lines · Mark Kettenis
Quoted 19 lines

Date: Tue, 28 Jun 2005 16:54:12 +0530
From: Vivek Goyal <[email protected]>

Quoted 1 line

Thanks. Any idea what might be amiss with my case where I am not

seeing

Quoted 1 line

proper function parameter values while analyzing kdump generated

crash

Quoted 5 lines

dump with gdb. I am using following gdb and gcc versions.

GNU gdb Red Hat Linux (6.1post-1.20040607.62rh)
gcc (GCC) 3.4.3 20041212 (Red Hat 3.4.3-9.EL4)

Some more info. I dumped the stack contents and it seems that stack
is fine
and parameters are intact on stack. So now it seems to be a matter of how gdb is interpreting the stack contents. Any guess, what the
problem is?

Quoted 6 lines

I'd say the problem is with a user building stuff with non-standard "optimizations", probably even stripping his executable, and expecting to be able to debug the result.

Why func2() and func1() are not showing right parameter values.

In this case I am building linux kernel with debug info (-g) and -mregparm is not specified. So parameters should be passed on stack. Following is the effective command line to build kernel/sysfs.c. I am not sure if any of the below mentioned options are going to affect the gdb results.

gcc -m32 -Wp,-MD,kernel/.ksysfs.o.d -nostdinc -isystem
/usr/lib/gcc/i386-redhat-linux/3.4.3/include -D__KERNEL__ -Iinclude

Review

Quoted 6 lines
(quoted diff) +0 -6
-Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing
-fno-common -ffreestanding -O2     -fomit-frame-pointer -g -pipe
-msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time
-march=i686 -mtune=pentium4 -Iinclude/asm-i386/mach-default
-Wdeclaration-after-statement     -DKBUILD_BASENAME=ksysfs
-DKBUILD_MODNAME=ksysfs -c -o kernel/ksysfs.o kernel/ksysfs.c

-O2 will have some effect. The compiler might optimize away variables (including function arguments) and doesn't always record that fact in the debug information.

But the real killer here is probably -fomit-frame-pointer. Last time I looked GCC didn't generate the correct debug information in that case. I didn't really look into this, but it seemed as if GCC blindly produces location descriptions relative to the frame pointer even though there no longer is a frame pointer. GCC 4.0 or 4.1 might have this fixed.

Quoted 10 lines
Quoted 6 lines

Repeating what Daniel said before, by using "regparm", function arguments are now passed in registers instead of on the stack. It's extremely unlikely that these function arguments will stay in those registers for ever, especially since you've only got a handfull of them on the i386.

Sorry for the confusion. In the last mail all the results were reported with REGPARM disabled. I wanted to make sure that first normal case works fine and then discuss the REGPARM case later.

If you're prepared to do some more tests, you might want to check out what happens if you leave out -O2 and -fomit-frame-pointer, and then add back only -O2

Mark

#10 lore raw
Quoted 31 lines

Review

Quoted 13 lines

In this case I am building linux kernel with debug info (-g) and -mregparm is not specified. So parameters should be passed on stack. Following is the effective command line to build kernel/sysfs.c. I am not sure if any of the below mentioned options are going to affect the gdb results.

gcc -m32 -Wp,-MD,kernel/.ksysfs.o.d -nostdinc -isystem
/usr/lib/gcc/i386-redhat-linux/3.4.3/include -D__KERNEL__ -Iinclude

(quoted diff) +0 -6
-Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing
-fno-common -ffreestanding -O2     -fomit-frame-pointer -g -pipe
-msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time
-march=i686 -mtune=pentium4 -Iinclude/asm-i386/mach-default
-Wdeclaration-after-statement     -DKBUILD_BASENAME=ksysfs
-DKBUILD_MODNAME=ksysfs -c -o kernel/ksysfs.o kernel/ksysfs.c

-O2 will have some effect. The compiler might optimize away variables (including function arguments) and doesn't always record that fact in the debug information.

But the real killer here is probably -fomit-frame-pointer. Last time I looked GCC didn't generate the correct debug information in that case. I didn't really look into this, but it seemed as if GCC blindly produces location descriptions relative to the frame pointer even though there no longer is a frame pointer. GCC 4.0 or 4.1 might have this fixed.

Quoted 7 lines
Quoted 6 lines

Repeating what Daniel said before, by using "regparm", function arguments are now passed in registers instead of on the stack. It's extremely unlikely that these function arguments will stay in those registers for ever, especially since you've only got a handfull of them on the i386.

Quoted 7 lines
Quoted 3 lines

Sorry for the confusion. In the last mail all the results were reported with REGPARM disabled. I wanted to make sure that first normal case works fine and then discuss the REGPARM case later.

If you're prepared to do some more tests, you might want to check out what happens if you leave out -O2 and -fomit-frame-pointer, and then add back only -O2

I built another kernel with -fno-omit-frame-pointer and output seems to have worsen a lot now. I am not able to build a kernel without -02. There seems to be some dependencies which I am sorting out.

With frame pointer support, following is the command line.

gcc -m32 -Wp,-MD,kernel/.ksysfs.o.d -nostdinc -isystem /usr/lib/gcc/i386-redhat-linux/3.4.3/include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -ffreestanding -O2 -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=i686 -mtune=pentium4 -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=ksysfs -DKBUILD_MODNAME=ksysfs -c -o kernel/ksysfs.o kernel/ksysfs.c

And the gdb trace has worsened. Trace is not even showing all the calls as it was showing when kernel was built with -fomit-frame-pointer.

#0 crash_get_current_regs (regs=0xec3b5e34) at arch/i386/kernel/crash.c:103 #1 0xc0114077 in crash_save_self (saved_regs=0xec3b5e34)

    at arch/i386/kernel/crash.c:134
#2  0xec3b5f04 in ?? ()
#3  0x00000014 in ?? ()
#4  0xec3b5e98 in ?? ()
#5  0xc013d7e6 in crash_kexec (regs=0x2) at kernel/kexec.c:1059
#6  0xecb29c80 in ?? ()
#7  0xecb29c80 in ?? ()
#8  0x00000000 in ?? ()

Thanks
Vivek

#11 lore raw
In reply to Adrian Bunk
Quoted 11 lines · Adrian Bunk

This patch should _not_ go into Linus' tree.

At some time in the future, we want to unconditionally enable REGPARM on i386.

Let's give it a bit broader testing coverage among -mm users.

This patch:
- removes the dependency of REGPARM on EXPERIMENTAL
- let REGPARM default to y

Quoted 6 lines

This patch assumes that people who use -mm are willing to test some more experimental features.

After this patch, REGPARM is still a config option users can disable.

Jens Axboe had hit an obscure bug with regparm just yesterday. It happened for him with gcc 3.3.5.

I have a preprocessed .c file which allows to reporduce this. For me, gcc 3.3.6 is okay. need to build 3.3.5 and test.

Meanwhile, maybe we shall prohibit regparm if gcc <=3.3.6 or 3.4? --
vda

#12 lore raw
Quoted 19 lines · Denis Vlasenko
Quoted 11 lines · Adrian Bunk

This patch should _not_ go into Linus' tree.

At some time in the future, we want to unconditionally enable REGPARM on i386.

Let's give it a bit broader testing coverage among -mm users.

This patch:
- removes the dependency of REGPARM on EXPERIMENTAL
- let REGPARM default to y

Quoted 6 lines

This patch assumes that people who use -mm are willing to test some more experimental features.

After this patch, REGPARM is still a config option users can disable.

Quoted 7 lines

Jens Axboe had hit an obscure bug with regparm just yesterday. It happened for him with gcc 3.3.5.

I have a preprocessed .c file which allows to reporduce this. For me, gcc 3.3.6 is okay. need to build 3.3.5 and test.

Meanwhile, maybe we shall prohibit regparm if gcc <=3.3.6 or 3.4?

It triggered without regparm as well, so I don't think that is to blame here.

Signature · 1 line
Jens Axboe