B::Lint does not detect undefined subs

  • Thread starter Alexander Frink
  • Start date
A

Alexander Frink

Hi!

I tried to use lint to detect undefined subroutines in a Perl script, but
recent 5.8 versions seem to fail.

With Perl 5.6.1 on Linux, everything still works as expected:

$ perl -MO=Lint,all -e 'foo();'
Undefined subroutine foo called at -e line 1
-e syntax OK

But with 5.8.8 for Win32, 5.8.5 for Linux and 5.8.2 for AIX, the undefined
sub is not detected:

$ perl -MO=Lint,all -e 'foo();'
-e syntax OK

One difference is that the 5.6.1 version is single-threaded, whereas all
other versions to which I have access are multi-threaded. The B::Lint man
page says "This module doesn't work correctly on thread-enabled perls."

Is there a way to force Perl to single-threaded mode without recompiling?
Or is this simply a bug?

Regards,

Alex
 
U

Uri Guttman

AF> I tried to use lint to detect undefined subroutines in a Perl script, but
AF> recent 5.8 versions seem to fail.

AF> With Perl 5.6.1 on Linux, everything still works as expected:

AF> $ perl -MO=Lint,all -e 'foo();'
AF> Undefined subroutine foo called at -e line 1
AF> -e syntax OK

that is a runtime error and not likely found by Lint (i don't know that
module).

AF> But with 5.8.8 for Win32, 5.8.5 for Linux and 5.8.2 for AIX, the undefined
AF> sub is not detected:

AF> $ perl -MO=Lint,all -e 'foo();'
AF> -e syntax OK

that never RAN the code so no runtime error happens.

AF> One difference is that the 5.6.1 version is single-threaded, whereas all
AF> other versions to which I have access are multi-threaded. The B::Lint man
AF> page says "This module doesn't work correctly on thread-enabled perls."

AF> Is there a way to force Perl to single-threaded mode without recompiling?
AF> Or is this simply a bug?

i doubt it is something to do with threading. lint can't detect (all)
undefined subs since subs can be loaded and created at runtime. lint
type programs do surface analysis on the code and runtime issues like
missing subs are not part of their scope. so my guess is that lint fixed
a 'bug' in the newer version by not allowing the code to be actually
run. lint is like perl's -c option in that they don't intend to run the
code itself, just compile and check it for syntax or errors that lint
can find in the source code.

uri
 
A

Alexander Frink

AF> $ perl -MO=Lint,all -e 'foo();'
AF> Undefined subroutine foo called at -e line 1
AF> -e syntax OK

that is a runtime error and not likely found by Lint (i don't know that
module).

B::Lint is part of Perl's standard library. As you can see, Perl 5.6.1
found that runtime error. But 5.8.x fail.
that never RAN the code so no runtime error happens.

That's the purpose of Lint: find possible runtime errors without actually
running the program, even more than with -c, -w or -W. False alarms are
expected. The following program

eval '$a=5;';
print $a;

when run with -c or -w, gives a warning

Name "main::a" used only once: possible typo at xxx.pl line n.

although everything is fine at run time.
i doubt it is something to do with threading. lint can't detect (all)
undefined subs since subs can be loaded and created at runtime. lint

I know that it is possible to define functions at run time, e.g. with
eval, and there may be good reasons to do so, but the programs I want to
check should explicitly avoid such things. A function which cannot be
resolved at compile time is considered an error (e.g. due to a typo).

And according to the documentation, B::Lint is supposed to find exactly
this with the option 'undefined-subs' (and I am fine with the
restrictions):
This option warns whenever an undefined subroutine
is invoked. This option will only catch explic­
itly invoked subroutines such as "foo()" and not
indirect invocations such as "&$subref()" or
"$obj->meth()". Note that some programs or modules
delay definition of subs until runtime by means of
the AUTOLOAD mechanism.

Regards,

Alex
 
B

Ben Morrow

Quoth Alexander Frink said:
Hi!

I tried to use lint to detect undefined subroutines in a Perl script, but
recent 5.8 versions seem to fail.

With Perl 5.6.1 on Linux, everything still works as expected:

$ perl -MO=Lint,all -e 'foo();'
Undefined subroutine foo called at -e line 1
-e syntax OK

But with 5.8.8 for Win32, 5.8.5 for Linux and 5.8.2 for AIX, the undefined
sub is not detected:

$ perl -MO=Lint,all -e 'foo();'
-e syntax OK

One difference is that the 5.6.1 version is single-threaded, whereas all
other versions to which I have access are multi-threaded. The B::Lint man
page says "This module doesn't work correctly on thread-enabled perls."

~% perl -v

This is perl, v5.8.8 built for i686-linux

Copyright 1987-2006, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.

~% perl -MB::Lint -le'print $B::Lint::VERSION'
1.03
~% perl -MO=Lint,all -e'foo()'
Undefined subroutine foo called at -e line 1
-e syntax OK
~%
Is there a way to force Perl to single-threaded mode without recompiling?
Or is this simply a bug?

No, I don't believe there is.

Ben
 
A

Alexander Frink

One difference is that the 5.6.1 version is single-threaded, whereas all
other versions to which I have access are multi-threaded. The B::Lint man
page says "This module doesn't work correctly on thread-enabled perls."

Meanwhile I have compiled Perl 5.9.3 with and without thread support. The
version without thread support detects the undefined sub, the one with
threads does not.

Can anyone shed some light on the reasons behind?

And still the question: can I force Perl in unthreaded mode (because I
have to use the packaged, precompiled Perl on the target platform)?

Regards,

Alex
 
X

xhoster

Alexander Frink said:
And still the question: can I force Perl in unthreaded mode (because I
have to use the packaged, precompiled Perl on the target platform)?

No. C preprocessor/compiler directives like #ifdef USE_ITHREADS are
sprinkled throughout the perl source code. There is no runtime switch that
can circumvent the effects that these have.

Xho
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top