Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

UoKit.com Форумы _ UO Pilot _ Логгер-дебаггер для Lua

Автор: DarkMaster 20.5.2018, 14:06

Вобщем озадачился я созданием лога в стиле пилота при использовании луа. Все относительно неплохо реализовывается, однако появилась проблемка, которую решить пока не получилось:
var = var2 + func()
При выводе в лог, естественно, хочется чтобы, как и в пилоте это выражение приняло примерно такой вид:
var(10) = var2(4) + func()(6)
Если с преобразованием переменных особых проблем нет, то как перехватить занчение функции? Тут нужно понимать, что просто вытащить return из функции может не получится, т.к. там тоже может содержаться функция либо это может быть вообще внешняя С-функция и никаких return там не найти и по стаку не пробежаться.

Для затравки smile.gif
Настройки:

Код
local dbg    = {}
dbg.trace    = 1                   -- Отображение стека
dbg.line     = 1                   -- Отображение номеров строк
dbg.code     = 1                   -- Отображение исходного кода
dbg.source   = 1                   -- Отображение источника кода(адрес файла, строка и т.д.)
dbg.source_abs = 0                 -- Абсолютные адреса фалов.
dbg.tab      = 75                  -- Выравнивание исходного кода в символах.
--     стек                 выравнивание     код
--(213)main->                             mycall()
--(213)main->(209)mycall->                file_echo()
--     стек                 выравнивание     код

dbg.file  = {}                   -- Настройки файла лога
dbg.file.enable = 1              -- Включить логирование в файл
dbg.file.path = "lua_log.txt"    -- Путь файла лога
dbg.file.append = 0              -- Дописывать лог (не удалять старый)
dbg.file.handle = nil            -- Хендл файла
dbg.buffer = {}                  -- Буфер с файлами скриптов.

Образец вывода в лог:
Код
(227)main->                                                                mycall()
(227)main->(223)mycall->                                                      mycall2()
(227)main->(223)mycall->(219)mycall2->                                        echo()
(227)main->(223)mycall->(219)mycall2->(214)echo->                              log("123")
(227)main->(223)mycall->(219)mycall2->(215)echo->                              log("321")
(227)main->(223)mycall->(219)mycall2->(216)echo->                          end
(227)main->(223)mycall->(220)mycall2->                                     end
(227)main->(224)mycall->                                                   end
(229)main->                                                                file_test()
(229)main->"lua\test.lua"->(11)file_test->                                     file_test2()
(229)main->"lua\test.lua"->(11)file_test->(8)file_test2->                      file_echo()
(229)main->"lua\test.lua"->(11)file_test->(8)file_test2->(4)file_echo->        log("my file echo")
(229)main->"lua\test.lua"->(11)file_test->(8)file_test2->(5)file_echo->    end
(229)main->"lua\test.lua"->(11)file_test->(9)file_test2->                  end
(229)main->"lua\test.lua"->(12)file_test->                                 end
(231)main->                                                                stop_script()

Это вывод в файл.
log() преобразует немножко лишнего, чем нужно, упрашиваю кнайта сделать доп вывод в лог без форматирования.

Автор: Cockney 20.5.2018, 15:23

1)Запомнить состояние стека до вызова функции
2)Получить его же, после.
3)Разница = результат

Автор: DarkMaster 20.5.2018, 15:44

Цитата
1)Запомнить состояние стека до вызова функции
2)Получить его же, после.
3)Разница = результат

Всмысле? Ну делаю, я, напремер:
var = var2 + math.floor(10.2)
и как я получу результат math.floor(10.2)? Из какого стека? Ну ладно тут еще посчитать можно, но ты же понимаешь, что это не реально созадавать универсальные уравнения. А если неизвестных будет несколько?

Автор: Cockney 20.5.2018, 16:25

1)Lua Debug Library (google)
2)lua_gettop(). Ищи как ее дергать из скриптов, иначе только писать самому длл)

Какие уравнения, о чем ты ? Это обычная раскрутка стека. Вешаешь хук на call/return функции. В хуке отлавливаются и позиция стека перед стартом(возвратом) функции и ее имя. Верти дальше что хочешь.


var1 = math.floor(math.sin(10), 5)

stack :

0)math.floor( )
1) math.sin( )
2) 10
3) 5

Вошли в floor - получили текущую верхушку(0)
Вошли в sin - получили текущую верхушку(1)
Докинули аргумент для sin. Теперь верхушкой становится(2)
Отрабатывает sin. (на его место(1) кладется его же результат)
Стек уменьшился на 1.

0)math.floor( )
1) sinres
2) 5

Теперь отрабатывает floor и на верхушке(0) будет его результат. И так с любой вложенностью.

Автор: DarkMaster 20.5.2018, 16:58

Цитата
Это обычная раскрутка стека. Вешаешь хук на call/return функции. В хуке отлавливаются и позиция стека перед стартом(возвратом) функции и ее имя. Верти дальше что хочешь.

Дык повешано оно уже. Результат то как перехватить?) Ты понимешь, что math.floor() не имеет стека по сути? Ну точнее он там есть внутренний, сишная функция и т.д., но через debug - это будет последнее, что ты увидишь. А значение то где брать?

Автор: Cockney 20.5.2018, 17:25

Второй пункт.

Автор: DarkMaster 20.5.2018, 17:43

Дык это апи с приложением. Как я его перехвачу?

Автор: Cockney 20.5.2018, 20:08

Его не надо перехватывать. Его надо вызывать до и после вызова. По поводу как вызывать я написал в том же пункте.

Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)