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>