Samba 2.2.2 problem in lib/sprintf.c
John E. Malmberg
wb8tyw at qsl.net
Tue Nov 27 04:37:03 GMT 2001
Andrew Tridgell wrote:
>>The original code has proven to be broken on several platforms, and
>>will not build. Either the compiler optimizer dies, or the resulting
>>object modules will not link.
>>
>
> the optimiser dies?!? That's a little hard to believe. Is the compiler
> on your system that broken? Link failures are also surprising.
As I stated before, the optimizer handles the snprintf() calls differently
than normal C library calls. Instead of leaving the overhead of decoding
the format string to the runtime, if possible it decodes it at compile
time. This behavior is triggered by the presence of #include <stdio.h>
header. With out both that header and the optimizer being turned on,
the compiler will treat the snprintf() in the classic C style.
This optimization technique is documented in the compiler user's guide.
It is possibly a bug in the compiler that it generates misleading error
messages when it finds that it is trying to compile a routine that a header
file indicated was a built in, and subject to optimization away.
>
>>It appears that the configure algorithm may have trouble getting the
>>appropriate #defines right.
>>
>
> no, it's that many systems have broken snprintf() implementations. The
> C99 standard specifies some very specific behaviour that Samba now
> relies on (for very good reasons). Some systems don't follow that
> standard. We replace snprintf on those systems.
>
>
>>Many systems will not allow a global procedure name conflict with one
>>that is supplied in a standard library. It produces a duplicate symbol
>>conflict at link time.
>>
>
> !?! then your linker is badly broken. Can you try the following simple
> program:
>
> #include <sys/types.h>
>
> int snprintf(char *str, size_t size, const char *format, ...)
> {
> return 0;
> }
>
> main()
> {
> return snprintf("foo", 0, 0);
> }
In this case, because the <stdio.h> file was not specified, the results
will be that you have locally overlaid the snprintf() function, and it
was not subject to compile time interpretation / optimization.
> and see if it compiles. It should on any system. It won't give the
> same answer on all systems, but it should *always* compile.
Add the #include <stdio.h> then you will start seeing differences in
compiler's behavior.
Also put the snprintf() replacement routine in a separate module.
>>If samba wants to supply it's own replacement routines for standard
>>library calls, I recommend changing the name of the routines to have
>>unique symbols like smb_snprintf() so that there is never a conflict
>>with existing symbols in a standard library.
>>
>
> we only do this when we absolutely have to. It is better to replace
> the broken function where possible.
Unless told otherwise, the default behavior of the Compaq C compiler is
to put prefixes on known library routines to prevent conflicts with user
written routines. The presence of a prototype in a standard header file
is what triggers the behavior.
To allow backwards compatability with older binaries, the presense of
the standard header can also determine that a new C89 compliant behavior
should be used, or if the older behavior should be used. So if the
configure test for c89 compatability is missing the appropriate standard
header files in the test program, it may not get the right results for
the test.
If the header file for the standard library routine is present, then the
compiler knows that the standard library version will be used. If
not, then the classic C compiler behavior will be followed.
Supplying both a standard header and a replacement function for an
external routine will cause a linker conflict.
This is standard behavior for high end compilers, and not limited to
Compaq C.
> show me the compiler output from the above test program. Then maybe we
> can work out how to fix it. If we need to use a macro we will, but I
> would like to know why. I find it hard to believe that the above
> simple program won't compile on any system that is even vaguely POSIX.
I will have to run the compiler outputs a bit later today.
An optimizing C compiler, especially on a RISC platform has intimate
knowledge of the standard library routines, and will attempt to
eliminate procedure calls where ever possible. If you are supplying
your own routines, their definition can not exist in a header file that
is #included for the module. That breaks things.
-John
wb8tyw at qsl.network
Personal Opinion Only
More information about the samba-technical
mailing list