xref: /aosp_15_r20/external/bcc/examples/lua/uprobe-tailkt.lua (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1*387f9dfdSAndroid Build Coastguard Worker#!/usr/bin/env bcc-lua
2*387f9dfdSAndroid Build Coastguard Worker--[[
3*387f9dfdSAndroid Build Coastguard WorkerCopyright 2016 Marek Vavrusa <[email protected]>
4*387f9dfdSAndroid Build Coastguard Worker
5*387f9dfdSAndroid Build Coastguard WorkerLicensed under the Apache License, Version 2.0 (the "License");
6*387f9dfdSAndroid Build Coastguard Workeryou may not use this file except in compliance with the License.
7*387f9dfdSAndroid Build Coastguard WorkerYou may obtain a copy of the License at
8*387f9dfdSAndroid Build Coastguard Worker
9*387f9dfdSAndroid Build Coastguard Workerhttp://www.apache.org/licenses/LICENSE-2.0
10*387f9dfdSAndroid Build Coastguard Worker
11*387f9dfdSAndroid Build Coastguard WorkerUnless required by applicable law or agreed to in writing, software
12*387f9dfdSAndroid Build Coastguard Workerdistributed under the License is distributed on an "AS IS" BASIS,
13*387f9dfdSAndroid Build Coastguard WorkerWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*387f9dfdSAndroid Build Coastguard WorkerSee the License for the specific language governing permissions and
15*387f9dfdSAndroid Build Coastguard Workerlimitations under the License.
16*387f9dfdSAndroid Build Coastguard Worker]]
17*387f9dfdSAndroid Build Coastguard Worker-- Trace operations on keys matching given pattern in KyotoTycoon daemon.
18*387f9dfdSAndroid Build Coastguard Worker-- This can show you if certain keys were modified or read during the lifetime
19*387f9dfdSAndroid Build Coastguard Worker-- even if KT doesn't support this. It also shows how to attach to C++ mangled symbols.
20*387f9dfdSAndroid Build Coastguard Workerlocal ffi = require('ffi')
21*387f9dfdSAndroid Build Coastguard Workerlocal bpf = require('bpf')
22*387f9dfdSAndroid Build Coastguard Workerlocal S = require('syscall')
23*387f9dfdSAndroid Build Coastguard Workerlocal function help(err)
24*387f9dfdSAndroid Build Coastguard Worker	print(string.format('%s [get|set] [key]', arg[0]))
25*387f9dfdSAndroid Build Coastguard Worker	if err then print('error: '..err) end
26*387f9dfdSAndroid Build Coastguard Worker	os.exit(1)
27*387f9dfdSAndroid Build Coastguard Workerend
28*387f9dfdSAndroid Build Coastguard Worker-- Accept the same format as ktremotemgr for clarity: <get|set> <key>
29*387f9dfdSAndroid Build Coastguard Workerlocal writeable, watch_key, klen = 'any', arg[2] or '*', 80
30*387f9dfdSAndroid Build Coastguard Workerif     arg[1] == 'get' then writeable = 0
31*387f9dfdSAndroid Build Coastguard Workerelseif arg[1] == 'set' then writeable = 1
32*387f9dfdSAndroid Build Coastguard Workerelseif arg[1] == '-h' or arg[1] == '--help' then help()
33*387f9dfdSAndroid Build Coastguard Workerelseif arg[1] and arg[1] ~= 'any' then
34*387f9dfdSAndroid Build Coastguard Worker	help(string.format('bad cmd: "%s"', arg[1]))
35*387f9dfdSAndroid Build Coastguard Workerend
36*387f9dfdSAndroid Build Coastguard Workerif watch_key ~= '*' then klen = #watch_key end
37*387f9dfdSAndroid Build Coastguard Worker
38*387f9dfdSAndroid Build Coastguard Worker-- Find a good entrypoint that has both key and differentiates read/write in KT
39*387f9dfdSAndroid Build Coastguard Worker-- That is going to serve as an attachment point for BPF program
40*387f9dfdSAndroid Build Coastguard Worker-- ABI: bool accept(void *this, const char* kbuf, size_t ksiz, Visitor* visitor, bool writable)
41*387f9dfdSAndroid Build Coastguard Workerlocal key_type = string.format('char [%d]', klen)
42*387f9dfdSAndroid Build Coastguard Workerlocal probe = bpf.uprobe('/usr/local/bin/ktserver:kyotocabinet::StashDB::accept',
43*387f9dfdSAndroid Build Coastguard Workerfunction (ptregs)
44*387f9dfdSAndroid Build Coastguard Worker	-- Watch either get/set or both
45*387f9dfdSAndroid Build Coastguard Worker	if writeable ~= 'any' then
46*387f9dfdSAndroid Build Coastguard Worker		if ptregs.parm5 ~= writeable then return end
47*387f9dfdSAndroid Build Coastguard Worker	end
48*387f9dfdSAndroid Build Coastguard Worker	local line = ffi.new(key_type)
49*387f9dfdSAndroid Build Coastguard Worker	ffi.copy(line, ffi.cast('char *', ptregs.parm2))
50*387f9dfdSAndroid Build Coastguard Worker	-- Check if we're looking for specific key
51*387f9dfdSAndroid Build Coastguard Worker	if watch_key ~= '*' then
52*387f9dfdSAndroid Build Coastguard Worker		if ptregs.parm3 ~= klen then return false end
53*387f9dfdSAndroid Build Coastguard Worker		if line ~= watch_key then return false end
54*387f9dfdSAndroid Build Coastguard Worker	end
55*387f9dfdSAndroid Build Coastguard Worker	print('%s write:%d\n', line, ptregs.parm5)
56*387f9dfdSAndroid Build Coastguard Workerend, false, -1, 0)
57*387f9dfdSAndroid Build Coastguard Worker-- User-space part of the program
58*387f9dfdSAndroid Build Coastguard Workerlocal ok, err = pcall(function()
59*387f9dfdSAndroid Build Coastguard Worker	local log = bpf.tracelog()
60*387f9dfdSAndroid Build Coastguard Worker	print('            TASK-PID   CPU#         TIMESTAMP  FUNCTION')
61*387f9dfdSAndroid Build Coastguard Worker	print('               | |      |               |         |')
62*387f9dfdSAndroid Build Coastguard Worker	while true do
63*387f9dfdSAndroid Build Coastguard Worker		print(log:read())
64*387f9dfdSAndroid Build Coastguard Worker	end
65*387f9dfdSAndroid Build Coastguard Workerend)
66