Page MenuHomeFreeBSD

lldb lua: Add some helper functions to deal with netinet
Needs ReviewPublic

Authored by thj on Feb 23 2024, 2:18 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sat, May 18, 7:45 AM
Unknown Object (File)
Sun, May 12, 10:51 PM
Unknown Object (File)
Thu, May 9, 10:08 AM
Unknown Object (File)
Thu, May 9, 5:49 AM
Unknown Object (File)
Fri, Apr 26, 3:38 AM
Unknown Object (File)
Sat, Apr 20, 4:53 PM
Unknown Object (File)
Apr 19 2024, 10:22 AM
Unknown Object (File)
Apr 9 2024, 4:26 AM
Subscribers
None

Details

Summary

lldb has enough support to do kernel coredump debugging. lldb multiple
scripting interfaces, most notably in python and lua. The lua interface is less
mature than the python interface, but it is small enough that we are able to
distribute it in the base lldb.

Implement some helper functions for use from lua and offer an explanation of
the lua interface.

This is a first attempt, I'm not supre confident that this is good lua or the
best use of the lldb api. There is a shortage of documentation for this
interface, but I've managed ok from adapting the generated python bindings.

Test Plan

We need to launch lldb for kernel debugging with the kernel symbols and a core
file:

$ lldb --core vmcore.5 kernel-debug/kernel.debug

From the lldb prompt we first need to do an empty script run, otherwise loading
a script will error out:

(lldb) script
>>> quit

Once the interface is initialised we can run a script, this example saved in
example.lua uses the netinet module.

netinet = require("netinet")

if lldb == nil
then
	lldb = savedlldb
	print("restored lldb: " .. tostring(lldb))
else
	savedlldb = lldb
	print("saved lldb: " .. tostring(lldb))
end

for v in netinet:vnet_iter()
do
	print(v)

	print(netinet:vnet_get_V_value("V_tcbinfo", v))

	print(v:GetChildMemberWithName("vnet_data_base"))
	ti = netinet:vnet_get_member_and_cast(
		v, "vnet_entry_tcbinfo", "struct inpcbinfo *")
	print(ti)
	inp = ti:GetChildMemberWithName("ipi_listhead")
		:GetChildMemberWithName("clh_first")

	print(inp)
	for i in netinet:inpcb_iter(ti)
	do
		print("inp\t" .. tostring(i))
	end
end

We can then load the script from the lldb interpreter:

(lldb) command script import ./lldb.lua
saved lldb: table: 0xdf66466a480
(vnet *) vnet0 = 0xfffff800034c0040
-2198998779352
(uintptr_t) vnet_data_base = 18446741876833615264
(struct inpcbinfo *) $0 = 0xfffffe0001757a28
(inpcb *) clh_first = 0xfffff80006e8ca80
inp     (inpcb *) clh_first = 0xfffff80006e8ca80
inp     (inpcb *) cle_next = 0xfffff8000ec2b540
inp     (inpcb *) cle_next = 0xfffff80006bd9540
inp     (inpcb *) cle_next = 0xfffff80006bd9a80
inp     (inpcb *) cle_next = 0xfffff8001d837540
inp     (inpcb *) cle_next = 0xfffff8001d837000

There are shortcomings in the lldb/lua implementation, but it is enough to do
some deep digging into a coredump. As a fuller example you can look at this in
progress implementation of extracting tcp log dumps from a coredump.

https://people.freebsd.org/~thj/lldb-scripts/tcplog_dumper.lua

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 56707
Build 53595: arc lint + arc unit

Event Timeline

thj requested review of this revision.Feb 23 2024, 2:18 PM
thj created this revision.
tools/lldb/netinet.lua
7

You no longer need the All Rights Reserved.

And if you like, you can omit the boilerplate

lldb multiple scripting interfaces, most notably in python and lua

Alright, who are you and what have you done with Tom? :-)

tools/lldb/netinet.lua
47

These should both be locals

54

Ditto above; db, mb, and addr should all be locals

67

This can be more concisely spelled:

local basevar = value:match("V_(.+)")
if not basevar then
    -- issue warning
end

-- basevar contains the var with prefix stripped

This also has the advantage of making sure that value isn't the empty string (i,e. we weren't just fed V_)

71

These messages might be more appropriate for stderr? io.stderr:write(...)

.oO(does lldb provide io/io.stderr?)

75

local vimage

thj marked 5 inline comments as done.Feb 26 2024, 9:49 AM
thj added inline comments.
tools/lldb/netinet.lua
71

Sadly while there I didn't get anything back from it:

(lldb) script
>>> io.stderr:write("hello world")
>>> io.stdout:write("hello world")
>>> print("hello world")
hello world
>>>

starting off with this in tools/ makes sense, but we probably want to install them at some point, perhaps making use of them in /usr/sbin/crashinfo.

tools/lldb/netinet.lua
41

Is it not more typical to have the then on the same line?

if not basevar then
    print(...)
end
  • Correct copyright statement
  • Move then for if statements onto the same line
thj marked an inline comment as done.Mar 20 2024, 2:23 PM