Piszę concolic engine dla Python za pomocą funkcji sys.settrace()
.Python śledzenie i warunkowe skoki
Głównym zadaniem podczas tego rodzaju wykonywania jest rejestrowanie ograniczeń zmiennych wejściowych. Ograniczenia są niczym innym jak warunkami instrukcji if, które tworzą dwie gałęzie (gałąź "wtedy" i "inna").
Po zakończeniu wykonywania, silnik wybiera ograniczenie i znajduje odpowiednie wartości dla danych wejściowych, tak że wykonanie będzie przebiegać w dół wzdłuż drugiego oddziału (przy wykonaniu x przechodzi do gałęzi 'wtedy', w wykonaniu x + 1 idzie wzdłuż gałęzi "else").
to jest mieć trochę kontekście, dlaczego robię to, co usiłuję zrobić ...
Łącząc settrace()
i moduł dis
, mogę zobaczyć kodu bajtowego każdej linii źródłowej, tuż zanim zostanie wykonany. W ten sposób mogę łatwo zapisać warunki, które pojawiają się podczas wykonywania.
Ale wtedy mam duży problem. Muszę wiedzieć, w którą stronę pójdzie, którą gałąź wykonała egzekucja. Więc jeśli mój kod jest coś takiego:
if x > a:
print x
else:
print a
w pewnym momencie moje śledzenia rzeczą będzie zobaczyć:
t: if x > 0:
następnie interpreter Pythona wykona wtedy i skok (lub nie) gdzieś. I widzę:
t + 1: print x
Więc jest instrukcja t + 1
w branży „następnie” lub w „inny” jeden? Należy pamiętać, że funkcja śledzenia widzi tylko jakiś kod bajtowy w bieżącym bloku.
Wiem dwa sposoby, aby to zrobić. Jednym z nich jest ocena warunku, aby zobaczyć dokładnie, czy jest to prawda czy fałsz. Działa to tylko wtedy, gdy nie ma żadnych skutków ubocznych.
Innym sposobem jest spróbuj spojrzeć i wskaźnik instrukcji pod numerem t + 1
i spróbuj zrozumieć, gdzie jesteśmy w kodzie. Tak właśnie używam, ale to bardzo delikatne, ponieważ na t + 1
mogłem znaleźć się gdzieś zupełnie innym (innym modułem, wbudowaną funkcją, itp.).
Na koniec pytanie, które mam, brzmi: czy istnieje sposób na uzyskanie samego Pythona lub z modułu C/rozszerzenie/cokolwiek, wynik ostatniego warunkowego skoku?
Alternatywnie, czy są dostępne bardziej szczegółowe opcje śledzenia? Coś jak wykonywanie kodu bajtowego po jednym kodzie naraz. Dzięki funkcji settrace()
maksymalna rozdzielczość, jaką otrzymuję, to całe linie kodu źródłowego.
W najgorszym przypadku, myślę, że mogę zmodyfikować interpreter Pythona, aby ujawnić takie informacje, ale zostawiłbym to w ostateczności, z oczywistych powodów.
Widziałem również, że istnieje możliwość zbudowania abstrakcyjnego drzewa składni z kodu, modyfikowania go, kompilowania i uruchamiania. Powinno być możliwe wykorzystanie tego i dodanie bardzo prostej oprzyrządowania (jak wywołanie funkcji na początku każdej gałęzi, która mówi, w którą stronę wypadł). –
Tak, to także możliwość, nie taka, z którą eksperymentowałem. –