how can a library avoid a symbol in the main program? - Unix

This is a discussion on how can a library avoid a symbol in the main program? - Unix ; I'm maintaining a shared library which makes use of the snprintf() library call, which typically comes from the C library. But I just traced down a core dump which turns out to be caused by the fact that the program ...

+ Reply to Thread
Results 1 to 13 of 13

Thread: how can a library avoid a symbol in the main program?

  1. how can a library avoid a symbol in the main program?

    I'm maintaining a shared library which makes use of the snprintf()
    library call, which typically comes from the C library. But I just
    traced down a core dump which turns out to be caused by the fact that
    the program which linked to my library provides its own implementation
    of snprintf. Apparently the author of that program needed to work around
    some bug and came up with a version which is good enough for his usage
    but not for mine. And my code ends up using his version which dumps core.

    So how do I tell my code to ignore the snprintf symbol in a.out and look
    only in libraries?

    Thanks,
    Arch Stanton

  2. Re: how can a library avoid a symbol in the main program?

    Arch Stanton wrote:
    > I'm maintaining a shared library which makes use of the snprintf()
    > library call, which typically comes from the C library. But I just
    > traced down a core dump which turns out to be caused by the fact that
    > the program which linked to my library provides its own implementation
    > of snprintf. Apparently the author of that program needed to work around
    > some bug and came up with a version which is good enough for his usage
    > but not for mine. And my code ends up using his version which dumps core.
    >
    > So how do I tell my code to ignore the snprintf symbol in a.out and look
    > only in libraries?


    BTW, the problem is currently observed on Solaris.

  3. Re: how can a library avoid a symbol in the main program?

    On Sun, 21 Sep 2008 11:04:55 -0400, Arch Stanton wrote:
    > I'm maintaining a shared library which makes use of the snprintf()
    > library call, which typically comes from the C library. But I just
    > traced down a core dump which turns out to be caused by the fact that
    > the program which linked to my library provides its own implementation
    > of snprintf. Apparently the author of that program needed to work
    > around some bug and came up with a version which is good enough for
    > his usage but not for mine. And my code ends up using his version
    > which dumps core.


    Hit the programmer with the funny ideas with a printed copy of the C99
    standard? 500+ pages of knowledge are bound to have at least a moderate
    amount of 'impact' to the way he programs :P

    > So how do I tell my code to ignore the snprintf symbol in a.out and
    > look only in libraries?


    You can try to statically link with "some" version of snprintf(). But
    this is fraught with the same amount of peril as the current situation.
    Whenever the *system* version of snprintf() gets fixed, or the internals
    of the stdio implementation of the system are updated to fix a bug, to
    support a new way of doing their own thing, or whenever _any_ change
    (i.e a security fix) is added to the standard version of the snprintf()
    function, you lose.


  4. Re: how can a library avoid a symbol in the main program?

    Arch Stanton wrote in
    news:lsKdnQIs98W6_kvVnZ2dnUVZ_hqdnZ2d@comcast.com:

    > Arch Stanton wrote:
    >> I'm maintaining a shared library which makes use of the
    >> snprintf() library call, which typically comes from the C
    >> library. But I just traced down a core dump which turns out to
    >> be caused by the fact that the program which linked to my
    >> library provides its own implementation of snprintf. Apparently
    >> the author of that program needed to work around some bug and
    >> came up with a version which is good enough for his usage but
    >> not for mine. And my code ends up using his version which dumps
    >> core.
    >>
    >> So how do I tell my code to ignore the snprintf symbol in a.out
    >> and look only in libraries?

    >
    > BTW, the problem is currently observed on Solaris.


    You mention Solaris so this may not be applicable, but I ran into
    a similar problem at one time and resolved it in part by using the
    fact that glibc aliases snpritnf as _snprintf (IIRC), and having
    my code call _snprintf instead of snprintf.

    In my case, the problem code was in a shared library so the full
    solution was to create my own snprintf in the main program and have
    it forward all calls to _snprintf in glibc.

    Perhaps some or all of this might be useful to you.

    MV

    --
    I do not want replies; please follow-up to the group.

  5. Re: how can a library avoid a symbol in the main program?

    On 21 Sep, 16:04, Arch Stanton wrote:
    > So how do I tell my code to ignore the snprintf symbol in a.out and look
    > only in libraries?


    On linux you can use the LD_PRELOAD enviroment variable to force the
    loader to look in whatever .so file it points to first for functions
    before any other libraries. Not sure if it'll work if the function is
    actually in a.out however but its work a try if Solaris has it too.

    B2003



  6. Re: how can a library avoid a symbol in the main program?

    Arch Stanton wrote:

    > I'm maintaining a shared library which makes use of the snprintf()
    > library call, which typically comes from the C library. But I just
    > traced down a core dump which turns out to be caused by the fact that
    > the program which linked to my library provides its own implementation
    > of snprintf. Apparently the author of that program needed to work
    > around some bug and came up with a version which is good enough for
    > his usage but not for mine. And my code ends up using his version
    > which dumps core.
    >
    > So how do I tell my code to ignore the snprintf symbol in a.out and
    > look only in libraries?


    You could use vsnprintf() in your library instead, possibly using a
    simple wrapper so you don't have to change your code (too much).

    Even better, don't support such foolishness.

    --
    Huibert
    "Hey! HEY! Curious cat, here!" -- Krosp I (GG)

  7. Re: how can a library avoid a symbol in the main program?

    Martin Vuille wrote:
    > You mention Solaris so this may not be applicable, but I ran into
    > a similar problem at one time and resolved it in part by using the
    > fact that glibc aliases snpritnf as _snprintf (IIRC), and having
    > my code call _snprintf instead of snprintf.
    >
    > In my case, the problem code was in a shared library so the full
    > solution was to create my own snprintf in the main program and have
    > it forward all calls to _snprintf in glibc.


    Thanks. I ended up using a similar but different hack. The meta-problem
    is there are a lot of programs which choose to use their own versions of
    the stdio *printf functions; among open source I know of Samba, curl,
    ccache, .... Since my library already happens to require libcurl, and
    since libcurl is another of those tools with its own printf code, I just
    converted my own code to use the libcurl implementations. Not ideal, but
    I'm already implicitly dependent on them anyway and they work fine for
    my purposes.

    I believe another alternative would have been to use dlopen/dlsym to get
    the address of the "real" function out of libc.so, then #define it back
    to the standard name for the scope of my code. Something like

    libc_snprintf = dlsym(...);
    #define snprintf libc_snprintf

    But I tried the libcurl trick first and it worked.

    Arch Stanton

  8. Re: how can a library avoid a symbol in the main program?

    Giorgos Keramidas wrote:
    > On Sun, 21 Sep 2008 11:04:55 -0400, Arch Stanton wrote:
    >> I'm maintaining a shared library which makes use of the snprintf()
    >> library call, which typically comes from the C library. But I just
    >> traced down a core dump which turns out to be caused by the fact that
    >> the program which linked to my library provides its own implementation
    >> of snprintf. Apparently the author of that program needed to work
    >> around some bug and came up with a version which is good enough for
    >> his usage but not for mine. And my code ends up using his version
    >> which dumps core.

    >
    > Hit the programmer with the funny ideas with a printed copy of the C99
    > standard? 500+ pages of knowledge are bound to have at least a moderate
    > amount of 'impact' to the way he programs :P


    I'd like to blame the original programmer but I don't think it would be
    fair. Lots of programs have their own printf implementations, and there
    are a lot of open-source aftermarket printf libraries to choose from
    (http://daniel.haxx.se/projects/trio/competition.html). Commonly a piece
    of code is developed on a popular modern platform (Linux, Solaris) which
    has good C99 support, but then as it gets ported around people find that
    older and stranger platforms don't do C99 well. At that point it's too
    late to stop depending on C99 semantics so the solution is to stick in
    one of the aftermarket packages.

    Arch Stanton

  9. Re: how can a library avoid a symbol in the main program?

    On Sep 21, 11:07 am, Arch Stanton wrote:
    > Arch Stanton wrote:
    > > I'm maintaining a shared library which makes use of the snprintf()
    > > library call, which typically comes from the C library. But I just
    > > traced down a core dump which turns out to be caused by the fact that
    > > the program which linked to my library provides its own implementation
    > > of snprintf. Apparently the author of that program needed to work around
    > > some bug and came up with a version which is good enough for his usage
    > > but not for mine. And my code ends up using his version which dumps core.

    >
    > > So how do I tell my code to ignore the snprintf symbol in a.out and look
    > > only in libraries?

    >
    > BTW, the problem is currently observed on Solaris.


    On Solaris, at least, you should link your library with
    the -Bdirect option. (see the ld(1) man page).

    Roger Faulkner
    Sun Microsystems

  10. Re: how can a library avoid a symbol in the main program?


    On Sep 21 2008 18:07, Arch Stanton wrote:
    >
    > I'd like to blame the original programmer but I don't think it would be fair.
    > Lots of programs have their own printf implementations, and there are a lot of
    > open-source aftermarket printf libraries to choose from
    > (http://daniel.haxx.se/projects/trio/competition.html). Commonly a piece of
    > code is developed on a popular modern platform (Linux, Solaris) which has good
    > C99 support, but then as it gets ported around people find that older and
    > stranger platforms don't do C99 well. At that point it's too late to stop
    > depending on C99 semantics so the solution is to stick in one of the
    > aftermarket packages.


    libc printf or self-provided, it SHOULD NOT crash under any circumstances,
    except perhaps when you pass it bad pointers, overrun a buffer (sprintf, don't
    we have snprintf?) or use humonguous sizes (%.100000s) that cause a buffer
    overflow somewhere.

  11. Re: how can a library avoid a symbol in the main program?

    On Sep 24, 10:51 am, Arch Stanton wrote:
    ....
    > > On Solaris, at least, you should link your library with
    > > the -Bdirect option. (see the ld(1) man page).

    >
    > This solution sounded good enough that I decided to experiment with it.
    > I backed out my workaround and linked with -Bdirect. Still broken. The
    > man page says I should use -z defs with -Bdirect so I added that and
    > fixed the resulting broken references. Still the same problem. What have
    > I missed? This seems like a much more systemic solution than my hack so
    > I'd like to get it working.


    That should have worked. You must have a bug somewhere.

    Answer these:

    What system are you on? (Solaris what?)
    What is your exact link line? (cc ... -Bdirect ...)
    You have a core file. Show the output of 'pstack core'.

    Roger Faulkner
    Sun Microsystems

  12. Re: how can a library avoid a symbol in the main program?

    roger.faulkner@sun.com wrote:
    > Answer these:


    Thanks for taking an interest.

    > What system are you on? (Solaris what?)


    Solaris 9 Sparc, not particularly up-to-date patches. gcc 3.4.5

    > What is your exact link line? (cc ... -Bdirect ...)


    gcc -o .SunOS_sparc/libao.so -gstabs+ -W -Wall -Wcast-align -Wshadow
    -Wpointer-arith -D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE
    -I. -I../../ops/include -fpic -shared -nodefaultlibs -Bdirect -z defs -z
    interpose -z combreloc -z ignore -z lazyload libunix.c
    -L../../ops/SunOS_sparc/lib -Wl,-Bstatic -lkaz -lcurl -lpcre -lcdb -lz
    -ltrio -Wl,-Bdynamic -lgcc -lsocket -lnsl -lm -ldl -lc

    > You have a core file. Show the output of 'pstack core'.


    ff0b44b8 strlen (ffbfe388, 900, ff20e137, ffbfe2cc, 1, 8000) + 1c
    00016d48 snprintf (ffbfe388, 900, ff20e120, 58, ff20c328, 2b630) + 1c
    ff1a10ac pa_toCSVString (2c860, ffbfe388, 900, 0, 81010100, 2c060) + 114
    ff195378 ca_write (2c7a0, d4, 31ee0, 32460, ff3c42d4, ff32a9bc) + d4
    ff1a8a54 _audit_flush (ff20eba0, 0, ff3ee230, 32460, ff3c6364, 0) + ac
    ff1b1700 fork_wrapper (ff20eba0, ff11a968, 0, 0, ff1b16e4, ff32bf00) + 1c
    ff1ab8a4 fork (2b700, 14, 17dfd, 4, 2c120, 10) + 1f8
    00014148 execute (2c120, 2ca40, 2ca78, 2ba28, 2ba28, 17610) + 4
    00013074 main (2ba40, 2, 17800, 29000, ffbff020, 29000) + abc

    I'm no expert but from the addresses it certainly looks as though
    snprintf is in the same module as 'main' and very far away from the
    libc.so addresses like fork and strlen.

    Arch Stanton

  13. Re: how can a library avoid a symbol in the main program?

    Arch Stanton wrote:
    >> What is your exact link line? (cc ... -Bdirect ...)


    In case it matters, I should add that this library is inserted via
    LD_PRELOAD, not at link time. I'm linking the *library* with -Bdirect; I
    do not link the executable at all (or even have source).

    Arch Stanton

+ Reply to Thread