Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery


by Kirsle (Pilgrim)
on Jun 22, 2012 at 21:26 UTC ( #977900=perlquestion: print w/replies, xml ) Need Help??

Kirsle has asked for the wisdom of the Perl Monks concerning the following question:

For a few years I've been trying to get the Tkx module to install and work on a Linux system, using a stock vendor version of Perl (I've also tested on a perlbrew install as well) but without very much success. The best I could get would be for the test suite to pass, but "real" programs using Tkx (including "tkx-ed" that comes with the module) would fail, giving segmentation faults.

I chalked it off as being that ActiveState did something custom with their version of Perl and that the only way to get Tkx to work is to use ActivePerl.

But today I decided to take another stab at it. At first I came to the same point I've come with it before: the test suite works, but nothing else. But I decided to look into the Makefile to see why the test suite works -- because, if I ran a test manually, like perl t/LabEntry.t, it would also segfault. To make a long story short, this doesn't work:

$ perl tkx-ed
Segmentation fault (code dumped)
But this does:

$ PERL_DL_NONLAZY=1 perl tkx-ed
The Makefile sets this variable and the tests pass. Without it, you get a segfault. With this variable, tkx-ed and tkx-prove both run. Without it, segfault.

What is this variable for, and what would cause it to be required for this one module to work?

Replies are listed 'Best First'.
by Lotus1 (Vicar) on Jun 23, 2012 at 02:04 UTC

    I found this and more detail at from March 2001. DL refers to the dynamic loader.

    Setting [PERL_DL_NONLAZY] forces the loader to load up all functions at once, so that it can ensure that it really does have code for all the functions it claims to have code for; this is usually what you want to do when testing.

    Here's another interesting one from perlrun

    PERL_DL_NONLAZY Set to "1" to have Perl resolve all undefined symbols when it loads a +dynamic library. The default behaviour is to resolve symbols when the +y are used. Setting this variable is useful during testing of extensi +ons, as it ensures that you get an error on misspelled function names + even if the test suite doesn't call them.
      Thanks for the info. I found that I can do this in a Tkx script to work around the problem:

      BEGIN {
          $ENV{PERL_DL_NONLAZY} = 1;

      This enables one to just run the script as normal without setting the variable manually first. Is this variable okay to use in production code? It sounds to me like it would be analogous to "use strict", as in, it might mean a slight performance hit when starting Perl but it catches potential errors at compile time.

by davido (Cardinal) on Jun 23, 2012 at 02:10 UTC

    This is interesting:

    The PERL_DL_NONLAZY=1 mechanism was specifically designed to spot problems with unresolved symbols at _load_ time rather than leaving it till the symbol is possibly referenced later in the running code (causing a fatal error).

    From an old P5P message here:

    I can't say why it matters here, but at least that's a description of what the environment variable does.


by Anonymous Monk on Jun 23, 2012 at 07:05 UTC

    Try increasing trace level, export PERL_DL_DEBUG=9999 and say $Tkx::TRACE=64;

    Also try install Tcl::pTk and running the demo widgetTclpTk

by mje (Curate) on Jun 25, 2012 at 10:00 UTC

    My guess is that 2 libraries in your chain have the same symbol and a dlopen is called with something like LT_GROUP or LT_GLOBAL. When running with PERL_DL_NONLAZY the undefined symbol is resolved correctly but without it, the undefined symbol is resolved in another library and it probably takes different arguments. I've seen this before. It is hard to debug.

    When I first hit this it was with unixODBC and some ODBC drivers when we put together Why do I get "SQLSetConnectOption err=-2" errors in my Perl scripts.

      Hmm, kinda hard to believe, IIRC even win32 won't look for symbols in a different dll/so

      If you can trigger it, strace ought to help -- also lsof -p, or ldd /objdump

        Read dlopen man page and look at LT_GROUP, LT_GLOBAL etc. Those flags change the way symbols are resolved. As you can change the way symbols are resolved if you have 2 symbols with the same name you can pick the wrong one e.g., symbols can be resolved downwards or from the top. I've seen it happen.

        See Why do I get "SQLSetConnectOption err=-2" errors in my Perl scripts for an example.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://977900]
Approved by NetWallah
Front-paged by NetWallah
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (2)
As of 2021-09-25 04:33 GMT
Find Nodes?
    Voting Booth?

    No recent polls found