On Sun, Mar 21, 2010 at 05:40:25AM -0300, Alberto Bertogli wrote:
> On Sat, Mar 20, 2010 at 08:37:06PM +0100, Serafeim Zanikolas wrote:
> > Hi again,
> > 
> > libfiu core dumps on kFreeBSD-{ia64,i386} when the following call is made:
> > 
> >     lock_fd = open(path, O_WRONLY|O_CREAT, 0600);
> > 
> > Here's the backtrace from a failure in asdfasdf.debian.org (GNU/kFreeBSD
> > 8.0-1-amd64):
> > 
> >     fiu-run -x ./beanstalkd -l 127.0.0.1 -p 11400 -b /tmp/bnch86651.d -s 
> > 1000 &
> >     [..]
> >     Core was generated by `beanstalkd'.
> >     Program terminated with signal 4, Illegal instruction.
> > 
> >     $ gdb beanstalkd beanstalkd.core
> >     [..]
> >     (gdb) bt
> >     #0  0x0000000800a372c0 in open (pathname=0x7fffffffdf10 
> > "/tmp/bnch86651.d/lock", flags=513) at modules/posix.custom.c:44
> >     #1  0x000000000040407a in binlog_lock () at binlog.c:691
> >     #2  0x00000000004026ac in main (argc=9, argv=0x7fffffffe4b0) at 
> > beanstalkd.c:298
> 
> Thanks for the detailed bug report.
> 
> It seems strange, because that line is at va_start(). I see nothing obviously
> wrong there (the open() call includes the mode as it should when using
> O_CREAT), so I'll install that platform and try to reproduce it.

I can't reproduce the bug on an amd64 install, but I see a compile-time
warning about it, and it makes sense.

Can you test with the attached patch?

You can also find it in the "next" branch of the repository (which is subject
to rebases), at git://blitiri.com.ar/libfiu (which can be browsed at
http://blitiri.com.ar/git/?p=libfiu;a=shortlog;h=refs/heads/next).

Thanks,
                Alberto

>From 37f6a98110e3bb59bbb4971241baa3a385c3f724 Mon Sep 17 00:00:00 2001
From: Alberto Bertogli <[email protected]>
Date: Sun, 21 Mar 2010 15:43:43 -0300
Subject: [PATCH] preload/posix: Pass an appropriate promoted type to va_arg()

va_arg() can only take a promoted type, which that means just an int in this
case.

On some platforms passing mode_t works, but on others (like Debian's kFreeBSD
amd64) causes a compile-time warning and a run-time error, as reported by
Serafeim Zanikolas on Debian bug 574752.

This patch fixes this by passing int as the argument to va_arg(), instead of
mode_t.

It also fixes the "mode" variable's type, which was int when it should have
been mode_t.

Signed-off-by: Alberto Bertogli <[email protected]>
---
 preload/posix/modules/posix.custom.c |   11 +++++++++--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/preload/posix/modules/posix.custom.c b/preload/posix/modules/posix.custom.c
index 5caff6f..1c709cd 100644
--- a/preload/posix/modules/posix.custom.c
+++ b/preload/posix/modules/posix.custom.c
@@ -37,12 +37,19 @@ int open(const char *pathname, int flags, ...)
 
 	/* Differences from the generated code begin here */
 
-	int mode;
+	mode_t mode;
 	va_list l;
 
 	if (flags & O_CREAT) {
 		va_start(l, flags);
-		mode = va_arg(l, mode_t);
+
+		/* va_arg() can only take fully promoted types, and mode_t
+		 * sometimes is smaller than an int, so we should always pass
+		 * int to it, and not mode_t. Not doing so would may result in
+		 * a compile-time warning and run-time error. We asume that it
+		 * is never bigger than an int, which holds in practise. */
+		mode = va_arg(l, int);
+
 		va_end(l);
 	} else {
 		/* set it to 0, it's ignored anyway */
-- 
1.7.0.270.g320aa

Reply via email to