Bug 94400 - printf() breaks in simple program when libpoppler is linked to it
Summary: printf() breaks in simple program when libpoppler is linked to it
Status: RESOLVED INVALID
Alias: None
Product: poppler
Classification: Unclassified
Component: general (show other bugs)
Version: unspecified
Hardware: x86 (IA32) Windows (All)
: medium normal
Assignee: poppler-bugs
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-03-05 02:16 UTC by mathog
Modified: 2016-03-08 22:43 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments

Description mathog 2016-03-05 02:16:31 UTC
The libpoppler in devlibs61, used by Inkscape, when linked to a simple test program that does something like this:

   double val=cos(0.0);
   printf("%lf\n",val);

causes the wrong value to be emitted.  The value is set correctly to 1.0 but printf() emits 0.0.  Within inkscape it can emit some dreadful things, like strings of hundreds of digits.  

Build the exact same program, but without linking libpoppler to it, and it works correctly.

Running the test program within Dr. Memory showed problems when libpoppler was linked in, and none when it wasn't.  The build environment was Mingw on 32 bit XP.

Details of testing so far, and commands to reproduce the issue, begin at message 40 here:

   https://bugs.launchpad.net/inkscape/+bug/1538361

and in this new bug report for devlibs:

   https://bugs.launchpad.net/inkscape-devlibs/+bug/1552913
Comment 1 Jason Crain 2016-03-05 05:29:07 UTC
What I've been able to tell from compiling the test program and looking at the disassembly, linking with libpopplar will make it use a mingw printf, otherwise it uses a msvcrt printf.  It might be because poppler builds with -D__USE_MINGW_ANSI_STDIO=1.  Building your test program with that defined will make the same error, even when not linking with poppler.
Comment 2 mathog 2016-03-08 21:06:32 UTC
The problem is in mingw.  Poppler was almost entirely an innocent bystander.

Depending on who knows what variables sometimes the linker gives you a printf() from one library and other times you get the one from MSVCRT.dll.  The problem is that the latter one is not strictly compliant with any of the recent C language standards.  In particular, in the context of a printf() it considers "%lf" to be a synonym for "%LF".  Something in the problematic poppler libraries is throwing that switch, resulting in the observed bugs.  For all I know building these libraries slightly differently would eliminate whatever this mysterious something is.  It doesn't seem to be a function of the Poppler code per se. 

I also discovered a really ironic way to get the wrong printf.  

gcc -std=gnu89 -o printf_bug printf_bug.c
./printf_bug

follows the C99 standard for how %lf should work, but 

gcc -std=c99 -o printf_bug printf_bug.c
./printf_bug

does not, it apparently uses the MSVCRT.dll printf().  

In other words, specifically requesting a language standard which says what "%lf" should do in this context gives you the opposite result!

Note: mingw apparently also has issues with printf() and long doubles.  As I understand it one library expects them to be 80 bits and the other 64 bits.

Some future version of mingw may resolve these issues, all it has to do is give its printf() precedence over the one in MSVCRT.
Comment 3 mathog 2016-03-08 21:07:36 UTC
Sorry Jason, I didn't see your last comment. Yes that is it.
Comment 4 Albert Astals Cid 2016-03-08 22:25:13 UTC
No bug then, right?
Comment 5 mathog 2016-03-08 22:43:43 UTC
Not in poppler.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.