Re: va_copy() problem
On Wed, Nov 28, 2007 at 09:44:28AM +0100, Simon 'corecode' Schubert wrote: Johannes Hofmann wrote: Sepherosa Ziehau [EMAIL PROTECTED] wrote: Could you try compiling your program with -fno-builtin-vsnprintf? This makes no difference here, also it does not matter whether I compile the program with gcc34 or gcc41. Did this ever get resolved? No, I just switched to a gcc34-built system. But I can easily reproduce the problem by LD_PRELOADing a gcc4 built libc. Johannes
Re: va_copy() problem
Johannes Hofmann wrote: Sepherosa Ziehau [EMAIL PROTECTED] wrote: Could you try compiling your program with -fno-builtin-vsnprintf? This makes no difference here, also it does not matter whether I compile the program with gcc34 or gcc41. Did this ever get resolved? cheers simon -- Serve - BSD +++ RENT this banner advert +++ASCII Ribbon /\ Work - Mac +++ space for low €€€ NOW!1 +++ Campaign \ / Party Enjoy Relax | http://dragonflybsd.org Against HTML \ Dude 2c 2 the max ! http://golden-apple.biz Mail + News / \
Re: va_copy() problem
On Nov 28, 2007 4:44 PM, Simon 'corecode' Schubert [EMAIL PROTECTED] wrote: Johannes Hofmann wrote: Sepherosa Ziehau [EMAIL PROTECTED] wrote: Could you try compiling your program with -fno-builtin-vsnprintf? This makes no difference here, also it does not matter whether I compile the program with gcc34 or gcc41. Did this ever get resolved? Nope, I think. However, does Johannes's test result mean our vsnprintf() is as broken as gcc4's builtin? Best Regards, sephe -- Live Free or Die
Re: va_copy() problem
Sepherosa Ziehau [EMAIL PROTECTED] wrote: Could you try compiling your program with -fno-builtin-vsnprintf? This makes no difference here, also it does not matter whether I compile the program with gcc34 or gcc41. Best Regards, Johannes Best Regards, sephe
Re: va_copy() problem
On Mon, Nov 12, 2007 at 08:53:46PM +, Johannes Hofmann wrote: Joerg Sonnenberger [EMAIL PROTECTED] wrote: On Mon, Nov 12, 2007 at 06:58:30PM +, Johannes Hofmann wrote: va_copy(va1, va); n = vsnprintf(s-str + s-len, s-size - s-len, format, va); va_end(va1); va - va1 in the call to vsnprintf. Also consider using vasprintf. Ooops, you are right of course. But unfortunately it still crashes badly... Works fine after the change on both NetBSD current and DragonFly 1.8. Joerg
Re: va_copy() problem
Joerg Sonnenberger [EMAIL PROTECTED] wrote: On Mon, Nov 12, 2007 at 08:53:46PM +, Johannes Hofmann wrote: Joerg Sonnenberger [EMAIL PROTECTED] wrote: On Mon, Nov 12, 2007 at 06:58:30PM +, Johannes Hofmann wrote: va_copy(va1, va); n = vsnprintf(s-str + s-len, s-size - s-len, format, va); va_end(va1); va - va1 in the call to vsnprintf. Also consider using vasprintf. Ooops, you are right of course. But unfortunately it still crashes badly... Works fine after the change on both NetBSD current and DragonFly 1.8. Thanks for testing this. Just tried it on my system booted from yesterdays LATEST-Devel snapshot and it works there too. I'm now checking my system. Perhaps some stale header files or weird kernel option... Johannes Joerg
Re: va_copy() problem
Johannes Hofmann [EMAIL PROTECTED] wrote: Joerg Sonnenberger [EMAIL PROTECTED] wrote: On Mon, Nov 12, 2007 at 08:53:46PM +, Johannes Hofmann wrote: Joerg Sonnenberger [EMAIL PROTECTED] wrote: On Mon, Nov 12, 2007 at 06:58:30PM +, Johannes Hofmann wrote: va_copy(va1, va); n = vsnprintf(s-str + s-len, s-size - s-len, format, va); va_end(va1); va - va1 in the call to vsnprintf. Also consider using vasprintf. Ooops, you are right of course. But unfortunately it still crashes badly... Works fine after the change on both NetBSD current and DragonFly 1.8. Thanks for testing this. Just tried it on my system booted from yesterdays LATEST-Devel snapshot and it works there too. I'm now checking my system. Perhaps some stale header files or weird kernel option... Ufff, I think I've found the problem. If libc is compiled with gcc41 it does not work. If I compile it with gcc34 it works fine. The snapshots on chlamydia are compiled with gcc34, that's why it worked there. Can someone please confirm that it does not work with a gcc41-compiled libc? Note, that you need to fix the typo spotted by Joerg! Johannes
Re: va_copy() problem
On Tue, Nov 13, 2007 at 06:41:03PM +, Johannes Hofmann wrote: Ufff, I think I've found the problem. If libc is compiled with gcc41 it does not work. If I compile it with gcc34 it works fine. The snapshots on chlamydia are compiled with gcc34, that's why it worked there. Can someone please confirm that it does not work with a gcc41-compiled libc? Confirmed. I also found that if you raise the second argument to string_resize() to 10 in main() and it seems to stop crashing. So it seems that the difference is how vsnprintf() behave when it's passed a buffer smaller than needed? gdb shows that vsnprintf() trashes *s when it's passed 1 as the size argument in such a case. Cheers.
Re: va_copy() problem
On 13 Nov 2007 18:41:03 GMT, Johannes Hofmann [EMAIL PROTECTED] wrote: Johannes Hofmann [EMAIL PROTECTED] wrote: Joerg Sonnenberger [EMAIL PROTECTED] wrote: On Mon, Nov 12, 2007 at 08:53:46PM +, Johannes Hofmann wrote: Joerg Sonnenberger [EMAIL PROTECTED] wrote: On Mon, Nov 12, 2007 at 06:58:30PM +, Johannes Hofmann wrote: va_copy(va1, va); n = vsnprintf(s-str + s-len, s-size - s-len, format, va); va_end(va1); va - va1 in the call to vsnprintf. Also consider using vasprintf. Ooops, you are right of course. But unfortunately it still crashes badly... Works fine after the change on both NetBSD current and DragonFly 1.8. Thanks for testing this. Just tried it on my system booted from yesterdays LATEST-Devel snapshot and it works there too. I'm now checking my system. Perhaps some stale header files or weird kernel option... Ufff, I think I've found the problem. If libc is compiled with gcc41 it does not work. If I compile it with gcc34 it works fine. The snapshots on chlamydia are compiled with gcc34, that's why it worked there. Can someone please confirm that it does not work with a gcc41-compiled libc? Could you try compiling your program with -fno-builtin-vsnprintf? Best Regards, sephe Note, that you need to fix the typo spotted by Joerg! Johannes -- Live Free or Die
va_copy() problem
Hello, I see crashes with a string handling library on DragonFly. The problem can be reduced to the test program below. It crashes on DragonFly when compiled with gcc -O2 -o foo foo.c. Without -O2 it runs fine. No problems on Linux with or without -O2. Can anyone spot the problem? I think its related to the use of va_copy(). Thanks, Johannes #include stdio.h #include string.h #include stdlib.h #include stdarg.h struct string { char *str; int size; int len; }; void string_resize(struct string *s, int n) { if (n 0 n s-size) { if (!s-str) { s-str = malloc(n); s-str[0] = '\0'; } else { s-str = realloc(s-str, n); } s-size = n; } } void string_printfa(struct string *s, char *format, ...) { va_list va, va1; int n; va_start(va, format); for (;;) { va_copy(va1, va); n = vsnprintf(s-str + s-len, s-size - s-len, format, va); va_end(va1); if (n s-size - s-len) { s-len += n; break; } string_resize(s, s-len + n + 1); } va_end(va); } int main(int argc, char **argv) { struct string s = {NULL, 0, 0}; string_resize(s, 1); string_printfa(s, %s %s , foo, bar); string_printfa(s, %s %s , foo, bar); printf(%s\n, s.str); return 0; }
gcc update (was: Re: va_copy() problem)
Johannes Hofmann wrote: Hello, I see crashes with a string handling library on DragonFly. The problem can be reduced to the test program below. It crashes on DragonFly when compiled with gcc -O2 -o foo foo.c. Without -O2 it runs fine. No problems on Linux with or without -O2. Can anyone spot the problem? I think its related to the use of va_copy(). No, the problem is that gcc uses %ebx after a function call, which it is not allowed to do: void string_printfa(struct string *s, char *format, ...) { 8048682: 55 push %ebp 8048683: 89 e5 mov%esp,%ebp 8048685: 56 push %esi 8048686: 53 push %ebx 8048687: 83 ec 10sub$0x10,%esp 804868a: 8b 5d 08mov0x8(%ebp),%ebx loads ebx 804868d: 8b 75 0cmov0xc(%ebp),%esi va_list va, va1; int n; va_start(va, format); 8048690: 8d 45 10lea0x10(%ebp),%eax 8048693: 89 45 f4mov%eax,0xfff4(%ebp) for (;;) { va_copy(va1, va); 8048696: 8b 45 f4mov0xfff4(%ebp),%eax 8048699: 89 45 f0mov%eax,0xfff0(%ebp) n = vsnprintf(s-str + s-len, s-size - s-len, format, va1); 804869c: 8b 53 08mov0x8(%ebx),%edx ^^^ uses ebx 804869f: 50 push %eax 80486a0: 56 push %esi 80486a1: 8b 43 04mov0x4(%ebx),%eax 80486a4: 29 d0 sub%edx,%eax 80486a6: 50 push %eax 80486a7: 03 13 add(%ebx),%edx 80486a9: 52 push %edx 80486aa: e8 01 fe ff ff call 80484b0 [EMAIL PROTECTED] call 80486af: 89 c1 mov%eax,%ecx if (n s-size - s-len) { 80486b1: 8b 53 08mov0x8(%ebx),%edx continues using ebx. WRONG. 80486b4: 8b 43 04mov0x4(%ebx),%eax 80486b7: 29 d0 sub%edx,%eax 80486b9: 83 c4 10add$0x10,%esp 80486bc: 39 c1 cmp%eax,%ecx 80486be: 7d 0d jge80486cd string_printfa+0x4b However, gcc34 also has the same bug, so I am at loss here. Or does the ABI dictate that %ebx needs to be restored? Seems that linux/glibc doesn't clobber ebx. cheers simon signature.asc Description: OpenPGP digital signature
Re: va_copy() problem
On Mon, Nov 12, 2007 at 06:58:30PM +, Johannes Hofmann wrote: va_copy(va1, va); n = vsnprintf(s-str + s-len, s-size - s-len, format, va); va_end(va1); va - va1 in the call to vsnprintf. Also consider using vasprintf. Joerg
Re: gcc update (was: Re: va_copy() problem)
On Mon, Nov 12, 2007 at 09:27:17PM +0100, Simon 'corecode' Schubert wrote: No, the problem is that gcc uses %ebx after a function call, which it is not allowed to do: It is allowed to. From the i386 ABI: If necessary, a function saves the values of %edi, %esi, and %ebx in the positions shown and restores their values before returning to the caller. Joerg
Re: va_copy() problem
Joerg Sonnenberger [EMAIL PROTECTED] wrote: On Mon, Nov 12, 2007 at 06:58:30PM +, Johannes Hofmann wrote: va_copy(va1, va); n = vsnprintf(s-str + s-len, s-size - s-len, format, va); va_end(va1); va - va1 in the call to vsnprintf. Also consider using vasprintf. Ooops, you are right of course. But unfortunately it still crashes badly... -stack-protector -fno-stack-protector does not help either. Johannes Joerg