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