PDA

Просмотр полной версии : [Include] TDW RScan - сканер рекурсий



VVWVV
12.05.2017, 18:22
TDW RScan
Описание

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

Документация

Как говорилось выше, основная функциональность библиотеки - поиск рекурсий. Библиотека проверяет все вложенные функции, а также функции вложенные во вложенные функции и т.д., пока не найдёт рекурсию. Количество уровней вложенности ограничено. Это делается для того, чтобы увеличить скорость работы сканера. Тем не менее библиотека представляет возможность изменить данное значение, определив макрос RSCAN_MAX_NESTED_LEVEL до включения библиотеки. Максимальное значение для уровня вложенности - 128. Значение по-умолчанию и рекомендуемое - 32.



Название функции
Описание


RScan_Run
Функция принимает необязательный параметр - адрес функции. Данная функция запускает и инициализирует сканер. Если был передан адрес, то функция запустит сканер только для этого адреса, т.е. другие функции не будут просканированы.


forward public func1();
forward public func2();

main() {
RScan_Run();

goto ___avoid_recursion; // избежать вызов рекурсии
func1();
___avoid_recursion:

}

func1() {
func2();
}

func2() {
func1();
}




addressofex
Дополнительная функция для определения адреса абсолютно любой функции. Принимает вызов функции.


addressofex(somefunc(0,0));





Библиотека имеет зависимость от amx_assembly (http://pro-pawn.ru/showthread.php?15075), однако в скором времени я попытаюсь сделать её автономной.


Скачать

github (https://github.com/TDW-org/samp-include-rscan)

Установка

Перейдите в репозиторий на github (ссылка выше).
Для скачивания на открывшейся странице нажмите на кнопку "Clone or download" (зелёного цвета) и в открывшемся меню - "Download ZIP".
Все файлы библиотеки перемести в папку '/pawno/includes/'.
Скомпилировать изменённые вами скрипты.



Автор: VVWVV (http://pro-pawn.ru/member.php?4348)
Распространяется по лицензии ZLIB.

SooBad
12.05.2017, 18:34
Полезно для тех, кто не использует модификатор от Zeex'a последних версий, аля там вшита возможная компиляция с ключом '-R', определяющая действующую рекурсию.
Хотелось бы задать отдельный вопрос про адреса: крашей нет с этим, при невалидной передаче(зависимость от некоторых критичных инструкций же)? Возможности сейчас проверить просто нет.

Alpano
12.05.2017, 19:07
Интересно)В Том же компиляторе by zeex, мне в консоль выдаёт:

recursion detected: function 40000004!=40000004 indirectly calls itself:
40000004!=40000004 <- ac_OnPlayerStateChange <- 40000004!=40000004
recursion detected: function 40000004/0 directly calls itself
recursion detected: function 40000004*0 indirectly calls itself:
40000004*0 <- AntySH <- 40000004*0
recursion detected: function -40000004 indirectly calls itself:
-40000004 <- GetCoordBonnetVehicleEx <- ac_OnPlayerKeyStateChange <- -40000004

Не будет ли такого же непонятного ответа от Вашего компилятора?) Или принцип поиска рекурсий идентичен?

VVWVV
12.05.2017, 19:28
Интересно)В Том же компиляторе by zeex, мне в консоль выдаёт:
Не будет ли такого же непонятного ответа от Вашего компилятора?) Или принцип поиска рекурсий идентичен?

Нет, принцип работы совсем другой.
http://ihost.pro-pawn.ru/image.php?di=LTNN

Edwin
12.05.2017, 20:02
Шикарно
Раньше поиском рекурсий занимался через компилятор от Трекера. Не сказал бы, что это сильно напряжно, но приходится сначала повозиться.

UPD: А он будет отлавливать, к примеру, таймеры, которые вызывают сами себя?

somebodies
08.06.2017, 02:42
Приветствую. Получил такую строку.


recursion detected: function 4438552 indirectly calls itself
Пробовал использовать функции из библиотеки amx_header по типу GetPublicNameFromIndex, однако не помогло. как получить имя public-функции?

VVWVV
08.06.2017, 11:33
Приветствую. Получил такую строку.


recursion detected: function 4438552 indirectly calls itself
Пробовал использовать функции из библиотеки amx_header по типу GetPublicNameFromIndex, однако не помогло. как получить имя public-функции?

1) Выводится адрес функции, а не индекс.
2) Если функция объявлена с помощью оператора public, то название этой функции будет и в сообщении. Для того чтобы зарегистрировать название функции необходимо написать:


forward public название_функции();



UPD: А он будет отлавливать, к примеру, таймеры, которые вызывают сами себя?

Нет, но в новой версии сделаю.