LINUX.ORG.RU

теряется код завершения процесса


0

2

привет.

речь идет о systrace. исходники лежат тут.

проблема в следующем: если трейсить программу собранную из этого( int main() {*((int)0)=33;return 44;} ) микрохеловорда, то код завершения получим неправильный - 0. если в этом хеловорде закомментить сегфолтную строку - код завершения правильный - 44.

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

последний вопрос в том, как доделать systrace?

дочерний процесс запускается отсюда, в зависимости от условия. сама функция запускающая процесс - тут.

я вот только немогу понять, куда я должен вписать wait()/waitpid() и код, который определит каким образом завершился процесс, и вернет его статус?

благодарен.

зы готов рассмотреть возможность вознаграждения.

★★★

ммм, в случае сегфолта прога не доходит до return 44. Поэтому было бы странно видеть 44 в коде возврата.

ЗЫ топик читал по диагонали, может во что-то не въехал

true_admin ★★★★★ ()

куда я должен вписать wait()/waitpid()

Если ты о функциях из libc то пихай куда хочешь :).

true_admin ★★★★★ ()
Ответ на: комментарий от true_admin

в случае сегфолта, процесс возвращает 11(SIGSEGV)

niXman ★★★ ()
Ответ на: комментарий от niXman

Он не возвращает — он получает. Походу ты путаешь сигналы и коды возврата.

beastie ★★★★★ ()
Ответ на: комментарий от niXman

ммм, у меня 139: Exit codes in the range 129-255 represent jobs terminated by Unix «signals».

true_admin ★★★★★ ()
Ответ на: комментарий от niXman

Смотри “man 2 wait” и sys/wait.h в частности WEXITSTATUS и WTERMSIG.

UPD: т.е. всё правильно, код завершения 0 → WEXITSTATUS(139) == 0 и убит SIGSEGV → WTERMSIG(139) == 11. В статусе передаётся больше, чем только код завершения.

beastie ★★★★★ ()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от beastie

я же в топике дал ссылку на доку которую прочел перед созданием топика. я знаю что вписывать(чего не хватает в systrace). но я не знаю куда это вписывать.

niXman ★★★ ()
Ответ на: комментарий от niXman

но я не знаю куда это вписывать.

В код родительского процесса. Только он и может ждать.

const86 ★★★★★ ()
Ответ на: комментарий от const86

wait4 там есть: https://github.com/majek/systrace/blob/master/systrace.c#L457, но сигнал-хандлер там с ошибками — сильно не вчитывался — первое, что в глаза бросилось, но данный кусок кода должен выглядеть примерно так:

static void
child_handler(int sig)
{
        int s = errno, status;

        /* и так ясно, что sig == SIGCHLD */
        close(trfd);
        while (wait4(-1, &status, WNOHANG, NULL) > 0)
                ;

        /* что дальше со status делать? */

        errno = s;
}
и именно тут status похоже и теряется.
signal(SIGCHLD, child_handler)
должен быть в main().

UPD: хотя… были там какие-то заковырки с SIGCHLD, не помню уже, поэтому всё, что я написал выше — ложь и IMHO ☺

beastie ★★★★★ ()
Последнее исправление: beastie (всего исправлений: 3)
Ответ на: комментарий от const86

в код systrace. да, я в курсе. ваша помощь неоценима, кэп.

niXman ★★★ ()
Ответ на: комментарий от niXman

Ну что вы, право, я ж со всей душой :) Ладно, wait4() там и так уже есть, только его результат бережно выбрасывается. Ты свой ноль где именно увидел? Ну и в intercept_run() я вижу какие-то жуткие пляски с уходом в background, вызовом daemon и там даже wait() зачем-то дёргается. С ходу даже и непонятно, кто на ком стоит. Так что прошу относиться к моему предыдущему посту не только как к шутке.

const86 ★★★★★ ()
Ответ на: комментарий от beastie

были там какие-то заковырки с SIGCHLD

Я помню только две, да и те здесь ни при делах. Если его заигнорить, то дети будут дохнуть вообще бесследно. И если поставить любой обработчик с флагом SA_NOCLDWAIT, то статус прилетит только в этот обработчик, а процесс пропадёт без wait*().

const86 ★★★★★ ()
Ответ на: комментарий от const86

Была там что-то, что обработчик SIGCHLD теряется в обработчике и его заново реиницализировать надо…

Т.ч. до дальнейшего разбора полётов полностью реведирую свою правку кода.

beastie ★★★★★ ()
Ответ на: комментарий от beastie

Была там что-то, что обработчик SIGCHLD теряется в обработчике и его заново реиницализировать надо…

Может, в каких-то бородатых системах только. Можно использовать sigaction() вместо signal(), там всё чётко рулится флагами.

const86 ★★★★★ ()
Ответ на: комментарий от niXman

Ты свой ноль где именно увидел?

в консоле.

Отлично. Если код не менял, то это всё и объясняет, ибо там статус просто выбрасывается.

const86 ★★★★★ ()
Ответ на: комментарий от const86

там статус просто выбрасывается.

где «там»? можно номер строки, плиз? ;)

niXman ★★★ ()
Ответ на: комментарий от niXman

Вот здесь статус положили в локальную переменную и больше не используем. Ещё один wait() дёргается в intercept_run() и точно так же статус никуда не возвращается и не передаётся.

const86 ★★★★★ ()
Ответ на: комментарий от const86

Вы на учли важный момент. а именно, что если трейсируемая программа завершается корректно, то systrace возвращает правильный код завершения программы. откуда-то он же его получает.

во вторых - единственный участок кода хоть как-то похожий на подходящее по цели использование child_handler(), находится тут и игнорируется препроцессором.

niXman ★★★ ()

А там в исходника в файле README в постскриптуме что-то ptrace, линукс и эмуляцию waitpid. Вы в это вникали?

mky ★★★★★ ()
Ответ на: комментарий от mky

только что прочел. там что-то про эмуляцию waitpid() и особенности pthrace на линуксах. не понятно, имеет ли это отношение к проблеме, или нет..

niXman ★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.