List Info

Thread: p4 print on a binary file causes problems




p4 print on a binary file causes problems
user name
2006-07-19 15:41:07
[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.hallni.com


_______________________________________________
p4perl mailing list
p4perlperforce.com

http://maillist.perforce.com/mailman/listinfo/p4perl
p4 print on a binary file causes problems
user name
2006-07-19 20:31:45
Hi Mike,

> [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.]

I can't speak for anyone else, but I only got it once 

> 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.  

That's normal - the server handles the line-feed
translation and sends
it to the client 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).

That's not good.

> 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.

I've had a quick look, and at first glance I think that
you're correct,
and your fix is right too. I'll take a deeper look tomorrow
to make sure
and to check for any similar cases.

Thanks for providing so much detail Mike!

Tony
_______________________________________________
p4perl mailing list
p4perlperforce.com

http://maillist.perforce.com/mailman/listinfo/p4perl
[1-2]

about | contact  Other archives ( Real Estate discussion Medical topics )