Blog/Of the Linux kernel, GNU Emacs, clangd and eglot

From ~esantoro
Revision as of 22:14, 20 November 2023 by Esantoro (talk | contribs) (Created page with "This is a short post, containing some quick notes on reading the Linux kernel sources with GNU Emacs. In my previous post Blog/More random notes about network programming (Episode 2) in the section about [https://santoro.tk/w/index.php/Blog/More_random_notes_about_network_programming_(Episode_2)#The_cmsghdr_structure_and_its_usage the cmsg structure and its usage] I wondered what other data can I find in there. Tonight I decided to go and take a look. I haven't fou...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This is a short post, containing some quick notes on reading the Linux kernel sources with GNU Emacs.

In my previous post Blog/More random notes about network programming (Episode 2) in the section about the cmsg structure and its usage I wondered what other data can I find in there.

Tonight I decided to go and take a look. I haven't found all the answers so far, this still an ongoing investigation.

As that feature is most likely implementation dependant (except for the SOL_SOCKET/SCM_RIGHT combo) I decided to look into the Linux kernel sources.

I cloned the sources from https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/ and opened that into Emacs.

Intuition suggested me to open net/ipv4/udp.c and look for the recvmsg function.

As I would like to get better at reading and writing code with Emacs, I enabled eglot to get lsp-based superpowers, and it kinda worked.

clangd and the Linux kernel

It kinda worked out of the box because it could look up function and structure declaration, but only within the same file.

The first intuition was to run a basic build of the kernel. I did a very quick make alldefconfig followed by make -j4 and then make headers.

But it still didn't work.

This stackoverflow reply contained the right suggestion:

in the scripts/clang-tools from the kernel top-level-directory, the gen_compile_commands.py must be ran:

./scripts/clang-tools/gen_compile_commands.py

Then a compile_commands.json file will appear, and it'll contain all the necessary directions for clangd to work properly.

Once that was done, a shutdown of the lsp server and a restart was sufficient.

emacs and eglot-based jump to definition

(More a note to myself than an important piece of content)

When using eglot and an lsp server GNU Emacs reuses the Xref features to browse source code.

Hence:

  • M-. will jump to the definition at point
  • M-, will go back to whence we came

More on Xref here.

cmsg: what I've found so far

I haven't done a proper dive-deep yet, however:

In net/ipv4/udp.c at line 1860 i see the following:

	sock_recv_cmsgs(msg, sk, skb);

In net/ipv4/udp.c at line 1876 i see the following:

	if (udp_test_bit(GRO_ENABLED, sk))
		udp_cmsg_recv(msg, sk, skb);

	if (inet_cmsg_flags(inet))
		ip_cmsg_recv_offset(msg, sk, skb, sizeof(struct udphdr), off);

So the next logical step would be to look into these three functions:

  • sock_recv_cmsgs
  • udp_cmsg_recv
  • ip_cmsg_recv_offset

My guesses are that:

  • they're respectively generic socket control message, udp-level control messages, ip-level control messages
  • there wil be an equivalent tcp_cmsg_recv (and possibly other for other protocols)


To the next post, I guess :)