On Sun, Dec 03, 2006 at 02:47:33AM -0800, kyle cronan wrote:

> Hi,
> 
> I was wondering if anyone can help me figure out a problem having to
> do with accessing a scalar variable with vec().. it's illustrated by
> this little test program:
> 
> #!/usr/bin/perl
> my $foo = '';
> vec($foo, (1<<$ARGV[0])-1, 8)=1;
> 
> I can run this with the argument 27, and it works just fine.  Perl
> uses a bit more than 128 MB virtual memory before exiting, just as one
> would expect.  When I run the program with n=28 (perl 5.8.8, linux), I
> get:
> 
> Out of memory!
> 
> I have plenty of virtual memory, so there's no reason a malloc would
> fail that I can think of.  From looking at perldebguts and malloc.c in
> the source, it looks like sbrk is also used (is this just for package
> globals?), so I tried using a lexical variable and I tried getting a
> reference to an anonymous scalar with $vec = *foo{SCALAR} then
> extending $$vec, but the same thing happened.
> 
> I can create a string of the same size using something like 'chr(0) x
> (1<<$ARGV[0])', and perl will happily create a character array of
> length 2^28 (and use half a gig to do so of course ;).  But even if I
> extend the scalar to the correct length in this fashion, I still get
> fatal errors when trying to write into it with vec().
> 
> Then I thought maybe there's something like a maximum bucket size in
> the perl allocator, which vec() lvalues don't handle properly, so I
> tried compiling perl with -DNO_FANCY_MALLOC and -DPLAIN_MALLOC.  I
> still get the same error.  I don't understand why a 128 MB scalar
> string is no problem but 256 MB causes this?
> 
> I've noticed that with perl 5.8.6 I get the error "panic: realloc at
> ...".  Perhaps it's the same error condition described more
> accurately?  But according to perldiag, this is an internal error that
> indicates something tried to allocate a negative number of bytes!
> 
> Should I submit this with perlbug?

You've found a bug in the vec code.  You can probably imagine that the
code is pretty fiddly in that area.  I've had a poke around and can see
a few problems but I'm probably not going to have time to look further
this week.  So yes, a perlbug report is in order.

You are correct with your analysis of the "panic: realloc" error.  You must
have your 5.8.6 built with -DDEBUGGING, since that is when you will see this
message.  In this case, a negative number of bytes really means when the top
bit is set, so >= 2**31 will also fail this test, which is what is happening
in this case.  This is a fundamental limit (pretty much) unless you move to 64
bits.

In the report it might be helpful to note the following cases, run with
the latest development source:

 $ perl5.9.5 -e 'vec($x, (1<<31) - 1, 1) = 1'
 panic: realloc at -e line 1.

 $ perl5.9.5 -e 'vec($x, (1<<31) - 1, 2)'
 segmentation fault

 $ gdb ./perl
 (gdb) run -e 'vec($x, (1<<31) - 1, 2)'
 Starting program: /home/pjcj/g/perl/bleadperl/perl -e 'vec($x, (1<<31) - 1, 2)'

 Program received signal SIGSEGV, Segmentation fault.
 0x081aede8 in Perl_do_vecget (sv=0x82b1cc0, offset=2147483647, size=2) at 
doop.c:825
 825             retnum = (s[uoffset >> 3] >> (uoffset & 7)) & ((1 << size) - 
1);
 (gdb) where
 #0  0x081aede8 in Perl_do_vecget (sv=0x82b1cc0, offset=2147483647, size=2) at 
doop.c:825
 #1  0x08157156 in Perl_pp_vec () at pp.c:3182
 #2  0x080b6474 in Perl_runops_debug () at dump.c:1908
 #3  0x080e5980 in S_run_body (oldscope=1) at perl.c:2404
 #4  0x080e4f5c in perl_run (my_perl=0x829d008) at perl.c:2324
 #5  0x0805e951 in main (argc=3, argv=0xbffff174, env=0xbffff184) at 
perlmain.c:113
 (gdb)

It may be that the solution ends up being, at least in part, that we do
better input validation, since vec($x, (1<<36) - 1, 1) = 1; probably
isn't doing what the author expected anyway.

If you would prefer I'd be happy to send the report, but I don't want to
send a duplicate, so let me know.

-- 
Paul Johnson - [EMAIL PROTECTED]
http://www.pjcj.net

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to