Hi,


I have a bunch of users getting SEGVs in my DVDSpanner app, and I honestly have no idea where to start looking.


Partly I think it may be due to using threads, and perl threads just not being stable, but I'm unsure.


Here's the top bit of the stack trace:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000036d45493
Crashed Thread:  0  Dispatch queue: com.apple.main-thread

Application Specific Information:
objc_msgSend() selector name: methodSignatureForSelector:


Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib               0x9361fedb objc_msgSend + 27
1   CamelBones.bundle             0x000c78cf XS_CamelBones_CBCallNativeMethod + 485
2   libperl.dylib                 0x00566141 Perl_pp_entersub + 1288
3   libperl.dylib                 0x0055f421 Perl_runops_standard + 41
4   libperl.dylib                 0x0055727f Perl_nothreadhook + 87
5   libperl.dylib                 0x00559c16 Perl_call_sv + 733
6   org.CamelBones.PerlBundle     0x00040a2b REAL_CBPerlIMP + 2820
7   com.apple.Foundation           0x91e67968 __NSFireTimer + 141

And the timer is fired calling this:

# used to update GUI
sub tick : Selector(tick:)
           ArgTypes(@) ReturnType(v)
{
    my ($self, $timer) = @_;
   
    return unless $timer->isValid;
   
    if (my $burn = $self->{in_burn}) {
        return $self->tick_burn($burn);
    }
   
    my $ev_count = 0;
    my $start = Time::HiRes::time();
   
    # pull up to 10 items off
    while (1) {
        my $data = $self->{status_queue}->dequeue_nb;
        last unless defined($data);
       
        #NSLog($data);
        if ($data =~ /^cmd_/) {
            my @params;
            if ($data =~ s/:(.*)$//) {
                @params = split(/:/, $1);
            }
            if (my $func = $self->can($data)) {
                $func->($self, @params);
            }
            else {
                NSLog("No such command: '$data' (@params)");
            }
        }
        else {
            NSLog("Unrecognised status: $data");
        }
       
        last if (Time::HiRes::time() > ($start + (TICKER_TIME * 0.9)) );
    }
    #NSLog("ticker end");
}

sub tick_burn {
    my ($self, $burn) = @_;
   
    my $burn_status      = $burn->status->objectForKey("DRStatusStateKey");
    $burn_status =~ s/^DRStatusState//;
        $burn_status =~ s/([a-z])([A-Z])/$1 $2/g;
   
    #NSLog("Burn status: $burn_status");
   
    if ($burn_status eq "Failed") {
        $self->{in_burn} = undef;
        $burn->release;
       
        $self->library->rollback_work;
       
        my $def_button = undef;
        my $alt_button = "Cancel";
        my $other_button = undef;
        my $alert = NSAlert->alertWithMessageText_defaultButton_alternateButton_otherButton_informativeTextWithFormat(
                                                                                                                      "Burn Failed", $def_button, $alt_button, $other_button, "Disc burning failed. Continue with other discs?"
                                                                                                                      );
        my $ret = $alert->runModal();
        $self->{control_queue}->enqueue($ret);
    }
    elsif ($burn_status eq "Done") {
        $self->{in_burn} = undef;
        $self->{drfolder}->release;
        $self->{drfolder} = undef;
        $burn->release;
        $self->library->commit_work;
        $self->{control_queue}->enqueue(1);
    }
    else {
        my $percent_complete = $burn->status->objectForKey("DRStatusPercentCompleteKey")->doubleValue;
       
        $self->dvdProgressText->setStringValue("Burning ($burn_status)...");
        if ($percent_complete >= 0) {
            $self->dvdProgressBar->setIndeterminate(0);
            $self->dvdProgressBar->setDoubleValue($percent_complete * 100);
        }
        else {
            $self->dvdProgressBar->setIndeterminate(1);
        }
    }
   
    return;
}

Any thoughts?