This example shows a problem with Win32::GUI::UnHook()
method.
The UnHook call appears to be the cause of error messages:
Attempt to free unreferenced scalar: SV 0x1a5519c, Perl
interpreter: 0x15d40a4 at unhookBug.pl line 40.
From perldiag:
Attempt to free unreferenced scalar:
(W internal) Perl went to decrement the reference count
of a
scalar to see if it would go to 0, and discovered that
it had
already gone to 0 earlier, and should have been freed,
and in
fact, probably was freed. This could indicate that
SvREFCNT_dec() was called too many times, or that
SvREFCNT_inc() was called too few times, or that the SV
was mortalized when it shouldn't have been, or that memory
has been corrupted.
Workaround:
It is possible to turn off internal warnings (that are
on by
default) by setting no warnings (internal);
I'm certainly no XS expert, but it looks like it's
possible to get
SvREFCNT_dec(*removedvalue) called twice in UnHook().
Is this the problem?
use strict;
use warnings;
#Turning off internal warnings removes the messages
#no warnings qw(internal);
use Win32::GUI 1.0;
my $WM_MOUSEMOVE = 512;
my $mw = new Win32::GUI::Window (
-size => [200,200],
);
$mw->Hook($WM_MOUSEMOVE, \&handler)
or die "Failed to add Hook";
$mw->UnHook($WM_MOUSEMOVE, \&handler)
or die "Failed to remove hook";
exit(0);
Perl Script showing Unhook() problem
Logged In: YES
user_id=674651
I see this problem on both these platforms:
Win2k(SP4) ActiveState Perl 811 (5.6.8) Win32::GUI 1.0
Win98 ActiveState Perl 811 (5.6.8) Win32::GUI 1.0
Reportd from others suggest the problem is not repeatable
with perl 5.6.1
I withdraw the comment about SvREFCNT_dec(*removedvalue)
called twice. I've re-read the code, and *removedvalue is
set differently in the 2 places it is called.
Logged In: YES
user_id=674651
It turns out this is a perl 5.6 vs. perl 5.8 issue.
av_delete in perl 5.8 mortalises the returned sv (the SV
being deleted), efectively decrementing its reference count.
This does not happen in perl 5.6, and so the is a reference
count discrepancy.
The easiest solution is to set the flags field of the
av_delete call to G_DISCARD: the behaviour is the same in
both cases with the deleted SV having its reference count
decremented, so we don't need to do it in our XS code. This
probably won't work with earlier perl code.
Logged In: YES
user_id=674651
Fix is in CVS, and should make it into the next formal release.