in reply to Re^2: panic: attempt to copy freed scalar a7b9650 to ad20598
in thread panic: attempt to copy freed scalar a7b9650 to ad20598

I doubt the problem is with Try::Tiny. This kind of problem is caused by bugs in Perl code or code that uses Perl as a library (XS code, B::, etc), and Try::Tiny doesn't have anything that. In fact, it's a tiny (living up to its name) and straightforward (nothing fancy) Perl module.

Start by trying your code on 5.10.1. Lots of bug fixes there.

  • Comment on Re^3: panic: attempt to copy freed scalar a7b9650 to ad20598

Replies are listed 'Best First'.
Re^4: panic: attempt to copy freed scalar a7b9650 to ad20598
by mje (Curate) on Dec 03, 2009 at 18:10 UTC

    I have built a default build of 5.10.1. It probably does not match how ubuntu build it (I don't know how they build it). When I run the problem code now I get the following on the console:

    Variable "$clientref" is not available at /home/martin/server/q.pl.pan +ics line 1894, <GEN506> line 1.

    It is strange as that line is the "};" at the end of the catch block. Although $clientref is referenced in the try block it is created above with a my at the start of the sub containing the try.

      Great! That's an unrelated error that you would need to fix no matter which version of Perl you were using.

      You're trying to capturing something, but Perl didn't capture it because it didn't think it needed too. It tries to capture the minimum amount of varaibles.

      Note that

      try { ... } catch { ... };
      is the same as
      try(sub { ... }, catch(sub { ... }));

      The error occurs with eval EXPR:

      $ perl -wle' sub f { my $x = "abc"; sub { eval q{"[$x]"} } }; print f()->(); ' Variable "$x" is not available at (eval 1) line 1. Use of uninitialized value in print at -e line 1. []

      The workaround is to make sure the sub references the lexical variables you will need in the eval EXPR:

      $ perl -wle' sub f { my $x = "abc"; sub { $x if 0; eval q{"[$x]"} } }; print f()->(); ' [abc]

        Thanks ikegami but I'm still not quite understanding this but I certainly appreciate your help. In your example you've used $x for the "workaround". I don't understand why I have to do this. Perhaps it would be easier if I posted the exact code (comments labelled MJE I added):

        sub queue_job { my ($betdb, $q, $job) = @_; my $key; $job->{jobid} = new_job_id($betdb); # MJE - obviously this can be undef but in the case in # question it is usually set my $clientref = $job->{clientref} if (exists($job->{clientref})); # # Insert info about this job in the audit file. # NOTE: This will fail if we've seen this client_reference before +as # client_reference is unique and it would indicate a client has su +bmitted # the same job twice e.g. posted the same job twice. # my $caught = try { my $repost = $clientref ? 0 : undef; $betdb->execProc( $p_run_or_queue_job, {DieOnError => 1, Comment => 'queue_job'}, $job->{jobid}, $clientref, $job->{sessionid}, $job->{name}, {clob => $json->objToData($job)}, $repost, 1); 0; } catch { my $ev = $_; if (($betdb->getDBh())->err == 1) { # constraint violation eval { $betdb->callPkgProc( {DieOnError => 1, Comment => 'run_now'}, BET::DB::SYN_PKG_BETDB, 'p_invalidJobRequest', $job->{jobid}, $clientref, $job->{sessionid}, $job->{name}, $json->objToData($job->{args}), R_DIE, "Job already seen"); 1; } or $log->warn("Failed to mark job already seen - $@"); $job->{joberr} = 'Already seen this job'; $job->{jobnative} = c_JOB_ALREADY_SEEN; $log->warn(sub {'JOB ALREADY POSTED ' . Dumper($job)}); } else { $log->logwarn("Failed to insert into job_audit, $ev"); } 1; }; return if $caught; my @now = gmtime(time()); $job->{jobqed} = sprintf "%d/%d/%d %02d:%02d:%02d", $now[3], $now[4]+1, $now[5]+1900, $now[2], $now[1], $now[0]; push @{$q->{jobs}}, $job; $q->{queued}->{$key} = $job->{jobid} if ($key); $log->debug("Queued job " . $job->{jobid}); $total_jobs_on_all_queues++; return $job->{jobid}; }

        $clientref if the scalar which 5.10.1 complains about.

Re^4: panic: attempt to copy freed scalar a7b9650 to ad20598
by mje (Curate) on Dec 03, 2009 at 16:46 UTC

    I'll try 5.10.1 but that will take a while to build and then install all the modules. It will also be annoying if it is fixed in 5.10.1 as this box is currently only using a packaged perl and I think the only upgrade path would be to delete the packaged perl and build our own (thus losing the benefit of the package system). There is some XS code (DBD::Oracle) inside the try and catch blocks but it works inside a simple eval (but then again, as you say Try::Tiny is really only an eval wrapper).