[Moscow.pm] как правильно сделать exit? (system in (global)?DESTROY)

Konstantin S. Uvarin khedin на gmail.com
Пн Мар 11 04:18:30 PDT 2013


Приветствую! 

> есть некий код - обертка над консольным приложением (вообще все это в
> тестах происходит)
> 
> 
> то есть обертка запускает консольку и помнит ее pid (общается с ней по
> сокету), а деструктор делает нечто вроде следующего
> 
>     sub DESTROY {
>         my ($self) = @_;
>         kill KILL => $self->{child};
>         waitpid $self->{child}, 0;
>         rmtree $self->{tempdir};
>     }
> 
> 
> 
> 
> ну и все работало нормально.
> 
> Далее, поскольку консолька пускается во временной директории, то
> решили добавить еще снятие бактрейса если консолька грохается в
> сегфолт. сваяли нечто вроде следующего:
> 
> 
>     sub DESTROY {
>         my ($self) = @_;
>         if (-r $self->{core}) [
>             system "echo bt|gdb $self->{path} $self->{core}";
>         }
> 
>         kill KILL => $self->{child} if $self->{child};
>         waitpid $self->{child}, 0;
>         rmtree $self->{tempdir};
>     }
> 
> и вот такой код приводит к тому что в пакете main такой вот код:
> 
> exit 123;
> 
> приводит к тому что приложение всегда возвращает 0 если был вызов
> system.
> 
> вопрос: где баг и как правильно сделать?

Проблема в глобальности $?. local $? в деструкторе должно помочь. 

Проверял только с END { }, но вроде бы так же должно работать (у меня была 
похожая штука именно в DESTROY и тоже с удалением временной директории). 

-bash$ perl -we 'exit 123; END { system "true" }' ; echo $?
0
-bash$ perl -we 'exit 123; END { local $?; system "true" }' ; echo $?
123


--
WBR,
Konstantin S. Uvarin


Подробная информация о списке рассылки Moscow-pm