[I apologize if this message is posted twice. I didn't
receive a copy of my
first posting, so I'm thinking it wasn't received
correctly.... or maybe I
just wasn't subscribed to the list correctly.]
Using the latest version of the P4 Perl module (3.5564) and
the 2006.1
P4 Client API, I'm seeing an odd behavior with "p4
print". I'm running
on a Windows XP system using ActiveState Perl 5.8.7 (build
815).
I built the P4 module using Microsoft Visual Studio 2003.
I'm printing a file that is stored in Perforce as text, but
when my
clientspec is set to "LineEnd: win" instead of
the default "LineEnd:
local" then the text file actually comes from the
server as binary. In
this case the results I get back from the P4::Run() function
are invalid
and I end up with a Perl warning (Attempt to free
unreferenced scalar).
I "fixed" the problem by editing
P4-3.5564/lib/perlclientuser.cc.
I changed the PerlClientUser::OutputBinary() method to
remove the
sv_2mortal() operation, so the method now just does:
results.AddOutput( newSVpv( data, length) );
I admit I'm not a Perl XS expert, but in poking around in
the code (and
reading the PerlXS docs) I guessed that the ref count for
the binary
data "string" object was part of the problem.
By not using sv_2mortal
the ref count is not decremented and, I guess, the data
object is not
cleaned up as soon as this P4::Run call returns to Perl. Of
course, I
could have just introduced a new memory leak but a
least this case
now works.
Here is a small piece of Perl code that shows the problem:
use strict;
use warnings;
use P4;
my $p4 = new P4;
$p4->DebugLevel( 3 );
$p4->Connect();
my commandOutput = $p4->Run( qw( print
//sa/ss/ctf/ctrl/export/160/161a21/announcement ) );
my $index = 0;
foreach my $item ( commandOutput )
{
print "$index : " . ( defined $item ?
$item : 'NOT DEFINED' ) . "\n";
$index++;
}
When run with an unedited P4 Perl module, here is the
output:
[P4::Run] Running a "p4 print" with 1 args
[P4::Run] Arg[0] =
//sa/ss/ctf/ctrl/export/160/161a21/announcement
[P4Result::Reset]: Discarding previous results
[PerlClientUser::OutputInfo]: Received data
[P4Result::AddOutput]:
//sa/ss/ctf/ctrl/export/160/161a21/announcement#1 - add
change 1368766
(text+S)
[PerlClientUser::OutputBinary]: Received 1722 bytes
[P4Result::AddOutput]: (perl object)
[PerlClientUser::OutputBinary]: Received 0 bytes
[P4Result::AddOutput]: (perl object)
0 : //sa/ss/ctf/ctrl/export/160/161a21/announcement#1 -
add change
1368766 (text+S)
1 : //sa/ss/ctf/ctrl/export/160/161a21/announcement#1 -
add change
1368766 (text+S)
2 : NOT DEFINED
Attempt to free unreferenced scalar: SV 0x18b1a64, Perl
interpreter:
0x350f4.
Attempt to free unreferenced scalar: SV 0x18b1ac4, Perl
interpreter:
0x350f4.
Notice how the first two array items are identical, probably
because
(I'm guessing) the 2nd item was freed too early so when my
little Perl
script prints out the array contents, that item is not
really valid.
And when run with my edited version of the module, here is
the output:
[P4::Run] Running a "p4 print" with 1 args
[P4::Run] Arg[0] =
//sa/ss/ctf/ctrl/export/160/161a21/announcement
[P4Result::Reset]: Discarding previous results
[PerlClientUser::OutputInfo]: Received data
[P4Result::AddOutput]:
//sa/ss/ctf/ctrl/export/160/161a21/announcement#1 - add
change 1368766
(text+S)
[PerlClientUser::OutputBinary]: Received 1722 bytes
[P4Result::AddOutput]: (perl object)
[PerlClientUser::OutputBinary]: Received 0 bytes
[P4Result::AddOutput]: (perl object)
0 : //sa/ss/ctf/ctrl/export/160/161a21/announcement#1 -
add change
1368766 (text+S)
1 : NI Component Test Runtime Library (NICTRL) 161a21
Export
The trunk was built on shelby.dy.natinst.com
[10.0.42.143]
which is running Windows Server 2003 Service Pack 1
(version 5.2
build 3790)
2 :
So, does this seem like a valid fix, or am I just masking
the real
problem by messing up the scalar object's ref count? Any
comments or
feedback would be greatly appreciated.
Thanks!
Mike Hall
National Instruments
mike.hall ni.com
_______________________________________________
p4perl mailing list
p4perl perforce.com
http://maillist.perforce.com/mailman/listinfo/p4perl
|