jjore's Journal http://use.perl.org/~jjore/journal/ jjore's use Perl Journal en-us use Perl; is Copyright 1998-2006, Chris Nandor. Stories, comments, journals, and other submissions posted on use Perl; are Copyright their respective owners. 2012-01-25T02:12:16+00:00 pudge pudge@perl.org Technology hourly 1 1970-01-01T00:00+00:00 jjore's Journal http://use.perl.org/images/topics/useperl.gif http://use.perl.org/~jjore/journal/ The mod_perl debugger you've always wanted http://use.perl.org/~jjore/journal/40458?from=rss <p>"The mod_perl debugger you've always wanted" is on my new blog at: <a href="http://bit.ly/agzWSU">http://bit.ly/agzWSU</a></p> jjore 2010-07-22T17:53:07+00:00 journal Unicode in Perl, FTW (&#1071; &#1086;&#1095;&#1077;&#1085;&#1100; &#1088;&#1072; http://use.perl.org/~jjore/journal/40438?from=rss <p>Hi,<br>This blog post is actually at <a href="http://blogs.perl.org/users/josh_ben_jore/2010/07/unicode-in-perl-ftw.html">http://blogs.perl.org/users/josh_ben_jore/2010/07/unicode-in-perl-ftw.html</a>.</p> jjore 2010-07-07T06:01:11+00:00 journal Under the covers of perldoc http://use.perl.org/~jjore/journal/40437?from=rss <p>Hi, I posted to my new blog at blogs.perl.org:</p><p><a href="http://blogs.perl.org/users/josh_ben_jore/2010/07/under-the-covers-of-perldoc.html">http://blogs.perl.org/users/josh_ben_jore/2010/07/under-the-covers-of-perldoc.h<nobr>t<wbr></nobr> ml</a></p> jjore 2010-07-07T05:44:28+00:00 journal JVM's -XX:-DontCompileHugeMethods &amp; dynamic languages http://use.perl.org/~jjore/journal/40367?from=rss <p>In <a href="http://nerds-central.blogspot.com/2009/09/tuning-jvm-for-unusual-uses-have-some.html">http://nerds-central.blogspot.com/2009/09/tuning-jvm-for-unusual-uses-have-some<nobr>.<wbr></nobr> html</a> which I just picked out of reddit.com's front page I notice there's an ordinary 8K bytecode size limit for JVM heuristics.</p><p>Allegedly adding -XX:-DontCompileHugeMethods to the command line eliminates this limit.</p><p>In "current" versions of JVM which don't have the very new invokedynamic bytecode operation and languages implemented on top of the JVM like JRuby, I assume their implementation does all the dynamism as ordinary code. I assume then this means the bytecode sizes are artificially inflated and then possibly just missing out on this nice optimization.</p><p>Allegedly, this is one of those heuristics that moved Java from the "slow" category to "faster than C++".</p><p>Last year I found that MRI Ruby-1.9 and JRuby were equivalently fast as Perl 5 but now I wonder if the JRuby implementation I was using was missing out and possibly could go even *faster*.</p><p>FWIW, MRI Ruby-1.8 is 1/10 the speed of Perl 5.</p> jjore 2010-05-26T22:02:34+00:00 journal Stop the debugger when a test fails http://use.perl.org/~jjore/journal/40350?from=rss <p>I was debugging some test failures earlier this morning but they were in the middle of a long test script. I thought it'd be nice if I could step through the test with the debugger and just stop whenever a test failed.</p><p>Here's the result. A test failure immediately followed by being in the debugger:</p><blockquote><div><p> <tt>not ok 236<br>14:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return $result;<br>&nbsp; DB&lt;1&gt;</tt></p></div> </blockquote><p>and then I could ask for the stack trace which is nice:</p><blockquote><div><p> <tt>&nbsp; DB&lt;1&gt; T<br>. = main::ok(undef) called from file `t/02_methods.t' line 796<br>. = main::check_tar_extract(ref(Archive::Tar), ref(ARRAY)) called from file `t/02_methods.t' line 507</tt></p></div> </blockquote><p>I wrote the below snippet to automatically stop the debugger whenever something like ok() failed. Currently you can just drop this right after your "use Test::More" statement. I think possibly this kind of idea should be packaged in a no-muss CPAN module or perhaps directly right into Test::More.</p><blockquote><div><p> <tt># Wrap Test::More functions with debugger breakpoints<br>BEGIN {<br>&nbsp; &nbsp; use B;<br> &nbsp; <br>&nbsp; &nbsp; # Enumerate over all symbols in the main:: symbol table.<br>&nbsp; &nbsp; SYMBOL:<br>&nbsp; &nbsp; for my $symbol ( sort keys %main:: ) {<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; # Choose only things that are functions.<br>&nbsp; &nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; no strict 'refs';<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; next SYMBOL if ! defined &amp;$symbol;<br>&nbsp; &nbsp; &nbsp; &nbsp; }<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; # Get a reference to the function.<br>&nbsp; &nbsp; &nbsp; &nbsp; my $code = do {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; no strict 'refs';<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \&amp;$symbol;<br>&nbsp; &nbsp; &nbsp; &nbsp; };<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; # Get a B::CV object so I can get at meta-data about the<br>&nbsp; &nbsp; &nbsp; &nbsp; # function.<br>&nbsp; &nbsp; &nbsp; &nbsp; my $cv&nbsp; &nbsp;= B::svref_2object( $code );<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; # Get the path to the compilation file. Will often be a path like<br>&nbsp; &nbsp; &nbsp; &nbsp; # '/usr/share/perl/5.10/Test/More.pm'.<br>&nbsp; &nbsp; &nbsp; &nbsp; #<br>&nbsp; &nbsp; &nbsp; &nbsp; # To visually inspect other meta-data possibly available about this function:<br>&nbsp; &nbsp; &nbsp; &nbsp; #<br>&nbsp; &nbsp; &nbsp; &nbsp; #&nbsp; &nbsp; &nbsp;use Devel::Peek;<br>&nbsp; &nbsp; &nbsp; &nbsp; #&nbsp; &nbsp; &nbsp;Dump( $code );<br>&nbsp; &nbsp; &nbsp; &nbsp; #<br>&nbsp; &nbsp; &nbsp; &nbsp; my $src_file = $cv-&gt;FILE;<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; # Select only functions coming from files named like<br>&nbsp; &nbsp; &nbsp; &nbsp; #<nobr> <wbr></nobr>.../Test/More.pm.<br>&nbsp; &nbsp; &nbsp; &nbsp; next SYMBOL if $src_file !~ m{/Test/More\.pm$};<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; # Propagate the old function's prototype to the new function.<br>&nbsp; &nbsp; &nbsp; &nbsp; my $prototype = prototype $code;<br>&nbsp; &nbsp; &nbsp; &nbsp; my $new_prototype =<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defined $prototype<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? "($prototype)"<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : '';<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; # Generate the new function and replace the old function. The new function<br>&nbsp; &nbsp; &nbsp; &nbsp; # has access to the original via the closed-over $old variable.<br>&nbsp; &nbsp; &nbsp; &nbsp; my $src = qq{<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; no warnings 'redefine';<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sub $symbol $new_prototype {<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Call the original function and get the test pass/fail.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; my \$result = \$code-&gt;( \@_ );<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Debugger single-stepping mode if the test failed.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ( ! \$result ) {<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \$DB::single = 1;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Return the test/failure.<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return \$result;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Compilation of the new function succeeded?<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1;<br>&nbsp; &nbsp; &nbsp; &nbsp; };<br>&nbsp; &nbsp; &nbsp; &nbsp; eval $src<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; or die $@;<br>&nbsp; &nbsp; }<br>}</tt></p></div> </blockquote> jjore 2010-05-09T17:43:40+00:00 journal Attaching to a process and calling a kernel function http://use.perl.org/~jjore/journal/40088?from=rss <p>I figured out last night that I could use allocate memory within another process for the purposes of using more complicated APIs. In the below example, I attached to one of my shells and queried the groups out of it.</p><p>In this snippet, the target shell tells me its process id is 40728.</p><blockquote><div><p> <tt>Last login: Fri Jan&nbsp; 8 16:51:00 on ttys000<br>w3m211a:~ jjore$ echo $$<br>40728</tt></p></div> </blockquote><p>I'm calling the (int)getgroups( int, int* ) kernel function. I start by getting the size of an integer because I'm going to allocate some multiple of this.</p><blockquote><div><p> <tt>w3m211a:~ jjore$ gdb -p 40728<br> &nbsp; <br>(gdb) print sizeof(int)<br>$1 = 4</tt></p></div> </blockquote><p>Call (int)getgroups(int,int*) once to get the number of groups I'm a member of.</p><blockquote><div><p> <tt>(gdb) print (int)getgroups(0,0)<br>$2 = 16</tt></p></div> </blockquote><p>Allocate 64 bytes of memory to hold my groups[16] array.</p><blockquote><div><p> <tt>(gdb) print (void*)malloc(64)<br>$3 = (void *) 0x10010fca0</tt></p></div> </blockquote><p>Call (int)getgroups(int,int*) again but this time the kernel will write to my memory with the group ids.</p><blockquote><div><p> <tt>(gdb) print (int)getgroups($2,$3)<br>$4 = 16</tt></p></div> </blockquote><p>Print the 16 decimal numbers out of memory</p><blockquote><div><p> <tt>(gdb) x/16d $3<br>0x10010fca0:&nbsp; &nbsp; 2042662593&nbsp; &nbsp; 401&nbsp; &nbsp; 1612991420&nbsp; &nbsp; 1178352327<br>0x10010fcb0:&nbsp; &nbsp; 102&nbsp; &nbsp; 800006232&nbsp; &nbsp; 204&nbsp; &nbsp; 100<br>0x10010fcc0:&nbsp; &nbsp; 98&nbsp; &nbsp; 81&nbsp; &nbsp; 80&nbsp; &nbsp; 79<br>0x10010fcd0:&nbsp; &nbsp; 62&nbsp; &nbsp; 12&nbsp; &nbsp; 155049148&nbsp; &nbsp; 2133303823</tt></p></div> </blockquote><p>Clean up</p><blockquote><div><p> <tt>(gdb) print (void)free($3)<br>$5 = void</tt></p></div> </blockquote> jjore 2010-01-09T01:30:33+00:00 journal Unicode URLs, wtf? http://use.perl.org/~jjore/journal/40081?from=rss <p>Hey internet, &#x2838;&#x2819;&#x2831; &#x281d;&#x2809;&#x2801;&#x2808; &#x2805;&#x281d;&#x2801;&#x2815;&#x2815;&#x2809;&#x2803; &#x281d;&#x2806;&#x280f;&#x280d;&#x281e;?</p><p>A year or more ago I was fixing work's web site to handle Unicode as entered by users into fields. We don't use CGI.pm because....? Well ok, we just don't. It also doesn't handle Unicode properly either. Or at least almost no version. Huh.</p><p>If a user types "Coat&#x131;cook" you'll probably get the dotless "i" character as either %C4%B1 or %u131 but CGI.pm as supplied by perl almost most of the time won't do something reasonable.</p><ul><li>not ok 5.11.3 CGI-3.48</li><li>not ok 5.10.1 CGI-3.43</li><li>ok 5.10.0 CGI-3.29</li><li>not ok 5.8.9 CGI-3.42</li><li>not ok 5.6.2 CGI-2.752</li></ul><p>Wut?</p><blockquote><div><p> <tt>for v in 5.11.3 5.10.1 5.10.0 5.8.9 5.6.2;do<br>&nbsp;<nobr> <wbr></nobr>/opt/perl-$v-64-thr-dbg/bin/perl\<br>&nbsp; &nbsp; -le '<br>&nbsp; &nbsp; &nbsp; use CGI;<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; my $input&nbsp; = "a=%u2021";<br>&nbsp; &nbsp; &nbsp; my $expect = "\x{2021}";<br>&nbsp; &nbsp; &nbsp; my $got = CGI-&gt;new( $input )-&gt;param( "a" );<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; print $expect eq $got<br>&nbsp; &nbsp; &nbsp; &nbsp; ? "ok $] $CGI::VERSION"<br>&nbsp; &nbsp; &nbsp; &nbsp; : "not ok $] $CGI::VERSION"<br>&nbsp; &nbsp; ';<br>done</tt></p></div> </blockquote> jjore 2010-01-07T05:43:29+00:00 journal Decoding multiple encoded utf-8 in perl or ruby http://use.perl.org/~jjore/journal/40080?from=rss <p>I'd recently encountered some data that had been re-encoded five times. Ugh. The key was to guess that if a character 0xC0-0xFF is followed by 0x80-xBF, it's likely that the bytes are actually utf-8. What follows is a function which guessed a reasonable way to deal with the data and turn it into the right utf-8.</p><blockquote><div><p> <tt>use Test::More tests =&gt; 1;<br>use Encode ();<br> &nbsp; <br>my $bad = "\xc3\x83\xc2\x83\xc3\x82\xc2\x83\xc3\x83\xc2\x82\xc3\x82\xc2\x83\xc3\x83\xc2\x<nobr>8<wbr></nobr> 3\xc3\x82\xc2\x82\xc3\x83\xc2\x82\xc3\x82\xc2\xa9";<br>my $good = "\xe9";<br>is( multiple_decode( $bad ), $good );<br> &nbsp; <br>sub multiple_decode {<br>&nbsp; my ( $str ) = @_;<br> &nbsp; <br>&nbsp; Encode::_utf8_on( $str );<br>&nbsp; while ( $str =~<nobr> <wbr></nobr>/[\xc0-\xff][\x80-\xbf]/ ) {<br>&nbsp; &nbsp; utf8::downgrade( $str );<br>&nbsp; &nbsp; Encode::_utf8_on( $str );<br>&nbsp; }<br> &nbsp; <br>&nbsp; return $str;<br>}</tt></p></div> </blockquote><p>I tried doing this in Ruby because I actually needed this for an EventMachine (<a href="http://rubyeventmachine.com/">http://rubyeventmachine.com/</a>) server but never quite got it working. Iconv seemed to want to be strict about rejecting the originally ostensibly invalid input.</p><blockquote><div><p> <tt># Iconv::IllegalSequence: "\303\203\302\203\303\202\302\203\303\203\302\202\303\202\302\203"...<br> &nbsp; <br>require 'test/unit'<br>require 'iconv'<br> &nbsp; <br>class MDecode &lt; Test::Unit::TestCase<br>&nbsp; def test_multiple_decode<br>&nbsp; &nbsp; conv = Iconv.new( 'UTF-8', 'ASCII' )<br> &nbsp; <br>&nbsp; &nbsp; bad = "\xc3\x83\xc2\x83\xc3\x82\xc2\x83\xc3\x83\xc2\x82\xc3\x82\xc2\x83\xc3\x83\xc2\x<nobr>8<wbr></nobr> 3\xc3\x82\xc2\x82\xc3\x83\xc2\x82\xc3\x82\xc2\xa9"<br>&nbsp; &nbsp; good = "\xe9"<br> &nbsp; <br>&nbsp; &nbsp; assert_equal( good, conv.multiple_decode( bad ) )<br>&nbsp; end<br>end<br> &nbsp; <br>class Iconv<br>&nbsp; def multiple_decode( str )<br>&nbsp; &nbsp; while str =~<nobr> <wbr></nobr>/[\xc0-\xff][\x80-\xbf]/<br>&nbsp; &nbsp; &nbsp; str = iconv( str )<br>&nbsp; &nbsp; end<br> &nbsp; <br>&nbsp; &nbsp; return str<br>&nbsp; end<br>end</tt></p></div> </blockquote> jjore 2010-01-07T03:57:25+00:00 journal Building a lot of perl today... http://use.perl.org/~jjore/journal/40057?from=rss <blockquote><div><p> <tt>#!/bin/bash<br> &nbsp; <br>set -x<br>set -e<br>perl="$HOME/src/perl"<br> &nbsp; <br>function build-it () {<br>&nbsp; bversion=$1<br>&nbsp; shift 1<br> &nbsp; <br>&nbsp; dir=/opt/$bversion<br>&nbsp; tar=/opt/$bversion.tar.bz2<br> &nbsp; <br>&nbsp; if [[ ! -e $tar ]]; then<br>&nbsp; &nbsp; echo "Clobbering $dir"<br> &nbsp; <br>&nbsp; &nbsp; rm -rf $dir<br>&nbsp; &nbsp; mkdir $dir<br> &nbsp; <br>&nbsp; &nbsp; cd $HOME/src/perl<br>&nbsp; &nbsp; echo "Configure "$(date) &gt; $dir/stamp.log<br>&nbsp; &nbsp;<nobr> <wbr></nobr>./Configure -des -Dcc='ccache gcc' -Dprefix=$dir $* 2&gt;&amp;1 | tee $dir/config.log<br>&nbsp; &nbsp; echo "make "$(date) &gt;&gt; $dir/stamp.log<br>&nbsp; &nbsp; make 2&gt;&amp;1 | tee $dir/make.log<br>&nbsp; &nbsp; echo "make test "$(date) &gt;&gt; $dir/stamp.log<br>&nbsp; &nbsp; make test 2&gt;&amp;1 | tee $dir/test.log<br>&nbsp; &nbsp; echo "make install "$(date) &gt;&gt; $dir/stamp.log<br>&nbsp; &nbsp; make install 2&gt;&amp;1 | tee $dir/install.log<br>&nbsp; &nbsp; echo "End "$(date) &gt;&gt; $dir/stamp.log<br>&nbsp; &nbsp; chown -R jbenjore $dir/<br> &nbsp; <br>&nbsp; &nbsp; cd<nobr> <wbr></nobr>/<br>&nbsp; &nbsp; tar cjf $tar $dir<br> &nbsp; <br>&nbsp; &nbsp; cd $HOME/src/perl<br>&nbsp; &nbsp; git clean -xdf<br>&nbsp; &nbsp; git reset --hard<br>&nbsp; fi<br>}<br> &nbsp; <br>git clean -xdf<br>git reset --hard<br> &nbsp; <br>for tag in\<br>&nbsp; &nbsp; v5.11.3\<br>&nbsp; &nbsp; perl-5.10.1 perl-5.10.1\<br>&nbsp; &nbsp; perl-5.8.9 perl-5.8.8 perl-5.8.7 perl-5.8.6 perl-5.8.5 perl-5.8.4 perl-5.8.3 perl-5.8.2 perl-5.8.2 perl-5.8.1 perl-5.8.0<br>&nbsp; do<br>&nbsp; git checkout $tag<br> &nbsp; <br>&nbsp; build-it $tag-64-dbg&nbsp; &nbsp; &nbsp; -DDEBUGGING -Duse64bitint<br>&nbsp; build-it $tag-thr-dbg&nbsp; &nbsp; &nbsp;-DDEBUGGING -Dusethreads<br>&nbsp; build-it $tag-64-thr-dbg&nbsp; -DDEBUGGING -Duse64bitint -Dusethreads<br>&nbsp; build-it $tag-dbg&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-DDEBUGGING<br>&nbsp; build-it $tag&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-DDEBUGGING=-g<br>done<br> &nbsp; <br>for tag in\<br>&nbsp; &nbsp; perl-5.6.2 perl-5.005_04<br>&nbsp; do<br>&nbsp; git checkout $tag<br> &nbsp; <br>&nbsp; build-it $tag-64-dbg&nbsp; &nbsp; &nbsp; -DDEBUGGING -Duse64bitint<br>&nbsp; build-it $tag-thr-dbg&nbsp; &nbsp; &nbsp;-DDEBUGGING -Dusethreads<br>&nbsp; build-it $tag-64-thr-dbg&nbsp; -DDEBUGGING -Duse64bitint -Dusethreads<br>&nbsp; build-it $tag-dbg&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-DDEBUGGING<br>&nbsp; build-it $tag&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;-g<br>done</tt></p></div> </blockquote> jjore 2009-12-29T21:49:08+00:00 journal Bugging myself http://use.perl.org/~jjore/journal/39984?from=rss <p>I've been seriously neglecting my CPAN code. It's been pretty overwhelming having too many modules up there and no time to really get into anything. I figured it was worth at least an hour and a half's time to read the CPAN tester reports.</p><p>I just filed 34 bugs based purely on CPAN testers output. Bleagh.<nobr> <wbr></nobr>:-(</p><p>Acme-Anything</p><ul><li>FIXED: #52481: Makefile.PL isn't valid perl 5.005 <a href="https://rt.cpan.org/Ticket/Display.html?id=52481">https://rt.cpan.org/Ticket/Display.html?id=52481</a></li></ul><p>Acme-Nothing</p><ul><li>FIXED: #52482: Makefile.PL doesn't declare 5.008 as mininum perl version <a href="https://rt.cpan.org/Ticket/Display.html?id=52482">https://rt.cpan.org/Ticket/Display.html?id=52482</a></li></ul><p>Alien-Judy</p><ul><li>FIXED: #52483: Build fails when prefix isn't absolute <a href="https://rt.cpan.org/Ticket/Display.html?id=52483">https://rt.cpan.org/Ticket/Display.html?id=52483</a></li><li>#52484: Mysterious hanging build <a href="https://rt.cpan.org/Ticket/Display.html?id=52484">https://rt.cpan.org/Ticket/Display.html?id=52484</a></li><li>FIXED: #52485: Requires sh implicitly <a href="https://rt.cpan.org/Ticket/Display.html?id=52485">https://rt.cpan.org/Ticket/Display.html?id=52485</a></li></ul><p>App-Perldoc-Search</p><ul><li>#52486: Basic search failing for some users <a href="https://rt.cpan.org/Ticket/Display.html?id=52486">https://rt.cpan.org/Ticket/Display.html?id=52486</a></li></ul><p>B-Deobfuscate</p><ul><li>#52487: Redundant nextstate <a href="https://rt.cpan.org/Ticket/Display.html?id=52487">https://rt.cpan.org/Ticket/Display.html?id=52487</a></li><li>#52488: Illegal seek <a href="https://rt.cpan.org/Ticket/Display.html?id=52488">https://rt.cpan.org/Ticket/Display.html?id=52488</a></li><li>#52489: B::Concise: Can't use an undefined value as a SCALAR reference <a href="https://rt.cpan.org/Ticket/Display.html?id=52489">https://rt.cpan.org/Ticket/Display.html?id=52489</a></li></ul><p>B-Generate</p><ul><li>#52490: XS_B__SVOP_sv: invalid lvalue in assignment <a href="https://rt.cpan.org/Ticket/Display.html?id=52490">https://rt.cpan.org/Ticket/Display.html?id=52490</a></li></ul><p>B-Lint</p><ul><li>#52492: Makefile.PL doesn't declare minimum version <a href="https://rt.cpan.org/Ticket/Display.html?id=52492">https://rt.cpan.org/Ticket/Display.html?id=52492</a></li><li>#52493: Can't detect $&amp; usage <a href="https://rt.cpan.org/Ticket/Display.html?id=52493">https://rt.cpan.org/Ticket/Display.html?id=52493</a></li><li>#52495: Too-old version of B? <a href="https://rt.cpan.org/Ticket/Display.html?id=52495">https://rt.cpan.org/Ticket/Display.html?id=52495</a></li><li>#52496: Tests finding flaws in test harness <a href="https://rt.cpan.org/Ticket/Display.html?id=52496">https://rt.cpan.org/Ticket/Display.html?id=52496</a></li><li>#52498: Can't call method "name" on an undefined value <a href="https://rt.cpan.org/Ticket/Display.html?id=52498">https://rt.cpan.org/Ticket/Display.html?id=52498</a></li></ul><p>B-Utils</p><ul><li>FIXED: #52491: Depends on cc <a href="https://rt.cpan.org/Ticket/Display.html?id=52491">https://rt.cpan.org/Ticket/Display.html?id=52491</a></li></ul><p>Devel-Dt</p><ul><li>FIXED: #52499: Makefile.PL doesn't declare minimum version <a href="https://rt.cpan.org/Ticket/Display.html?id=52499">https://rt.cpan.org/Ticket/Display.html?id=52499</a></li></ul><p>Devel-OptreeDiff</p><ul><li>#52500: Tests too static <a href="https://rt.cpan.org/Ticket/Display.html?id=52500">https://rt.cpan.org/Ticket/Display.html?id=52500</a></li></ul><p>Devel-StackBlech</p><ul><li>#52501: Mininum version is 5.9.x, not declared <a href="https://rt.cpan.org/Ticket/Display.html?id=52501">https://rt.cpan.org/Ticket/Display.html?id=52501</a></li><li>#52502: structure has no member named `next_op' <a href="https://rt.cpan.org/Ticket/Display.html?id=52502">https://rt.cpan.org/Ticket/Display.html?id=52502</a></li></ul><p>ESPPlus-Storage</p><ul><li>#52504: Makefile.PL doesn't declare minimum version <a href="https://rt.cpan.org/Ticket/Display.html?id=52504">https://rt.cpan.org/Ticket/Display.html?id=52504</a></li><li>#52505: Can't use an undefined value as filehandle reference <a href="https://rt.cpan.org/Ticket/Display.html?id=52505">https://rt.cpan.org/Ticket/Display.html?id=52505</a></li></ul><p>Enbugger</p><ul><li>#52503: Can't get terminal size <a href="https://rt.cpan.org/Ticket/Display.html?id=52503">https://rt.cpan.org/Ticket/Display.html?id=52503</a></li></ul><p>Geo-TigerLine-Abbreviations</p><ul><li>#52506: Missing Cache::Cache dependency <a href="https://rt.cpan.org/Ticket/Display.html?id=52506">https://rt.cpan.org/Ticket/Display.html?id=52506</a></li></ul><p>Judy</p><ul><li>#52507: error: Judy.h: No such file or directory <a href="https://rt.cpan.org/Ticket/Display.html?id=52507">https://rt.cpan.org/Ticket/Display.html?id=52507</a></li><li>#52508: undefined symbol: JudyLPrevEmpty <a href="https://rt.cpan.org/Ticket/Display.html?id=52508">https://rt.cpan.org/Ticket/Display.html?id=52508</a></li><li>#52509: Symbol not found: _Judy1ByCount <a href="https://rt.cpan.org/Ticket/Display.html?id=52509">https://rt.cpan.org/Ticket/Display.html?id=52509</a></li><li>#52510: Fetch Word_t test fails <a href="https://rt.cpan.org/Ticket/Display.html?id=52510">https://rt.cpan.org/Ticket/Display.html?id=52510</a></li></ul><p>Regexp-NamedCaptures</p><ul><li>#52513: Makefile.PL fails to prevent perl-5.9+ from using this <a href="https://rt.cpan.org/Ticket/Display.html?id=52513">https://rt.cpan.org/Ticket/Display.html?id=52513</a></li></ul><p>Runops-Trace</p><ul><li>#52514: t/03even fails "sometimes" <a href="https://rt.cpan.org/Ticket/Display.html?id=52514">https://rt.cpan.org/Ticket/Display.html?id=52514</a></li></ul><p>Term-HiliteDiff</p><ul><li>#52515: Tests completely broken <a href="https://rt.cpan.org/Ticket/Display.html?id=52515">https://rt.cpan.org/Ticket/Display.html?id=52515</a></li></ul><p>UNIVERSAL-ref</p><ul><li>#52516: Makefile.PL doesn't declare minimum version <a href="https://rt.cpan.org/Ticket/Display.html?id=52516">https://rt.cpan.org/Ticket/Display.html?id=52516</a></li></ul><p>overload-eval</p><ul><li>#52511: Test fails <a href="https://rt.cpan.org/Ticket/Display.html?id=52511">https://rt.cpan.org/Ticket/Display.html?id=52511</a></li></ul><p>perl-lint-mode</p><ul><li>#52512: Signature is invalid <a href="https://rt.cpan.org/Ticket/Display.html?id=52512">https://rt.cpan.org/Ticket/Display.html?id=52512</a></li></ul> jjore 2009-12-06T23:11:05+00:00 journal Measuring copy-on-write on Linux http://use.perl.org/~jjore/journal/39724?from=rss <p><a href="http://perlmonks.org/?node=Corion">http://perlmonks.org/?node=Corion</a> asked about measuring memory allocation in IRC but I was reminded of something I've poked at recently which is measuring how much memory is copy-on-write shared between forked mod_perl processes. Thus far, when on Linux the only answer I know of is to use the exmap kernel module. The main page is <a href="http://www.berthels.co.uk/exmap/">http://www.berthels.co.uk/exmap/</a> but Dave Olszewski wrote some bug fixes for it at <a href="http://github.com/cxreg/exmap">http://github.com/cxreg/exmap</a>. exmap uses a kernel module to add a new<nobr> <wbr></nobr>/proc/exmap file. To read physical page stats, write the PID to this file, then read the results. The exmap distribution comes with a C++ and perl GTK program to interpret the kernel data. Below is what I know of the format for the kernel data.</p><p>To use:</p><blockquote><div><p> <tt>$ echo $pid &gt;<nobr> <wbr></nobr>/proc/exmap<br>$ cat<nobr> <wbr></nobr>/proc/exmap<br>VMA 400000 87<br>1 0 1c6e7<br>1 0 1c6e8<br>1 0 1d328<br>...</tt></p></div> </blockquote><blockquote><div><p> <tt>$ grep 400000<nobr> <wbr></nobr>/proc/$pid/maps<br>00400000-00457000 r-xp 00000000 08:01 722755<nobr> <wbr></nobr>/usr/bin/screen</tt></p></div> </blockquote><p>The sections provided by<nobr> <wbr></nobr>/proc/exmap correspond to each of the chunks in<nobr> <wbr></nobr>/proc/$pid/maps. Each line then details a page, whether it is swapped, and whether it is writable.</p><blockquote><div><p> <tt>(<br>&nbsp; &nbsp; VMA $address $page_count<br>&nbsp; &nbsp; ( $resident $writable $page_id )+<br>)+</tt></p></div> </blockquote><p>Anyway, just thought I'd share. If you know a better trick, I'd love to hear of it. When I next get around to looking at the mod_perl in question I'll likely actually try to use this but for now this is just a tool I think I plan to use but haven't done serious work with yet.</p> jjore 2009-10-06T18:06:05+00:00 journal Migrate from use.perl to ...? http://use.perl.org/~jjore/journal/39705?from=rss <p>I want to migrate from use.perl to someplace nicer. Where should I go? Is there a blog migration protocol so RSS gets some kind of automatic redirect? People seem to find my blog through use.perl - how do I get into the appropriate aggregators?</p> jjore 2009-10-02T16:40:45+00:00 journal use Modern::Perl? http://use.perl.org/~jjore/journal/39699?from=rss <p>I'm tired of writing a long stanza to declare "yes, I'm going to write an ordinary perl program."</p><blockquote><div><p> <tt>use strict;<br>use warnings;<br>use feature ':5.10';</tt></p></div> </blockquote><p>I'm going to go use chromatic's Modern::Perl and see how it feels.</p><blockquote><div><p> <tt>use Modern::Perl;</tt></p></div> </blockquote> jjore 2009-09-30T17:50:53+00:00 journal Grumble, mutter, Padre's dependencies, Grr, Mutter http://use.perl.org/~jjore/journal/39644?from=rss <p>I saw the screen shots of Padre 0.46 in <a href="http://ahmadzawawi.blogspot.com/2009/09/whats-new-in-padre-046.html">http://ahmadzawawi.blogspot.com/2009/09/whats-new-in-padre-046.html</a> and thought I'd try it myself. I've got a non-threaded perl but potentially <a href="http://search.cpan.org/dist/forks">http://search.cpan.org/dist/forks</a> will let me run without it. I've just spent the last hour trying to get <a href="http://search.cpan.org/Wx">http://search.cpan.org/Wx</a> and its dependencies installed. Mostly its just oddness like a default in wxWidgets to demand OpenGL. Now I'm just hanging out in Wx's build:</p><blockquote><div><p><nobr> <wbr></nobr><tt>/opt/perl-5.10.0/bin/perl<nobr> <wbr></nobr>/opt/perl-5.10.0/lib/5.10.0/ExtUtils/xsubpp&nbsp; -noprototypes -nolinenumbers&nbsp; -typemap<nobr> <wbr></nobr>/opt/perl-5.10.0/lib/5.10.0/ExtUtils/typemap -typemap<nobr> <wbr></nobr>../../typemap -typemap typemap&nbsp; RichText.xs &gt; RichText.xsc &amp;&amp; mv RichText.xsc RichText.c<br>Cannot open 'xspp -t typemap.xsp -t<nobr> <wbr></nobr>../../typemap.xsp XS/RichTextCtrl.xsp |': No such file or directory in RichText.xs, line 65<br>make[2]: *** [RichText.c] Error 1<br>make[2]: Leaving directory `/home/josh/.cpan/build/Wx-0.92-psm_3c/ext/richtext'<br>make[1]: *** [subdirs] Error 2<br>make[1]: Leaving directory `/home/josh/.cpan/build/Wx-0.92-psm_3c/ext'<br>make: *** [subdirs] Error 2</tt></p></div> </blockquote><p>Anyway, kind of annoying. Wx is prettier than Tk but Tk is easier to install.</p> jjore 2009-09-18T01:33:49+00:00 journal Missing Perl's useful regexp errors http://use.perl.org/~jjore/journal/39636?from=rss <p>Using ruby-1.9, I just got the helpful exception "bin/pp-pretty:60: undefined (?...) sequence: / (RegexpError)". I don't know what it's complaining about since it's not telling me where inside the 70 line regexp it started failing.<nobr> <wbr></nobr>:-(</p><p>When I write Perl, I get useful context like: </p><blockquote><div><p> <tt>Reference to nonexistent named group in regex; marked by &lt;-- HERE in m/<br>&nbsp; (?&lt;object&gt;<br>&nbsp; &nbsp; \#&lt;<br>&nbsp; &nbsp; (?&amp;class_nm)<br>&nbsp; &nbsp; : [ \t\n]*<br>&nbsp; &nbsp; (?:<br>&nbsp; &nbsp; &nbsp; 0x[0-9a-f]+ [ \t\n]* (?=\@) (?&amp;object_data &lt;-- HERE )<br>&nbsp; &nbsp; &nbsp; | [^&gt;]*<br>&nbsp; &nbsp; )?<br>&nbsp; &nbsp; &gt;<br>&nbsp; )/</tt></p></div> </blockquote> jjore 2009-09-16T18:10:05+00:00 journal Starting to chart a map of where perl locates data http://use.perl.org/~jjore/journal/39604?from=rss <p>At work, I've got a problem on the back burner which is kind of interesting. We've got some mod_perl processes with big data sets. The processes fork and then serve requests. I've heard from Operations that they're not using Linux's Copy-on-Write feature to the extent desired so I'm trying to understand just what's being shared and not shared.</p><p>To that end, I wanted to map out where perl put its data. I made a picture (<a href="http://diotalevi.isa-geek.net/~josh/090909/memory-0.png">http://diotalevi.isa-geek.net/~josh/090909/memory-0.png</a>, a strip, showing the visible linear memory layout from 0x3042e0 to 0x8b2990. The left edge shows where arenas are. The really clustered lines to the middle show the pointers from the arenas to the SV heads. The really splayed lines from the middle to the right show the SvANY() pointer from the SV heads to the SV bodies.</p><p>I kind of now suspect that maybe the CoW unshared pages containing SV heads because of reference counting are maybe compact or sparse. They sure seem to be highly clustered so maybe it's a-ok to go get a bunch of values between two forked processes and not worry about reference counts. Sure, the SV head pages are going to be unshared but maybe those pages are just full of other SV heads and it's not a big deal. If SV heads weren't clustered then reference count changes could have affected lots of other pages.</p><p>Anyway, there's a nice little set of pics at <a href="http://diotalevi.isa-geek.net/~josh/090909/">http://diotalevi.isa-geek.net/~josh/090909/</a>. I started truncating precision by powers of two to get things to visually chunk up more. So when you look at memory-0.png, there's no chunking but when you look at memory-4.png, the bottom 4 bits were zeroed out.</p><p>There's a github repo of this at <a href="http://github.com/jbenjore/Internals-GraphArenas/tree/master">http://github.com/jbenjore/Internals-GraphArenas/tree/master</a> for the interested.</p> jjore 2009-09-09T23:32:46+00:00 journal Whither Ruby's Text::Balanced? http://use.perl.org/~jjore/journal/39560?from=rss <p>Today at work the toy problem of extracting some data from $more_json in a line like "$json|$more_json". The obvious thing seemed to use Text::Balanced to skip the first $json, snip off the '|' and then use a real JSON parser on the next json blob.</p><p>So uh... there's no Text::Balanced in Ruby. Not that I can find. We solved our work problem by just declaring that we'd only use delimiters which didn't occur in our input so we wouldn't need to find a Ruby Text::Balanced. I'm thinking maybe the easiest thing to do if we do turn out to need this in Ruby will be to write a gem that embeds a Perl interpreter. Then Ruby's Text::Balanced is just a short adapter over the Perl version.</p><p>It's just a thought though.</p> jjore 2009-08-31T19:07:40+00:00 journal Simple trick to get more copy-on-write goodness http://use.perl.org/~jjore/journal/39514?from=rss <p>I've got a preforking Apache server at work that's not sharing enough memory among the many children. This snippet helped identify post-fork module loading. I put an @INC hook at the end of my httpd.conf and it writes a warning to my log whenever the forked child loads something.</p><blockquote><div><p> <tt># httpd.conf<br>...<br>&lt;Perl&gt;<br>&nbsp; # This fragment goes at the end, when I think I'm ready to let Apache start forking<br>&nbsp; $main::PARENT_PID = $$;<br>&nbsp; unshift @INC, sub {<br>&nbsp; &nbsp; print STDERR "LATE LOAD: $_[1]\n" if $$ != $main::PARENT_PID;<br>&nbsp; &nbsp; return undef;<br>&nbsp; };<br>&lt;/Perl&gt;</tt></p></div> </blockquote><p>I just found 233 modules I was loading post-fork. Oops! It's now trivial to make sure my httpd.conf has the proper lines to load the stuff I was forgetting to:</p><blockquote><div><p> <tt># httpd.conf<br>LoadModule XML::LibXML<br>LoadModule LWP::UserAgent<br>...</tt></p></div> </blockquote> jjore 2009-08-23T23:45:26+00:00 journal Ruby's regexp engine sucks to debug http://use.perl.org/~jjore/journal/39491?from=rss <p>Today, I'm using Ruby for a project at work and Oh! My! God! Every week I get deeper with Ruby I become more impressed with how much I <i>like</i> writing ordinary things in it and how much I <i>loath</i> having to solve hard problems in it. This language, or the implementation seems to go miles out of its way to make it nigh impossible to debug.</p><p>Today's frustration:</p><ul><li>Without changing anything I'm aware of my trepan gem (<a href="http://github.com/jbenjore/trepan/tree/master">http://github.com/jbenjore/trepan/tree/master</a>) has started throwing Bus error</li><li>I've found that the regexp engine is matching "something" wrong</li><li>To debug a regex in 1.8.6, I recompiled ruby with CFLAGS=-DDEBUG_REGEX</li><li>-DDEBUG_REGEX produces only the inscrutable output "regex loop(5): matching 0x01" which doesn't seem to map to anything like characters or offsets or anything. I can't use it</li><li>Ruby 1.9 uses Oniguruma but it also fails to match the same regexp</li><li>Installing the latest Oniguruma from <a href="http://www.geocities.jp/kosako3/oniguruma/">http://www.geocities.jp/kosako3/oniguruma/</a> yields libonig, not something I can use in ruby. Oops</li><li>Building 2.x per the page tries to patch my Ruby 1.8 source code but fails</li><li>There's apparently a<nobr> <wbr></nobr>/third/ version of Oniguruma at <a href="http://rubyforge.org/projects/oniguruma">http://rubyforge.org/projects/oniguruma</a>. Maybe's it's just old? Maybe it's the version that works. Dunno<p>I just want a language that doesn't make me spend immense amounts of energy! Is that so much to ask? I throw tons of energy at perl but I get cool things for it. I'm throwing tons at ruby now and not even getting things I have for <b>FREE</b> in perl.</p><p>FWIW, after spending several hours struggling with Ruby, I threw in the towel. Read a book and went to bed early, exhausted.</p></li></ul> jjore 2009-08-19T15:27:42+00:00 journal CPAN commit bits, given freely http://use.perl.org/~jjore/journal/39480?from=rss <p>Hi there $world and PAUSE administrators,</p><p>Commit bits to my CPAN modules are given freely. If a PAUSE administrator or some other core hackers can vouch for you, I don't mind if upload and indexing permission bits are handed out and I only find out about it later.</p><p>This is prompted by an IRC conversation. I'd gone away for the weekend and left people hanging about whether some permissions were available. The answer in general is "yes, and be nice with them."</p><p>-<br>Josh</p> jjore 2009-08-17T17:41:22+00:00 journal Life... draining... out..., ruby-1.8 to blame http://use.perl.org/~jjore/journal/39405?from=rss <p>Losing...</p><p>the will to live...</p><p>must...</p><p>have...</p><p>useful stack traces...</p><p>I wish Ruby were as useful as Perl. I wish the following had the arguments like I'd get from any perl program using Carp. I also wish this code had just used perror(3) so it'd report the ordinary message "Address already in use" instead of making up its own message "no acceptor."</p><blockquote><div><p> <tt>&gt;&gt; Thin web server (v1.2.2 codename I Find Your Lack of Sauce Disturbing)<br>&gt;&gt; Maximum connections set to 1024<br>&gt;&gt; Listening on, CTRL+C to stop<br>Failed to start the service<br>RuntimeError<br>no acceptor<br>/usr/lib/ruby/gems/1.8/gems/eventmachine-0.12.8/lib/eventmachine.rb:5<nobr>6<wbr></nobr> 5:in `start_tcp_server'<br>/usr/lib/ruby/gems/1.8/gems/eventmachine-0.12.8/lib/eventma<nobr>c<wbr></nobr> hine.rb:565:in `start_server'<br>/usr/lib/ruby/gems/1.8/gems/thin-1.2.2/lib/thin/backends/tcp_se<nobr>r<wbr></nobr> ver.rb:16:in `connect'<br>/usr/lib/ruby/gems/1.8/gems/thin-1.2.2/lib/thin/backends/base.rb:49:<nobr>i<wbr></nobr> n `start'<br>/usr/lib/ruby/gems/1.8/gems/eventmachine-0.12.8/lib/eventmachine.rb:24<nobr>2<wbr></nobr> <nobr> <wbr></nobr>:in `call'<br>/usr/lib/ruby/gems/1.8/gems/eventmachine-0.12.8/lib/eventmachine.rb:242<nobr>:<wbr></nobr> in `run_machine'<br>/usr/lib/ruby/gems/1.8/gems/eventmachine-0.12.8/lib/eventmachine<nobr>.<wbr></nobr> rb:242:in `run'<br>/usr/lib/ruby/gems/1.8/gems/thin-1.2.2/lib/thin/backends/base.rb:57:in `start'<br>/usr/lib/ruby/gems/1.8/gems/thin-1.2.2/lib/thin/server.rb:156:in `start'<br>/usr/lib/ruby/gems/1.8/gems/thin-1.2.2/lib/thin/controllers/controller<nobr>.<wbr></nobr> rb:80:in `start'<br>./basic.rb:68<br>./basic.rb:51:in `initialize'<br>./basic.rb:51:in `new'<br>./basic.rb:51</tt></p></div> </blockquote> jjore 2009-08-05T00:17:23+00:00 journal My phone knows perl http://use.perl.org/~jjore/journal/39393?from=rss <p>It's cool to run perl on my phone. I tried compiling bleadperl on it just now but it didn't generate a Makefile. I guess I'm going to learn how the configuration system works now. The last few weeks have been endless yak shaving. I tracked down some debuild problem through diff to FSF's diffutils and all their various versions, learned how to override parts of Makefiles for ExtUtils::MakeMaker, installed and set up Gnus, have been getting into the internals of Git in a fairly serious way.</p><p>Blech. It seems it's so difficult to get to<nobr> <wbr></nobr>/actual/ work.</p><p><a href="http://www.webos-internals.org/wiki/Application:Terminal">http://www.webos-internals.org/wiki/Application:Terminal</a> fwiw</p> jjore 2009-08-03T04:37:19+00:00 journal Your future Unicode overlords http://use.perl.org/~jjore/journal/39354?from=rss <p>Recently while testing perl-5.10.1-RC0 at $work I found that it worked seamlessly for everything except our custom debianized build. It turns out <a href="http://cpansearch.perl.org/src/ADAMK/Parse-CPAN-Meta-1.39/t/data/utf_16_le_bom.yml">http://cpansearch.perl.org/src/ADAMK/Parse-CPAN-Meta-1.39/t/data/utf_16_le_bom.<nobr>y<wbr></nobr> ml</a> a UTF-16LE encoded file with a BOM (byte order mark) breaks my build of a<nobr> <wbr></nobr>.deb including this.</p><p>debuild makes both the binary and source packages. It's nice for presenting the whole picture to someone trying to follow along later. debuild uses dpkg-source to generate a diff between the vendor's source package and the source tree used in the actual debian build. dpkg-source uses your diff which probably comes from diffutils-2.8.1 which was the last release in 2002 (<a href="http://ftp.gnu.org/pub/gnu/diffutils/">http://ftp.gnu.org/pub/gnu/diffutils/</a>).</p><p>It looks like dev continued on til 2008 including the dev releases (<a href="ftp://alpha.gnu.org/pub/gnu/diffutils/">ftp://alpha.gnu.org/pub/gnu/diffutils/</a>, <a href="http://git.savannah.gnu.org/cgit/diffutils.git">http://git.savannah.gnu.org/cgit/diffutils.git</a>). Somewhere along the way it got support for multibyte characters. It still doesn't work for that UTF-16LE text file with a BOM.</p><p>Oh well. Anyway, consider this a tale of basic tools just not working nicely when your source code is in Unicode.</p> jjore 2009-07-26T09:20:25+00:00 journal You'll miss composable functions http://use.perl.org/~jjore/journal/39347?from=rss <p>In perl or almost any other functional language (I guess) you can combine functions together and the innards of one thing aren't going to affect the flow control of the other. Here's a simple bit of perl:</p><blockquote><div><p> <tt>method trap (CodeRef $block) {<br>&nbsp; &nbsp; $block-&gt;() }<br>&nbsp; &nbsp; uffda(); # Called in Perl, not called in Ruby<br>}<br> &nbsp; <br>method moo (<nobr> <wbr></nobr>... ) {<br>&nbsp; &nbsp; trap( sub {<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; # Early return because<nobr> <wbr></nobr>...<br>&nbsp; &nbsp; &nbsp; &nbsp; return<nobr> <wbr></nobr>... if<nobr> <wbr></nobr>...;<br> &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp;<nobr> <wbr></nobr>...<br>&nbsp; &nbsp; } );<br>}</tt></p></div> </blockquote><p>Writing the equivalent flow control in Ruby and I found out today that the return() calls go all the way <b>through and past</b> the wrapping "trap" function.</p><p>WTF? I don't think I understand how Ruby programmers put up with this. Maybe 1.9 is better about this.</p> jjore 2009-07-24T20:34:11+00:00 journal Gems driving me to drink http://use.perl.org/~jjore/journal/39339?from=rss <p>I don't know my blood pressure but I'm considering getting a desk-side monitor just to empirically know when I'm being driven out of my mind.</p><p>I wish:</p><ul><li>that Ruby's RubyForge had something like CPAN's browseable directories like <a href="http://cpan.org/modules/by-module/Test/">http://cpan.org/modules/by-module/Test/</a> for finding related things all grouped together</li><li>that Ruby's gems were named categorically instead of "Bob's Unit Testing Framework"</li><li>that there was a search.rubyforge.org which worked at least as nice as <a href="http://search.cpan.org/">http://search.cpan.org/</a></li><li>that I could find where the test reports of gem's tests are aggregated like the CPAN Tester's <a href="http://matrix.cpantesters.org/?dist=Test-Simple+0.92">http://matrix.cpantesters.org/?dist=Test-Simple+0.92</a></li></ul><p>Work day's done now. I feel ill.</p> jjore 2009-07-24T00:09:13+00:00 journal Cuneiform version numbers http://use.perl.org/~jjore/journal/39338?from=rss <p>I was disappointed yesterday to find out I couldn't fully use Sumerian numbers even though I don't know a thing about them. Given the ASCII program:</p><blockquote><div><p> <tt>use 5.010_000;<br>use strict;<br>use warnings;<br>use version qw( qv );<br>use Devel::Peek qw( Dump );<br>use charnames qw(<nobr> <wbr></nobr>:full );<br> &nbsp; <br>binmode STDOUT, ':encoding(utf8)';<br>eval "use utf8;<br>&nbsp; &nbsp; package Booga;<br>&nbsp; &nbsp; our \$VERSION = '\N{CUNEIFORM NUMERIC SIGN TWO ASH}';<br>&nbsp; &nbsp; \$INC{'Booga.pm'} = 1;<br>&nbsp; &nbsp; sub iz { 'Okay!' }<br> &nbsp; <br>&nbsp; &nbsp; 1;<br>"<br>&nbsp; or die $@;<br> &nbsp; <br>eval "use utf8;<br>&nbsp; &nbsp; use Booga \N{CUNEIFORM NUMERIC SIGN THREE ASH};<br>&nbsp; &nbsp; print Booga::iz(), qq{\\n};<br>&nbsp; &nbsp; 1;<br>"<br>&nbsp; or die $@;<br> &nbsp; <br>Dump( $Booga::VERSION &gt; 1);<br>Dump( Booga-&gt;VERSION );<br>Dump( qv( $Booga::VERSION ) );</tt></p></div> </blockquote><p>Several things came out:</p><ul><li>"\N{CUNEIFORM NUMERIC SIGN TWO ASH}"<br> &nbsp; &nbsp; <ul><li><br> &nbsp; &nbsp; &nbsp; &nbsp;</li> <li>is numeric according to<nobr> <wbr></nobr>/\p{Nd}/<br> &nbsp; &nbsp; &nbsp; &nbsp;</li> <li>is not numeric according to &lt;=&gt;<br> &nbsp; &nbsp; &nbsp; &nbsp;</li> <li>is not numeric according to version::qv<br> &nbsp; &nbsp; &nbsp; &nbsp;</li> <li>is not numeric according to Booga-&gt;VERSION<br> &nbsp; &nbsp;</li> </ul></li><li>use Booga &amp;#x12409;<blockquote><div><p> <tt>Bareword "&amp;#x12409;" not allowed while "strict subs" in use at (eval 7) line 2.</tt></p></div> </blockquote></li> <li>use Booga 2;<blockquote><div><p> <tt>Version string '&amp;#x12409;' contains invalid data; ignoring: '&amp;#x12409;' at (eval 7) line 2.<br>Booga version 2 required--this is only version 0 at (eval 7) line 2.</tt></p></div> </blockquote></li> <li>$Booga::VERSION &gt; 2<blockquote><div><p> <tt>Argument "\x{12409}" isn't numeric in numeric gt (&amp;gt;) at booga line 27.</tt></p></div> </blockquote></li> <li>Booga-&gt;VERSION<blockquote><div><p> <tt>Version string '&amp;#x12409;' contains invalid data; ignoring: '&amp;#x12409;' at booga line 28.<br> &nbsp; <br>SV = PV(0x82ca18) at 0x847b30<br>&nbsp; REFCNT = 1<br>&nbsp; FLAGS = (POK,pPOK)<br>&nbsp; PV = 0x25beb0 "0"\0<br>&nbsp; CUR = 1<br>&nbsp; LEN = 16</tt></p></div> </blockquote></li> </ul><p>Also, the HTML formatting of this post is defeating me.<nobr> <wbr></nobr>:-(</p> jjore 2009-07-23T20:12:28+00:00 journal git up to date http://use.perl.org/~jjore/journal/39335?from=rss <p>One of my esteemed prior co-workers recommends that I follow git releases very closely. I've added a "git-update" command into my path so I can just say "git update" occasionally to get all the newest features and bugs.</p><blockquote><div><p> <tt>#!/bin/bash<br>(<br>&nbsp; set -e<br>&nbsp; cd $HOME/src/git<br>&nbsp; export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin<br>&nbsp; git fetch<br>&nbsp; git clean -xdf<br>&nbsp; git reset --hard<br>&nbsp; git merge origin/master<br>&nbsp; make configure<br>&nbsp; sh configure --prefix=/opt/git<br>&nbsp; make all doc<br>&nbsp; sudo make install install-doc install-html<br>)</tt></p></div> </blockquote> jjore 2009-07-22T22:02:17+00:00 journal A MANIFESTly bad idea http://use.perl.org/~jjore/journal/39333?from=rss <p>While cleaning my home directory, I found this beauty in ~/OhNo-0.01/MANIFEST.</p><blockquote><div><p> <tt>touch $'\x2f'|<br>Changes<br>Makefile.PL<br>MANIFEST<br>README<br>lib/OhNo.pm</tt></p></div> </blockquote> jjore 2009-07-22T20:47:04+00:00 journal Add remote debugging terminal to mod_perl http://use.perl.org/~jjore/journal/39325?from=rss <p>Occasionally my mod_perl servers go sour and it's useful to attach a remote debugger. There's typically no useful console and production doesn't run under the debugger. I'm forced into two things: force load the debugger with Enbugger and then have it connect to a remote terminal.</p><p>Works great BTW and is almost identical to <a href="http://use.perl.org/~jjore/journal/39319">http://use.perl.org/~jjore/journal/39319</a>. The only real difference is we're eval()ing something different. This is also documented as a "cookbook" recipe in at <a href="http://search.cpan.org/dist/Enbugger">http://search.cpan.org/dist/Enbugger</a>.</p><p>Step 1: Start a remote terminal. I like netcat. I'll just start a Terminal and have it listen on port 8000. Anything that connect there will show up and I'll be able to type to it, etc.</p><blockquote><div><p> <tt>nc -l 8000</tt></p></div> </blockquote><p>Step 2: Attach GDB to mod_perl. Assuming my process ID is 765, I can attach with the simple command:</p><blockquote><div><p> <tt>gdb -p 765</tt></p></div> </blockquote><p>It's occasionally useful to know if there's anything "interesting" going on so get a quick backtrace of the current call stack:</p><blockquote><div><p> <tt>(gdb) backtrace<br>#0&nbsp; 0xb7f7b919 in poll () from<nobr> <wbr></nobr>/lib/tls/libc.so.6<br>#1&nbsp; 0xb7da57ff in apr_poll () from<nobr> <wbr></nobr>/opt/apache/das/lib/libapr-0.so.0<br>#2&nbsp; 0x080b2050 in child_main ()<br>#3&nbsp; 0x080b231e in make_child ()<br>#4&nbsp; 0x080b2393 in startup_children ()<br>#5&nbsp; 0x080b279c in ap_mpm_run ()<br>#6&nbsp; 0x080b93c9 in main ()</tt></p></div> </blockquote><p>Step 3: As in <a href="http://use.perl.org/~jjore/journal/39319">http://use.perl.org/~jjore/journal/39319</a>, I need to know whether there's a thread context to pass into eval().</p><blockquote><div><p> <tt>(gdb) print $thread_context = (void*)Perl_get_context()<br>$1 = (void *) 0x0</tt></p></div> </blockquote><p>OR</p><blockquote><div><p> <tt>(gdb) print $thread_context = (void*)Perl_get_context()<br>$1 = (void *) 0x800000</tt></p></div> </blockquote><p>Step 4: Install the debugger. If you've got a $thread_context, it goes before the eval string (eval_pv($ctx,"...",0)).</p><blockquote><div><p> <tt>(gdb) call (void*)Perl_eval_pv("eval { require Enbugger; print STDERR qq{stopping\\n}; $ENV{PERLDB_OPTS} = 'RemotePort=localhost:4000'; Enbugger-&gt;stop;}; print STDERR $@; print STDERR qq{stopped?\\n};", 0)</tt></p></div> </blockquote><p>Step 5: profit:</p><blockquote><div><p> <tt>jjore$ nc -l -p 4000<br> &nbsp; <br>Loading DB routines from perl5db.pl version 1.28<br>Editor support available.<br> &nbsp; <br>Enter h or `h h' for help, or `man perldebug' for more help.<br> &nbsp; <br>x<br>main::((eval 982):1):&nbsp; &nbsp; print STDERR $@<br>&nbsp; DB&lt;1&gt; 0&nbsp; 0<br>&nbsp; DB&lt;1&gt;</tt></p></div> </blockquote><p>Step 6: Now detach to resume your program. You've interrupted your program at two levels. First at perl, so run "c" to continue out from the perl debugger. Second, in gdb so "detach" or "quit" to continue the process.</p> jjore 2009-07-20T15:48:06+00:00 journal Get a stack trace from your running perl http://use.perl.org/~jjore/journal/39319?from=rss <p>When you've got a process that's spinning and don't know what's going on, it's useful to get a perl level stack trace. There's a "simple" gdb function to get your perl to write its call stack to STDERR. It's not entirely without risk to corrupting your process. I've used it just fine against my mod_perl in prod when all our other normal methods of inspection failed.</p><p>Step 1: attach with gdb.</p><blockquote><div><p> <tt>jjore$ ps -x<br>&nbsp; PID&nbsp; &nbsp;TT&nbsp; STAT&nbsp; &nbsp; &nbsp; TIME COMMAND<br>...<br>&nbsp; 765 s001&nbsp; S&nbsp; &nbsp; &nbsp; 0:00.01 perl -e while(1){sleep 1}<br> &nbsp; <br>jjore$ gdb --quiet -p 765<br>Attaching to process 780.<br>Reading symbols for shared libraries . done<br>Reading symbols for shared libraries<br>warning: Could not find object file "..." - no debug information available for "...c".<br>...<br>..... done<br>0x9005e46e in __semwait_signal ()<br>(gdb)</tt></p></div> </blockquote><p>Step 2: Get a C level backtrace to see if that's informative enough. In this case, I can see the program is current in some sleep functions. In prod, I've seen things like bugs in libxslt show up nicely here - I could see the stack extending down into the libxml/libxslt libraries which eventually lead me to solve the problem by upgrade my libxml library.</p><blockquote><div><p> <tt>(gdb) bt<br>#0&nbsp; 0x9005e46e in __semwait_signal ()<br>#1&nbsp; 0x9005e2ef in nanosleep$UNIX2003 ()<br>#2&nbsp; 0x900b3e71 in sleep$UNIX2003 ()<br>#3&nbsp; 0x0015a054 in Perl_pp_sleep ()<br>#4&nbsp; 0x00081bb7 in Perl_runops_debug ()<br>#5&nbsp; 0x000b6791 in perl_run ()<br>#6&nbsp; 0x0000247e in main ()</tt></p></div> </blockquote><p>Step 3: Get your thread context pointer. For threaded perl, you'll need to pass in a thread context pointer. If this step returns 0x0, you don't have threaded perl and shouldn't pass this argument in. If you get something other than 0x0, you'll need to use this value.</p><blockquote><div><p> <tt>(gdb) print $thread_context = (void*)Perl_get_context()<br>$1 = (void *) 0x0</tt></p></div> </blockquote><p>OR</p><blockquote><div><p> <tt>(gdb) print $thread_context = (void*)Perl_get_context()<br>$1 = (void *) 0x800000</tt></p></div> </blockquote><p>Step 4: Use Carp::cluck() from inside gdb. If you've got a $thread_context, use it.</p><blockquote><div><p> <tt>(gdb) call (void*)Perl_eval_pv($thread_context, "require Carp;Carp::cluck('Hi')", 0)</tt></p></div> </blockquote><p>OR</p><blockquote><div><p> <tt>(gdb) call (void*)Perl_eval_pv("require Carp; Carp::cluck('Hi')", 0)</tt></p></div> </blockquote><p>Step 5: Profit.</p><blockquote><div><p> <tt>Hi at (eval 1) line 1<br>&nbsp; &nbsp; eval 'require Carp; Carp::cluck(\'Hi\')<br>;' called at -e line 1</tt></p></div> </blockquote> jjore 2009-07-20T05:05:49+00:00 journal