Как отлаживать модуль mod_perl2 без перезапуска?

Среда: Apache / 2.2.11 (Win32) mod_apreq2-20051231 / 2.6.2-dev mod_perl / 2.0.4-dev Perl / v5.10.0

Ситуация очень похожа на то, что описано в этом сообщении со списком обсуждения, за исключением находясь на win32.

У меня это в httpd.conf:

PerlModule Apache2::Reload
PerlInitHandler Apache2::Reload
PerlSetVar ReloadAll Off
PerlSetVar ReloadModules "MyPackage::*"

... а также обработка скриптов mod-perl.

У меня есть сценарий, в котором используется модуль MyPackage, и он работает.

Я ломаю модуль и перезагружаю скрипт. Ошибка полезна, сообщая строчку, где я сломал модуль.

(Если я перезагружаюсь в этот момент, и он сообщает мне только «Неопределенная подпрограмма и ModPerl :: ROOT :: ModPerl :: Registry ...», потому что он не смог загрузить файл в первый раз. Но в любом случае следующее поведение по-прежнему происходит.)

Я возвращаю паузу и тоже касаюсь файла сценария, чтобы он перезагрузил модуль, и перезагрузил. Теперь там написано:

Attempt to reload MyPackage/Foo.pm aborted.
Compilation failed in require at E:/dev/test.pl line 4.

И даже если я прикоснусь к скрипту и модулю, я не смогу правильно перезагрузить его, кроме как перезапустив веб-сервер.

Нарушение только самого скрипта (в отличие от модуля) работает нормально: правильные ошибки и его обратное изменение приводят к тому, что он снова работает после перезагрузки.

После каждого из этих действий я перезапускал веб-сервер перед тестированием:

  1. Я пробовал выполнить трассировку, но строка, в которой продолжает появляться ошибка, - это строка 204 ModPerl / RegistryCooker.pm, которая представляет собой просто строку, которая оценивает весь сценарий.

  2. Я пробовал изменить «использовать предупреждения FATAL => 'all'», чтобы просто «использовать предупреждения» в скрипте и модуле. Не имело значения.

  3. Я пробовал отключить свою пользовательскую функцию $ SIG {__ DIE__}. Не имело значения. (Ну, конечно, только там, где ошибка возникла, но сгенерированные ошибки были такими же.)

  4. По ссылке на обсуждение в начале обнаружил, что MaxRequestsPerChild все это время был равен 0, и я попробовал ThreadsPerChild 1, но без разницы. Я попробовал MaxRequestsPerChild до 1, что решает странное поведение этого вопроса, но перезагружает веб-сервер после каждого отдельного запроса:

    Child 7072: Process exiting because it reached MaxRequestsPerChild. Signaling the parent to restart a new child process.
    Parent: Received restart signal -- Restarting the server.
    

    Это не очень хорошее решение, поскольку у меня есть значительный фрагмент кода, который запускается при первом обращении к странице.

  5. Также, согласно обсуждению, я запускаю httpd как службу, поэтому я добавил -X в окно параметров службы и нажал «Пуск», и он все еще пытался запустить полные три минуты спустя (обычно запускается в течение 3 секунд). Даже получил тайм-аут. сообщение. Убил процесс через диспетчер задач и подтвердил, что я не могу открыть страницу из веб-браузера. Запустил httpd -X из командной строки. По-прежнему такое же поведение, как и в начале этого вопроса. Также мне показалось странным, что -X не было в списке, когда я запускал httpd - ?. Может его нет на win32 MPM?

  6. # P18 #
    # P19 #
    # P20 #

Нет ли возможности работать с модулями mod_perl2 без перезапуска веб-сервера после каждой перезагрузки (автоматически, через MaxRequestsPerChild, или вручную, как раньше)?


person Community    schedule 11.02.2009    source источник


Ответы (1)


Скопируйте подпрограмму в сценарий, из которого вы ее вызываете, и поместите этот код перед копией:

package MyPackage::Foo;
no warnings 'redefine';

Когда вы закончите вносить изменения, переместите подпрограмму обратно в фактический модуль.

person Community    schedule 17.02.2009
comment
Вам действительно нужно перезапустить его после копирования (иногда!), Но до тех пор это все равно полезно. - person Kev; 18.02.2009