[PATCH] warning: passing argument 4 of ‘ptrace’ makes integer from pointer without a cast

Denys Vlasenko dvlasenk at redhat.com
Fri Jan 23 19:54:40 UTC 2009


On Wed, 2009-01-21 at 12:13 -0500, Michal Nowak wrote:
> Yet another clean-up patch. Compiling on i386 gave me following
> warnings:
> 
> [...]
> strace.c: In function ‘handle_stopped_tcbs’:
> strace.c:2539: warning: passing argument 4 of ‘ptrace’ makes integer from pointer without a cast
> strace.c:2566: warning: passing argument 4 of ‘ptrace’ makes integer from pointer without a cast
> [...]
> util.c: In function ‘do_ptrace’:
> util.c:260: warning: passing argument 4 of ‘ptrace’ makes integer from pointer without a cast
> util.c: In function ‘ptrace_restart’:
> util.c:282: warning: passing argument 4 of ‘ptrace’ makes integer from pointer without a cast
> [...]
> 
> The thing is that the 'Linux/Glibc at i386' prototype of ptrace() [1] is
> different from the "expected" one from '<sys/ptrace.h>' [2].
> 
> The patch now #ifdefine-s the ptrace(...) functions according to 
> architecture. #ifdefine-s were roughly taken from 'defs.h' and
> wired into the warnings-emitting code.

No, this is not acceptable, especially at every callsite.
It's dreaded ifdef forest:

+#if (defined(LINUXSPARC) || defined(LINUX_X86_64) || defined(LINUX_ARM)) && defined(__GLIBC__)
        l = ptrace(request, tcp->pid, addr, data);
+#else
+#ifdef __STDC__
+#ifdef LINUX
+       l = ptrace(request, tcp->pid, addr, (long) data);
+#else /* !LINUX */
+       l = ptrace(request, tcp->pid, addr, (int) data);
+#endif /* !LINUX */
+#else /* !__STDC__ */
+       l = ptrace();
+#endif /* !__STDC__ */
+#endif

I propose adding a macro which casts 3rd and 4th
ptrace() parameters. Something like:

#define ptrace(a,b,c,d,...) ptrace(a,b,(char*)(uintptr_t)(c),(int)(d),##__VA_ARGS__)

in defs.h. Double cast (char*)(uintptr_t) prevents warnings about widening conversion.

This will allow us to drop all casts for these parameters in all callsites.
Yes, we lose the type check protection, but for ptrace() only it's acceptable.

Testing: t.c:

#define ptrace(a,b,c,d,...) ptrace(a,b,(char*)(uintptr_t)(c),(int)(d),##__VA_ARGS__)
ptrace(a,b,c,d)
ptrace(a,b,c,d,e)
ptrace(a,b,c,d,e,f)

Result:

# gcc -E t.c
# 1 "t.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "t.c"
ptrace(a,b,(char*)(uintptr_t)(c),(int)(d))
ptrace(a,b,(char*)(uintptr_t)(c),(int)(d),e)
ptrace(a,b,(char*)(uintptr_t)(c),(int)(d),e,f)


> Anyway, I pretty wonder whether this part of the patch
> 
> [...]
> +#endif /* !LINUX */
> +#else /* !__STDC__ */
> +                               ptrace();
> +#endif /* !__STDC__ */
> `-------------------------------^^^^^^^^^
> [...]

Yes, it's wrong. You got confused by defs.h:

#ifdef __STDC__
...
#else /* !__STDC__ */
extern int ptrace();
#endif /* !__STDC__ */

In C (as opposed to C++), int func(); declaration does not mean
that function takes no parameters. That would be int func(void);

int func(); means that function takes unknown number of parameters.
--
vda






More information about the Strace-devel mailing list