Linux за българи: Форуми

Програмиране => Web development => Темата е започната от: CaBA в Apr 20, 2005, 18:55



Титла: Трасиране на стека на perl
Публикувано от: CaBA в Apr 20, 2005, 18:55
Дебъгвам CGI скриптове, които имат такава структура:
Примерен код
eval{
...#тук се извикват функции от разни модули, които хвърлят изключения - die
};

if ($@)
{
   ...#тук се обработват изключенията
}

Въпросът ми е: когато възникне изключение, дали може да се трасира стека? След излизането от eval-a интерпретаторът е извадил от стека извиканите функции, но дали има начин те да се достигнат някакси?
Практическата полза от упражнението е, че при възникване на неочаквано изключение в производствена среда проблемът ще бъде открит по-лесно.


Титла: Трасиране на стека на perl
Публикувано от: danchev в Apr 20, 2005, 19:36
Здрасти Сава,

по принцип се запуска дебъгера на интерпретера: perl -d и гледаш за Stack Tracing (T) и Tracing Program Execution тук например: http://linux.skavt.net/teach_perl_in_21days/ch21.htm

п.с. Отдавна има нужда да се заформи свестен bg perl mailing list, като тук например: http://lists.uni-sofia.bg/cgi-bin/mailman/listinfo/perl


Титла: Трасиране на стека на perl
Публикувано от: zazzko в Apr 20, 2005, 20:48
Това определено е добра идея. Или пощенски списък или форум само за perl.


Титла: Трасиране на стека на perl
Публикувано от: CaBA в Apr 22, 2005, 13:03
Уф, сега като чета въпроса си, виждам че съм го задал доста зле :(
Всъщност исках да кажа "тествам" вместо "дебъгвам" - т.е. кодът е сравнително узрял и го друсам да видя дали ще падне :). Въпросът е, че когато го тестват потребителите и приложението се срути на неочаквано от мен място, $@ e с доста неинформативно съдържание и в лога се появава примерно:
Примерен код
Cannot decode string with wide characters at /usr/lib/perl5/5.8.3/i586-linux-thread-multi/Encode.pm line 164, <DATA> line 373.

В случая е ясно, че има някаква грешка в моето приложение, което извиква Encode::decode() със параметър, който съдържа "wide characters", обаче как да разбера кое това извикване, като в програмата има 10 такива?
Единият подход е да се опитам да уловя грешката при всяко такова извикване, т.е. да го заградя в
Примерен код
eval{...} if($@){..}
Обаче този подход не ми се струва особено елегантен - той трябва да се прави за всеки ред. Все пак приложението ми е изградено като Модел-Изглед-Контролер, така че всички изключения в модела се улавят от контролера. Първоначалната ми идея беше да използвам DB пакета да се закача след eval преди връщането от стека, обаче като четох man страницата му, май няма да стане или ще е доста сложно, свързано с ровене във вътрешностите на perl.


Титла: Трасиране на стека на perl
Публикувано от: CaBA в Apr 22, 2005, 13:12
Исках задам въпроса директно в пощенския списък на perl, след като видях адреса му в списъка на LUG-BG (дискусията къде трябва да отиват въпросите относно perl), обаче видях, че архивът му е празен и това ме обезкуражи.
Иначе вече се записах и ще го задам и там, когато ми остане време.


Титла: Трасиране на стека на perl
Публикувано от: zarrro в May 18, 2005, 11:46
Не знам да ли си виждал това. Там е обяснено подробно.


Титла: Трасиране на стека на perl
Публикувано от: CaBA в May 18, 2005, 15:14
Да, виждал съм Error модула. Само че той има огромен проблем: try{} и catch{} блоковете са реализирани като функционални затваряния и затова всяко влагане, например
Примерен код

try
{
  some_function();
}

sub some_function
{
  try
  {
      ...
  }
}
резултира в утечка на памет. Между другото, това е и основната причина try и catch да са част от Perl 6.

А първоначалната ми идея e нереализируема върху фон Ноймановата архитектура.


Титла: Трасиране на стека на perl
Публикувано от: zarrro в May 18, 2005, 18:23
Ееех.. Perl 6, дано Лари  скоро да приключи с Апокалипсисите:)

Иначе аз имах предвид това че eval просто не го може това.


Титла: Трасиране на стека на perl
Публикувано от: CaBA в May 18, 2005, 20:48
Опааа, оказа, че не съм съвсем прав - можело. Вместо eval се ползва модула Try.pm, имплементация на http://www.avrasoft.com/perl6/rfc88.htm за Perl 5. Това, което искам, го прави методът show() - трасира стека.