SlideShare a Scribd company logo
1 of 68
Download to read offline
Мало и для
vanilla Lua
и для LuaJIT
Хорошо в
игростроении
Отсутствие
тулинга >
ограничивает
доступную
экспертизу
Мало тулинга в
экосистеме Луа
• Поддержка синтаксиса, навигации и рефакторинг в редакторе;
• Пакетный менеджер и живое сообщество вокруг него;
• Отладчик, желательно в интегрированной среде;
• Инструменты для анализа производительности, желательно -
доступные из редактора;
• Тестирование, желательно из редактора;
• Статический анализатор;
• Фаззинг.
• Lua 5.2/5.3/5.4
• LuaJIT 2.1
• Moonscript, Terra, Nelua, Ravi, MetaLua,
MoonSharp, Luau etc.
• Очень быстрая NoSQL СУБД с сервером приложений
• Открытый код ядра, есть компоненты closed source (в
коммерческой версии)
• Способность обрабатывать огромное кол-во одновременных
подключений
• Соответствие ACID
• Отказоустойчивость и масштабируемость (репликация,
шардинг)
• Кооперативная многозадачность, неблокирующие операции
IO (включая работу с внешними сервисами и файловой
системой)
Файбер (fiber) – он как сопрограмма
(coroutine) только файбер 
• Файбер (fiber)
• Легковесная нить исполнения, реализующая
кооперативную многозадачность
• Кооперативная многозадачность
• Следующая задача выполняется после того, как
текущая объявит о передаче управления
Goto Definition
Diagnostics
Auto Completion
Возможно посредством
формата EmmyLua/Sumneko
Возможно посредством
формата EmmyLua/Sumneko
$HOME/.vscode-server/extensions/sumneko.lua-
2.6.0/server/meta/LuaJIT en-us utf8/ffi.lua
---@meta
---@class ffi.namespace*: table
---@class ffi.cdecl*: string
---@class ffi.ctype*: userdata
local ctype
---@class ffi.cdata*: userdata
---@alias ffi.ct* ffi.cdecl*|ffi.ctype*|ffi.cdata*
---@class ffi.cb*: userdata
local cb
---@class ffi.VLA*: userdata
---@class ffi.VLS*: userdata
---@version JIT
---@class ffilib
---@field C ffi.namespace*
---@field os string
---@field arch string
local ffi = {}
---@param def string
function ffi.cdef(def) end
---@param name string
---@param global? boolean
---@return ffi.namespace* clib
---@nodiscard
function ffi.load(name, global) end
---@param ct ffi.ct*
---@param nelem? integer
---@param init? any
---@return ffi.cdata* cdata
---@nodiscard
Tarantool Tarantool
describe('Busted unit testing framework', function()
describe('should be awesome', function()
it('should be easy to use', function()
assert.truthy('Yup.')
end)
it('should have lots of features', function()
-- deep check comparisons!
assert.same({ table = 'great'}, { table = 'great' })
-- or check by reference!
assert.is_not.equals({ table = 'great'}, { table = 'great'})
assert.falsy(nil)
assert.error(function() error('Wat') end)
end)
it('should provide some shortcuts to common functions', function()
assert.unique({{ thing = 1 }, { thing = 2 }, { thing = 3 }})
end)
it('should have mocks and spies for functional tests', function()
local thing = require('thing_module')
spy.spy_on(thing, 'greet')
thing.greet('Hi!')
http://olivinelabs.com/busted/
#!/usr/bin/tarantool
local tap = require('tap')
test = tap.test("my test name")
test:plan(2)
test:ok(2 * 2 == 4, "2 * 2 is 4")
test:test("some subtests for test2", function(test)
test:plan(2)
test:is(2 + 2, 4, "2 + 2 is 4")
test:isnt(2 + 3, 4, "2 + 3 is not 4")
end)
test:check()
Tarantool
https://www.tarantool.io/ru/d
oc/latest/reference/reference
_lua/tap/
-- test/feature_test.lua
local t = require('luatest')
local g = t.group('feature')
-- Tests. All properties with name staring with `test` are treated as
test cases.
g.test_example_1 = function() ... end
g.test_example_n = function() ... End
-- Define parametrized groups
local pg = t.group('pgroup', {{engine = 'memtx'}, {engine = 'vinyl'}})
pg.test_example_3 = function(cg)
-- Use cg.params here
box.schema.space.create('test', {
engine = cg.params.engine,
})
end
-- Hooks can be specified for one parameter
pg.before_all({engine = 'memtx'}, function() ... end)
pg.before_each({engine = 'memtx'}, function() ... end)
Tarantool
https://github.com/tarantool/l
uatest/
local function sum_up_to(n)
local sum = 0
for i = 1, n do
sum = sum + i
end
return sum
end
property 'sum of numbers is equal to (n + 1) * n / 2' {
generators = { int(100) },
check = function(n)
return sum_up_to(n) == (n + 1) * n / 2
end
}
https://github.com/luc-tielen/lua-quickcheck
Lua ---@alias hookmask string
---|+'"c"' # Calls hook when Lua calls a function.
---|+'"r"' # Calls hook when Lua returns from a function.
---|+'"l"' # Calls hook when Lua enters a new line of
code.
---
---Sets the given function as a hook.
---
---[View documents](command:extension.lua.doc?["en-
us/51/manual.html/pdf-debug.sethook"])
---
---@overload fun(hook: function, mask: hookmask, count?:
integer)
---@param thread thread
---@param hook async fun()
---@param mask hookmask
---@param count? Integer
function debug.sethook(thread, hook, mask, count) end
Lua ---@param co? thread
---@return function hook
---@return string mask
---@return integer count
---@nodiscard
function debug.gethook(co) end
---@alias infowhat string
---|+'"n"' # `name` and `namewhat`
---|+'"S"' # `source`, `short_src`, `linedefined`,
`lastlinedefined`, and `what`
---|+'"l"' # `currentline`
---|+'"t"' # `istailcall`
---|+'"u"' # `nups`, `nparams`, and `isvararg`
---|+'"f"' # `func`
---|+'"L"' # `activelines`
Lua ---
---Returns a table with information about a function.
---
---[View documents](command:extension.lua.doc?["en-
us/51/manual.html/pdf-debug.getinfo"])
---
---@overload fun(f: integer|function, what?:
infowhat):debuginfo
---@param thread thread
---@param f integer|async fun()
---@param what? infowhat
---@return debuginfo
---@nodiscard
function debug.getinfo(thread, f, what) end
Lua ---
---Assigns the `value` to the local variable with index
`local` of the function at `level` of the stack.
---
---[View documents](command:extension.lua.doc?["en-
us/51/manual.html/pdf-debug.setlocal"])
---
---@overload fun(level: integer, index: integer, value:
any):string
---@param thread thread
---@param level integer
---@param index integer
---@param value any
---@return string name
function debug.setlocal(thread, level, index, value) end
Lua ---
---Returns the name and the value of the local variable
with index `local` of the function at level `f` of the
stack.
---
---[View documents](command:extension.lua.doc?["en-
us/51/manual.html/pdf-debug.getlocal"])
---
---@overload fun(f: integer|async fun(), index:
integer):string, any
---@param thread thread
---@param f integer|async fun()
---@param index integer
---@return string name
---@return any value
---@nodiscard
function debug.getlocal(thread, f, index) end
Lua
---
---Returns the name and the value of the upvalue with
index `up` of the function.
---
---[View documents](command:extension.lua.doc?["en-
us/51/manual.html/pdf-debug.getupvalue"])
---
---@param f async fun()
---@param up integer
---@return string name
---@return any value
---@nodiscard
function debug.getupvalue(f, up) end
Lua ---
---Returns a string with a traceback of the call stack.
The optional message string is appended at the beginning
of the traceback.
---
---[View documents](command:extension.lua.doc?["en-
us/51/manual.html/pdf-debug.traceback"])
---
---@overload fun(message?: any, level?: integer): string
---@param thread thread
---@param message? any
---@param level? integer
---@return string message
---@nodiscard
function debug.traceback(thread, message, level) end
Debug API:
local loadFunct = assert( loadfile(fileToExec) )
debug.sethook(covHandler, "l" )
-- Workaround: coroutines require us to sethook again.
local oldCreate = coroutine.create
coroutine.create = function( coFunct )
return oldCreate( function(...)
debug.sethook(covHandler, "l" )
return coFunct(unpack(arg))
end)
end
loadFunct() -- run the main program
M.stop()
function M.stop()
debug.sethook()
…
end
end
Debug API: function traceback ()
local level = 1
while true do
local info = debug.getinfo(level, "Sl")
if not info then break end
if info.what == "C" then -- is a C function?
print(level, "C function")
else -- a Lua function
print(string.format("[%s]:%d",
info.short_src,
info.currentline))
end
level = level + 1
end
end
`n´ selects fields name and namewhat
`f´ selects field func
`S´ selects fields source, short_src,
what, and linedefined
`l´ selects field currentline
`u´ selects field nup
• gperftools, callgrind покажут граф
вызовов на уровне Си
• jit.p позволит собрать граф вызовов
в LuaJIT
• Но никто не соберёт всё вместе
• Строчный хук позволяет собрать профиль исполнения
• Тайминги будут неверные…
• … но счетчикам строк верить можно
• Luacov - https://github.com/keplerproject/luacov
****0 local interval_mt = {
new = interval_new,
}
****0 return setmetatable(
{
new = datetime_new,
interval = setmetatable(interval_mt, interval_mt),
now = datetime_now,
is_datetime = is_datetime,
****0 }, {}
)
====================================================================
Summary
====================================================================
File Hits Missed Coverage
-----------------------------------------
builtin/datetime.lua 515 76 87.14%
-----------------------------------------
Total 515 76 87.14%
https://github.com/tarantool/tarantool/
wiki/How-to-generate-Lua-coverage-
report-for-built-in-module%3F
• Luatrace - https://github.com/geoffleyland/luatrace
“luatrace is a Lua module that collects information about
what your code is doing and how long it takes, and can
analyse that information to generate profile and coverage
reports.
luatrace adds a layer on top of Lua's debug hooks to make
it easier to collect information for profiling and coverage
analysis. luatrace traces of every line executed, not just
calls.
luatrace can trace through coroutine resumes and yields,
and through xpcalls, pcalls and errors. On some platforms it
uses high resolution timers to collect times of the order of
nanoseconds.”
https://github.com/tarantool/luajit/tree/fckxor
g/gh-5688-cli-for-memprof-parse
https://github.com/tarantool/luajit/tree/shishqa
/gh-781-platform-and-lua-profiler
Lua – язык, с динамической типизацией
Нет проверок времени компиляции
Но можно использовать внешний линтер
для статического анализа кода
std = "luajit"
globals = {"box", "_TARANTOOL", "tonumber64"}
ignore = {
-- Accessing an undefined field of a global variable
<debug>.
"143/debug",
-- Accessing an undefined field of a global variable
<string>.
"143/string",
-- Accessing an undefined field of a global variable
<table>.
"143/table",
-- Unused argument <self>.
"212/self",
-- Redefining a local variable.
"411",
-- Redefining an argument.
"412",
-- line contains only whitespace
"611",
}
include_files = {
"**/*.lua",
}
exclude_files = {
"build*/**/*.lua",
-- Third-party source code.
"test-run/**/*.lua",
".rocks/**/*.lua",
".git/**/*.lua",
}
std = "tarantool"
include_files = {
'**/*.lua',
'*.luacheckrc',
'*.rockspec'
}
exclude_files = {
'.rocks/',
'tmp/'
}
max_line_length = 120
https://github.com/tarantool/tarantool/wiki/How-to-verify-all-modified-lua-files-via-luachecks%3F
require('checks')
local function get_stat(uri, opts)
checks('string', {timeout =
'?number'})
end
get_stat()
-- error: bad argument #1 to get_stat
(string expected, got nil)
get_stat('localhost', {timeuot = 1})
-- error: unexpected argument opts.timeuot
to get_stat
13
get_stat('localhost', {timeuot = 1})
-- ^^ typo
-- No error, but does not work as expected
-- Still bad
https://github.com/tarantool/checks
• https://teal-playground.netlify.app/
• https://github.com/teal-language/teal-
types/tree/master/types/penlight/pl
• https://github.com/teal-language/vscode-teal
• https://github.com/teal-language/vim-teal
Teal –
local ltn12 = require("ltn12")
local Sink = ltn12.Sink
local Source = ltn12.Source
local record socket
record TCP
-- master methods
bind: function(TCP, string, integer)
connect: function(TCP, string, integer): integer, string
listen: function(TCP, integer): integer, string
-- client methods
getpeername: function(TCP): string, integer
enum TCPReceivePattern
"*l"
"*a"
end
enum TCPReceiveError
"closed"
"timeout"
end
receive: function(TCP, TCPReceivePattern|integer, string):
string, TCPReceiveError
https://github.com/teal-language/teal-
types/blob/master/types/luasocket/socket.d.tl
• Нет готового решения с удобным отладчиком
• Есть отладчик в Redis как артефакт поддержки в
ZeroBrane Studio Павла Ключенко
• Есть популярный модуль Mobdebug того же Павла
Ключенко
• Развитие RemDebug;
• Mobdebug можно поднять почти везде, где есть LuaSocket;
• Есть надежды зайти через VSCode Debug Adapter
API
• https://github.com/devcat-studio/VSCodeLuaDebug
• форк https://github.com/microsoft/vscode-mono-debug
• https://github.com/BeamNG/VSCodeLuaDebug
https://luarocks.org/modules/3scale/debugger
Basically Vscode-debuggee.lua drops the speed of running Lua
programs because it implements the breakpoint mechanism
using debug.sethook.
This performance degradation can be overcome by applying a
simple patch to the Lua VM.
Download:
lua 5.1.5 : Patch, Code
lua 5.3.4 : Patch, Code
https://marketplace.visualstudio.com/items?itemName=devCAT.lua-debug
Тимур Сафин

More Related Content

What's hot

Something about Golang
Something about GolangSomething about Golang
Something about GolangAnton Arhipov
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Sergey Platonov
 
Язык параллельного программирования Intel Cilk Plus
Язык параллельного программирования Intel Cilk PlusЯзык параллельного программирования Intel Cilk Plus
Язык параллельного программирования Intel Cilk PlusMikhail Kurnosov
 
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"Fwdays
 
Антон Полухин, Немного о Boost
Антон Полухин, Немного о BoostАнтон Полухин, Немного о Boost
Антон Полухин, Немного о BoostSergey Platonov
 
Лекция 7. Язык параллельного программирования Intel Cilk Plus
Лекция 7. Язык параллельного программирования Intel Cilk PlusЛекция 7. Язык параллельного программирования Intel Cilk Plus
Лекция 7. Язык параллельного программирования Intel Cilk PlusMikhail Kurnosov
 
08 - Hadoop. Алгоритмы на графах в MapReduce
08 - Hadoop. Алгоритмы на графах в MapReduce08 - Hadoop. Алгоритмы на графах в MapReduce
08 - Hadoop. Алгоритмы на графах в MapReduceRoman Brovko
 
06 - Hadoop. Java API и Hadoop Streaming
06 - Hadoop. Java API и Hadoop Streaming06 - Hadoop. Java API и Hadoop Streaming
06 - Hadoop. Java API и Hadoop StreamingRoman Brovko
 
Reform: путь к лучшему ORM
Reform: путь к лучшему ORMReform: путь к лучшему ORM
Reform: путь к лучшему ORMBadoo Development
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловSergey Platonov
 
Лекция 12 (часть 1): Языки программирования семейства PGAS: Cray Chapel
Лекция 12 (часть 1): Языки программирования семейства PGAS: Cray ChapelЛекция 12 (часть 1): Языки программирования семейства PGAS: Cray Chapel
Лекция 12 (часть 1): Языки программирования семейства PGAS: Cray ChapelMikhail Kurnosov
 
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Python Meetup
 
13 - Hadoop. Парадигма Spark
13 - Hadoop. Парадигма Spark13 - Hadoop. Парадигма Spark
13 - Hadoop. Парадигма SparkRoman Brovko
 
Язык параллельного программирования Cray Chapel
Язык параллельного программирования Cray ChapelЯзык параллельного программирования Cray Chapel
Язык параллельного программирования Cray ChapelMikhail Kurnosov
 
RDSDataSource: Promises
RDSDataSource: PromisesRDSDataSource: Promises
RDSDataSource: PromisesRAMBLER&Co
 
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Ontico
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковSergey Platonov
 
DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6Dmitry Soshnikov
 
Эффективное программирование на NodeJS
Эффективное программирование на NodeJSЭффективное программирование на NodeJS
Эффективное программирование на NodeJSYura Bogdanov
 

What's hot (20)

Something about Golang
Something about GolangSomething about Golang
Something about Golang
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 
Язык параллельного программирования Intel Cilk Plus
Язык параллельного программирования Intel Cilk PlusЯзык параллельного программирования Intel Cilk Plus
Язык параллельного программирования Intel Cilk Plus
 
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
Aleksei Milovidov "Let's optimize one aggregate function in ClickHouse"
 
Антон Полухин, Немного о Boost
Антон Полухин, Немного о BoostАнтон Полухин, Немного о Boost
Антон Полухин, Немного о Boost
 
Парсим CSS
Парсим CSSПарсим CSS
Парсим CSS
 
Лекция 7. Язык параллельного программирования Intel Cilk Plus
Лекция 7. Язык параллельного программирования Intel Cilk PlusЛекция 7. Язык параллельного программирования Intel Cilk Plus
Лекция 7. Язык параллельного программирования Intel Cilk Plus
 
08 - Hadoop. Алгоритмы на графах в MapReduce
08 - Hadoop. Алгоритмы на графах в MapReduce08 - Hadoop. Алгоритмы на графах в MapReduce
08 - Hadoop. Алгоритмы на графах в MapReduce
 
06 - Hadoop. Java API и Hadoop Streaming
06 - Hadoop. Java API и Hadoop Streaming06 - Hadoop. Java API и Hadoop Streaming
06 - Hadoop. Java API и Hadoop Streaming
 
Reform: путь к лучшему ORM
Reform: путь к лучшему ORMReform: путь к лучшему ORM
Reform: путь к лучшему ORM
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
Лекция 12 (часть 1): Языки программирования семейства PGAS: Cray Chapel
Лекция 12 (часть 1): Языки программирования семейства PGAS: Cray ChapelЛекция 12 (часть 1): Языки программирования семейства PGAS: Cray Chapel
Лекция 12 (часть 1): Языки программирования семейства PGAS: Cray Chapel
 
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
Быстрые конструкции в Python - Олег Шидловский, Python Meetup 26.09.2014
 
13 - Hadoop. Парадигма Spark
13 - Hadoop. Парадигма Spark13 - Hadoop. Парадигма Spark
13 - Hadoop. Парадигма Spark
 
Язык параллельного программирования Cray Chapel
Язык параллельного программирования Cray ChapelЯзык параллельного программирования Cray Chapel
Язык параллельного программирования Cray Chapel
 
RDSDataSource: Promises
RDSDataSource: PromisesRDSDataSource: Promises
RDSDataSource: Promises
 
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
 
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворковНикита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
 
DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6
 
Эффективное программирование на NodeJS
Эффективное программирование на NodeJSЭффективное программирование на NodeJS
Эффективное программирование на NodeJS
 

Similar to Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool

Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool Modules, Tarantool Meetup 2016-08-25Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool Modules, Tarantool Meetup 2016-08-25Roman Tsisyk
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerAnton Arhipov
 
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)Ontico
 
Язык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистовЯзык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистовAndrew Shitov
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Sergey Platonov
 
Командная разработка “толстых клиентов”
Командная разработка “толстых клиентов”Командная разработка “толстых клиентов”
Командная разработка “толстых клиентов”Open-IT
 
Константин Осипов (Mail.Ru)
Константин Осипов (Mail.Ru)Константин Осипов (Mail.Ru)
Константин Осипов (Mail.Ru)Ontico
 
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...Ontico
 
Cобачники против кинофобов
Cобачники против кинофобовCобачники против кинофобов
Cобачники против кинофобовLidiya Myalkina
 
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptСтажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptSmartTools
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?Vasil Remeniuk
 
Batch processing in rails
Batch processing in railsBatch processing in rails
Batch processing in railssergeymoiseev
 
Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPython Meetup
 
Hacking PostgreSQL. Обзор исходного кода
Hacking PostgreSQL. Обзор исходного кодаHacking PostgreSQL. Обзор исходного кода
Hacking PostgreSQL. Обзор исходного кодаAnastasia Lubennikova
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Yandex
 
Clojure – есть ли жизнь после Java
Clojure – есть ли жизнь после JavaClojure – есть ли жизнь после Java
Clojure – есть ли жизнь после JavaOlim Saidov
 

Similar to Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool (20)

Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool Modules, Tarantool Meetup 2016-08-25Tarantool Modules, Tarantool Meetup 2016-08-25
Tarantool Modules, Tarantool Meetup 2016-08-25
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profiler
 
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
Осваиваем Tarantool 1.6 / Евгений Шадрин (Sberbank Digital Ventures)
 
Язык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистовЯзык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистов
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
 
Erlang tasty & useful stuff
Erlang tasty & useful stuffErlang tasty & useful stuff
Erlang tasty & useful stuff
 
Командная разработка “толстых клиентов”
Командная разработка “толстых клиентов”Командная разработка “толстых клиентов”
Командная разработка “толстых клиентов”
 
Константин Осипов (Mail.Ru)
Константин Осипов (Mail.Ru)Константин Осипов (Mail.Ru)
Константин Осипов (Mail.Ru)
 
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
Практика совместного использования Lua и C в opensource спам-фильтре Rspamd /...
 
UWDC 2013, Yii2
UWDC 2013, Yii2UWDC 2013, Yii2
UWDC 2013, Yii2
 
Cocos2d-x и Lua
Cocos2d-x и LuaCocos2d-x и Lua
Cocos2d-x и Lua
 
Cобачники против кинофобов
Cобачники против кинофобовCобачники против кинофобов
Cобачники против кинофобов
 
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptСтажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?
 
Суперсилы Chrome developer tools
Суперсилы Chrome developer toolsСуперсилы Chrome developer tools
Суперсилы Chrome developer tools
 
Batch processing in rails
Batch processing in railsBatch processing in rails
Batch processing in rails
 
Pyton – пробуем функциональный стиль
Pyton – пробуем функциональный стильPyton – пробуем функциональный стиль
Pyton – пробуем функциональный стиль
 
Hacking PostgreSQL. Обзор исходного кода
Hacking PostgreSQL. Обзор исходного кодаHacking PostgreSQL. Обзор исходного кода
Hacking PostgreSQL. Обзор исходного кода
 
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
Руслан Гроховецкий "Как Python стал делать погоду в Яндексе"
 
Clojure – есть ли жизнь после Java
Clojure – есть ли жизнь после JavaClojure – есть ли жизнь после Java
Clojure – есть ли жизнь после Java
 

More from Timur Safin

Go vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoFGo vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoFTimur Safin
 
Новый InterSystems: open-source, митапы, хакатоны
Новый InterSystems: open-source, митапы, хакатоныНовый InterSystems: open-source, митапы, хакатоны
Новый InterSystems: open-source, митапы, хакатоныTimur Safin
 
Native json in the Cache' ObjectScript 2016.*
Native json in the Cache' ObjectScript 2016.*Native json in the Cache' ObjectScript 2016.*
Native json in the Cache' ObjectScript 2016.*Timur Safin
 
InterSystems iKnow and Twitter API
InterSystems iKnow and Twitter APIInterSystems iKnow and Twitter API
InterSystems iKnow and Twitter APITimur Safin
 
Multimodel Database Caché
Multimodel Database CachéMultimodel Database Caché
Multimodel Database CachéTimur Safin
 
Implementation of community package manager
Implementation of community package managerImplementation of community package manager
Implementation of community package managerTimur Safin
 
Новости Global summit 2015
Новости Global summit 2015Новости Global summit 2015
Новости Global summit 2015Timur Safin
 
Approaching package manager
Approaching package managerApproaching package manager
Approaching package managerTimur Safin
 

More from Timur Safin (8)

Go vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoFGo vs C++ - CppRussia 2019 Piter BoF
Go vs C++ - CppRussia 2019 Piter BoF
 
Новый InterSystems: open-source, митапы, хакатоны
Новый InterSystems: open-source, митапы, хакатоныНовый InterSystems: open-source, митапы, хакатоны
Новый InterSystems: open-source, митапы, хакатоны
 
Native json in the Cache' ObjectScript 2016.*
Native json in the Cache' ObjectScript 2016.*Native json in the Cache' ObjectScript 2016.*
Native json in the Cache' ObjectScript 2016.*
 
InterSystems iKnow and Twitter API
InterSystems iKnow and Twitter APIInterSystems iKnow and Twitter API
InterSystems iKnow and Twitter API
 
Multimodel Database Caché
Multimodel Database CachéMultimodel Database Caché
Multimodel Database Caché
 
Implementation of community package manager
Implementation of community package managerImplementation of community package manager
Implementation of community package manager
 
Новости Global summit 2015
Новости Global summit 2015Новости Global summit 2015
Новости Global summit 2015
 
Approaching package manager
Approaching package managerApproaching package manager
Approaching package manager
 

Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool

  • 1.
  • 2.
  • 3.
  • 4. Мало и для vanilla Lua и для LuaJIT Хорошо в игростроении Отсутствие тулинга > ограничивает доступную экспертизу Мало тулинга в экосистеме Луа
  • 5. • Поддержка синтаксиса, навигации и рефакторинг в редакторе; • Пакетный менеджер и живое сообщество вокруг него; • Отладчик, желательно в интегрированной среде; • Инструменты для анализа производительности, желательно - доступные из редактора; • Тестирование, желательно из редактора; • Статический анализатор; • Фаззинг.
  • 6. • Lua 5.2/5.3/5.4 • LuaJIT 2.1 • Moonscript, Terra, Nelua, Ravi, MetaLua, MoonSharp, Luau etc.
  • 7.
  • 8. • Очень быстрая NoSQL СУБД с сервером приложений • Открытый код ядра, есть компоненты closed source (в коммерческой версии) • Способность обрабатывать огромное кол-во одновременных подключений • Соответствие ACID • Отказоустойчивость и масштабируемость (репликация, шардинг) • Кооперативная многозадачность, неблокирующие операции IO (включая работу с внешними сервисами и файловой системой)
  • 9.
  • 10. Файбер (fiber) – он как сопрограмма (coroutine) только файбер  • Файбер (fiber) • Легковесная нить исполнения, реализующая кооперативную многозадачность • Кооперативная многозадачность • Следующая задача выполняется после того, как текущая объявит о передаче управления
  • 11.
  • 12.
  • 17. Возможно посредством формата EmmyLua/Sumneko $HOME/.vscode-server/extensions/sumneko.lua- 2.6.0/server/meta/LuaJIT en-us utf8/ffi.lua ---@meta ---@class ffi.namespace*: table ---@class ffi.cdecl*: string ---@class ffi.ctype*: userdata local ctype ---@class ffi.cdata*: userdata ---@alias ffi.ct* ffi.cdecl*|ffi.ctype*|ffi.cdata* ---@class ffi.cb*: userdata local cb ---@class ffi.VLA*: userdata ---@class ffi.VLS*: userdata ---@version JIT ---@class ffilib ---@field C ffi.namespace* ---@field os string ---@field arch string local ffi = {} ---@param def string function ffi.cdef(def) end ---@param name string ---@param global? boolean ---@return ffi.namespace* clib ---@nodiscard function ffi.load(name, global) end ---@param ct ffi.ct* ---@param nelem? integer ---@param init? any ---@return ffi.cdata* cdata ---@nodiscard
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 25. describe('Busted unit testing framework', function() describe('should be awesome', function() it('should be easy to use', function() assert.truthy('Yup.') end) it('should have lots of features', function() -- deep check comparisons! assert.same({ table = 'great'}, { table = 'great' }) -- or check by reference! assert.is_not.equals({ table = 'great'}, { table = 'great'}) assert.falsy(nil) assert.error(function() error('Wat') end) end) it('should provide some shortcuts to common functions', function() assert.unique({{ thing = 1 }, { thing = 2 }, { thing = 3 }}) end) it('should have mocks and spies for functional tests', function() local thing = require('thing_module') spy.spy_on(thing, 'greet') thing.greet('Hi!') http://olivinelabs.com/busted/
  • 26. #!/usr/bin/tarantool local tap = require('tap') test = tap.test("my test name") test:plan(2) test:ok(2 * 2 == 4, "2 * 2 is 4") test:test("some subtests for test2", function(test) test:plan(2) test:is(2 + 2, 4, "2 + 2 is 4") test:isnt(2 + 3, 4, "2 + 3 is not 4") end) test:check() Tarantool https://www.tarantool.io/ru/d oc/latest/reference/reference _lua/tap/
  • 27. -- test/feature_test.lua local t = require('luatest') local g = t.group('feature') -- Tests. All properties with name staring with `test` are treated as test cases. g.test_example_1 = function() ... end g.test_example_n = function() ... End -- Define parametrized groups local pg = t.group('pgroup', {{engine = 'memtx'}, {engine = 'vinyl'}}) pg.test_example_3 = function(cg) -- Use cg.params here box.schema.space.create('test', { engine = cg.params.engine, }) end -- Hooks can be specified for one parameter pg.before_all({engine = 'memtx'}, function() ... end) pg.before_each({engine = 'memtx'}, function() ... end) Tarantool https://github.com/tarantool/l uatest/
  • 28.
  • 29.
  • 30. local function sum_up_to(n) local sum = 0 for i = 1, n do sum = sum + i end return sum end property 'sum of numbers is equal to (n + 1) * n / 2' { generators = { int(100) }, check = function(n) return sum_up_to(n) == (n + 1) * n / 2 end } https://github.com/luc-tielen/lua-quickcheck
  • 31.
  • 32. Lua ---@alias hookmask string ---|+'"c"' # Calls hook when Lua calls a function. ---|+'"r"' # Calls hook when Lua returns from a function. ---|+'"l"' # Calls hook when Lua enters a new line of code. --- ---Sets the given function as a hook. --- ---[View documents](command:extension.lua.doc?["en- us/51/manual.html/pdf-debug.sethook"]) --- ---@overload fun(hook: function, mask: hookmask, count?: integer) ---@param thread thread ---@param hook async fun() ---@param mask hookmask ---@param count? Integer function debug.sethook(thread, hook, mask, count) end
  • 33. Lua ---@param co? thread ---@return function hook ---@return string mask ---@return integer count ---@nodiscard function debug.gethook(co) end ---@alias infowhat string ---|+'"n"' # `name` and `namewhat` ---|+'"S"' # `source`, `short_src`, `linedefined`, `lastlinedefined`, and `what` ---|+'"l"' # `currentline` ---|+'"t"' # `istailcall` ---|+'"u"' # `nups`, `nparams`, and `isvararg` ---|+'"f"' # `func` ---|+'"L"' # `activelines`
  • 34. Lua --- ---Returns a table with information about a function. --- ---[View documents](command:extension.lua.doc?["en- us/51/manual.html/pdf-debug.getinfo"]) --- ---@overload fun(f: integer|function, what?: infowhat):debuginfo ---@param thread thread ---@param f integer|async fun() ---@param what? infowhat ---@return debuginfo ---@nodiscard function debug.getinfo(thread, f, what) end
  • 35. Lua --- ---Assigns the `value` to the local variable with index `local` of the function at `level` of the stack. --- ---[View documents](command:extension.lua.doc?["en- us/51/manual.html/pdf-debug.setlocal"]) --- ---@overload fun(level: integer, index: integer, value: any):string ---@param thread thread ---@param level integer ---@param index integer ---@param value any ---@return string name function debug.setlocal(thread, level, index, value) end
  • 36. Lua --- ---Returns the name and the value of the local variable with index `local` of the function at level `f` of the stack. --- ---[View documents](command:extension.lua.doc?["en- us/51/manual.html/pdf-debug.getlocal"]) --- ---@overload fun(f: integer|async fun(), index: integer):string, any ---@param thread thread ---@param f integer|async fun() ---@param index integer ---@return string name ---@return any value ---@nodiscard function debug.getlocal(thread, f, index) end
  • 37. Lua --- ---Returns the name and the value of the upvalue with index `up` of the function. --- ---[View documents](command:extension.lua.doc?["en- us/51/manual.html/pdf-debug.getupvalue"]) --- ---@param f async fun() ---@param up integer ---@return string name ---@return any value ---@nodiscard function debug.getupvalue(f, up) end
  • 38. Lua --- ---Returns a string with a traceback of the call stack. The optional message string is appended at the beginning of the traceback. --- ---[View documents](command:extension.lua.doc?["en- us/51/manual.html/pdf-debug.traceback"]) --- ---@overload fun(message?: any, level?: integer): string ---@param thread thread ---@param message? any ---@param level? integer ---@return string message ---@nodiscard function debug.traceback(thread, message, level) end
  • 39. Debug API: local loadFunct = assert( loadfile(fileToExec) ) debug.sethook(covHandler, "l" ) -- Workaround: coroutines require us to sethook again. local oldCreate = coroutine.create coroutine.create = function( coFunct ) return oldCreate( function(...) debug.sethook(covHandler, "l" ) return coFunct(unpack(arg)) end) end loadFunct() -- run the main program M.stop() function M.stop() debug.sethook() … end end
  • 40. Debug API: function traceback () local level = 1 while true do local info = debug.getinfo(level, "Sl") if not info then break end if info.what == "C" then -- is a C function? print(level, "C function") else -- a Lua function print(string.format("[%s]:%d", info.short_src, info.currentline)) end level = level + 1 end end `n´ selects fields name and namewhat `f´ selects field func `S´ selects fields source, short_src, what, and linedefined `l´ selects field currentline `u´ selects field nup
  • 41.
  • 42. • gperftools, callgrind покажут граф вызовов на уровне Си • jit.p позволит собрать граф вызовов в LuaJIT • Но никто не соберёт всё вместе
  • 43. • Строчный хук позволяет собрать профиль исполнения • Тайминги будут неверные… • … но счетчикам строк верить можно • Luacov - https://github.com/keplerproject/luacov
  • 44. ****0 local interval_mt = { new = interval_new, } ****0 return setmetatable( { new = datetime_new, interval = setmetatable(interval_mt, interval_mt), now = datetime_now, is_datetime = is_datetime, ****0 }, {} ) ==================================================================== Summary ==================================================================== File Hits Missed Coverage ----------------------------------------- builtin/datetime.lua 515 76 87.14% ----------------------------------------- Total 515 76 87.14% https://github.com/tarantool/tarantool/ wiki/How-to-generate-Lua-coverage- report-for-built-in-module%3F
  • 45. • Luatrace - https://github.com/geoffleyland/luatrace “luatrace is a Lua module that collects information about what your code is doing and how long it takes, and can analyse that information to generate profile and coverage reports. luatrace adds a layer on top of Lua's debug hooks to make it easier to collect information for profiling and coverage analysis. luatrace traces of every line executed, not just calls. luatrace can trace through coroutine resumes and yields, and through xpcalls, pcalls and errors. On some platforms it uses high resolution timers to collect times of the order of nanoseconds.”
  • 48.
  • 49. Lua – язык, с динамической типизацией Нет проверок времени компиляции Но можно использовать внешний линтер для статического анализа кода
  • 50. std = "luajit" globals = {"box", "_TARANTOOL", "tonumber64"} ignore = { -- Accessing an undefined field of a global variable <debug>. "143/debug", -- Accessing an undefined field of a global variable <string>. "143/string", -- Accessing an undefined field of a global variable <table>. "143/table", -- Unused argument <self>. "212/self", -- Redefining a local variable. "411", -- Redefining an argument. "412", -- line contains only whitespace "611", } include_files = { "**/*.lua", } exclude_files = { "build*/**/*.lua", -- Third-party source code. "test-run/**/*.lua", ".rocks/**/*.lua", ".git/**/*.lua", }
  • 51. std = "tarantool" include_files = { '**/*.lua', '*.luacheckrc', '*.rockspec' } exclude_files = { '.rocks/', 'tmp/' } max_line_length = 120
  • 52.
  • 54.
  • 55. require('checks') local function get_stat(uri, opts) checks('string', {timeout = '?number'}) end get_stat() -- error: bad argument #1 to get_stat (string expected, got nil) get_stat('localhost', {timeuot = 1}) -- error: unexpected argument opts.timeuot to get_stat 13 get_stat('localhost', {timeuot = 1}) -- ^^ typo -- No error, but does not work as expected -- Still bad https://github.com/tarantool/checks
  • 56. • https://teal-playground.netlify.app/ • https://github.com/teal-language/teal- types/tree/master/types/penlight/pl • https://github.com/teal-language/vscode-teal • https://github.com/teal-language/vim-teal
  • 57. Teal – local ltn12 = require("ltn12") local Sink = ltn12.Sink local Source = ltn12.Source local record socket record TCP -- master methods bind: function(TCP, string, integer) connect: function(TCP, string, integer): integer, string listen: function(TCP, integer): integer, string -- client methods getpeername: function(TCP): string, integer enum TCPReceivePattern "*l" "*a" end enum TCPReceiveError "closed" "timeout" end receive: function(TCP, TCPReceivePattern|integer, string): string, TCPReceiveError https://github.com/teal-language/teal- types/blob/master/types/luasocket/socket.d.tl
  • 58.
  • 59. • Нет готового решения с удобным отладчиком • Есть отладчик в Redis как артефакт поддержки в ZeroBrane Studio Павла Ключенко • Есть популярный модуль Mobdebug того же Павла Ключенко • Развитие RemDebug; • Mobdebug можно поднять почти везде, где есть LuaSocket; • Есть надежды зайти через VSCode Debug Adapter API
  • 60.
  • 61.
  • 62.
  • 63. • https://github.com/devcat-studio/VSCodeLuaDebug • форк https://github.com/microsoft/vscode-mono-debug • https://github.com/BeamNG/VSCodeLuaDebug
  • 64.
  • 66. Basically Vscode-debuggee.lua drops the speed of running Lua programs because it implements the breakpoint mechanism using debug.sethook. This performance degradation can be overcome by applying a simple patch to the Lua VM. Download: lua 5.1.5 : Patch, Code lua 5.3.4 : Patch, Code https://marketplace.visualstudio.com/items?itemName=devCAT.lua-debug
  • 67.