Odpowiednik „truss-T” i „truss -U” w systemie Linux?

12

Czy istnieje odpowiednik działania -Ti -Uopcji trussnarzędzia Solaris w systemie Linux.

Służą one do określenia funkcji systemowej ( -T) lub funkcji bibliotecznej ( -U), która wywołana przez śledzoną aplikację spowoduje jej zatrzymanie.

Lub, inaczej mówiąc, chciałbym, aby każdy proces uruchamiany przez śledzoną aplikację został zatrzymany (tak jakby został zabity przez SIGSTOP), jak tylko wykona dane wywołanie systemowe lub wywołanie funkcji biblioteki współużytkowanej.

stracea ltracew systemie Linux zapewniają większość funkcji systemu Solaris truss, ale wydaje się, że nie robią tego.

Na przykład:

truss -f -T open cmd

Byłoby tak strace -f cmd, gdyby proces wykonujący cmdlub którykolwiek z jego potomków wykonał jakieś openwywołanie systemowe, zostałoby natychmiast zatrzymane (i mogę wznowić je później według mojej wygody)

W niektórych przypadkach mogłem użyć gdb's' catch syscall, ale szukałem rozwiązania, które może wygodnie śledzić rozwidlenia i kontynuować robienie tego dla wszystkich rozwidlonych procesów i kontynuować to nawet po execves.

Wydaje mi się, że pamiętam jakieś narzędzie, które daje tę samą funkcjonalność, nawet jedną (lub opcje tego samego narzędzia) dla aplikacji jednoetapowych między niektórymi wystąpieniami niektórych syscall zdalnie tak, ale moja pamięć mnie zawodzi, nawet nie jestem pewien to było na Linuksie.

Stéphane Chazelas
źródło
1
Naprawdę nie jest to odpowiedź na twoje pytanie, ale gdb ma kilka opcji śledzenia forksów, po prostu nie wyklucza execve. Nadal jednak wykonuje tylko jeden proces na raz, co prawdopodobnie jest przełomowe, jeśli szukasz funkcji przypominającej strace, ale pomyślałem, że wspomnę o tym na wszelki wypadek.
Bratchley,
@JoelDavis, dzięki. I wygląda na to, że może to również nastąpić po exec, ( follow-exec-mode), eksperymentuję z tym. Nie odpowiada ściśle na pytanie, ale może być wystarczająco dobry na to, czego potrzebuję.
Stéphane Chazelas
Jeśli rozumiem twoje pytanie, szukasz sposobu na śledzenie, dopóki nie pojawi się określony sygnał, a następnie zatrzymaj śledzenie, nie zatrzymuj ani nie zabijaj aplikacji, którą śledzisz w jakikolwiek sposób, prawda?
slm
@slm, nie, chcę, aby proces rozpoczęty przez śledzoną aplikację został zatrzymany (tak jakby został zabity przez SIGSTOP), jak tylko wykona dane wywołanie systemowe. Dodałem link do strony trusspodręcznika Solaris .
Stéphane Chazelas,
Pozwól mi upewnić się, że rozumiem poprawnie. Potrzebujesz sposobu na zatrzymanie procesu, gdy nastąpi określone wywołanie systemowe. Czy to jest poprawne?
sparticvs

Odpowiedzi:

3

Zgodnie z moją najlepszą wiedzą nie można tego zrobić za stracepomocą ptracefunkcji używanej wewnętrznie SIGSTOPlub SIGINTpodczas połączeń.

EDYTOWAĆ:

Wstawiłem to proste rozwiązanie do ministrace , więc kodowanie nie jest wymagane.

Moim proponowanym rozwiązaniem, jeśli nie jest wymagana cała funkcjonalność strace, byłoby zmodyfikowanie ministrace - co znalazłem tutaj Napisz sobie strace w 70 liniach kodu .

W programie One Shot można dodać dwie linie przed następującym kodem:

if (wait_for_syscall(child) != 0) break;

Pseudo kod:

if(syscall == SYS_write)
    do {
        char str[4];
        gets(str);  // waits until enter to continue    
    } while(0);

Nic z tego nie powiedziałem, te ostatnie kroki należy do ciebie.

Daniël W. Crompton
źródło
Dzięki. Działa i ten link jest bardzo przydatny. Jednak (co zrozumiałe w kilku wierszach kodu), nie wykonuje dekodowania arg, tak jak robi to gdb / strace, więc nie byłoby to przydatne w moim celu. Pokazuje jednak, że łatwo to zrobić. W końcu wybrałem gdb, ale wygląda na to, że łatanie ścieżki dla tej funkcji byłoby stosunkowo łatwe. Pozostawienie pytania otwartego, ponieważ podejrzewam, że istnieje już takie polecenie. Kiedy będę miał czas, przyjrzę się python-ptrace.
Stéphane Chazelas
Nie ma za co! Rozszerzyłem nieco implementację, więc możliwe byłoby odwołanie się do syscall według identyfikatora i nazwy. Znowu było fajnie grać z ptrace.
Daniël W. Crompton