How to get around in the source code tree?

There exists a number of tools (some proprietary, some FOSS, some with IDEs..etc. Which one is the best?...

You might be aware of a number of tools that gives you easy access to source trees. But the one I have found best is, without surprise vim/emacs and grep. Mix it with cscope and tags, you don't need anything else.

You can also browse the kernel with lxr.


Set up cscope with the make target cscope

$ pwd
$ make cscope
$ ls cscope*
308K cscope.files   24M  134M cscope.out  190M cscope.po.out
$ cscope -d    # starts cscope


Set up ctags with the make target tags

$ pwd
$ make tags
$ ls tags
61M tags

Once you launch [g]vim editor (emacs should work too, I don't know much about it), make sure tags are set right.

<ESC>:set tags?

GREP and Regular Expressions

REs pack a lot of power. The best reason for using them is, that it is not easy. Secondly, the more REs you use, the more familiar with them you grow. Moreover, you would grow more familiar with the source code too.

For example, I want to get to the definition of struct task_struct. I can use cscope, and in my setup, it returns around 30 entries. I can go through all and finally find out it is defined in sched.h. Similarly, using ctags, I get almost the same number of entries.

Now since I am trying to use grep, let's see how many entries can I see using grep.

$ type findc
findc is a function
findc () 
    find $1 -name '*.[ch]'
[om@testserv ~/src]
$ findc | xargs grep task_struct | wc -l

3738 lines?... if you think searching among 30 lines is a lot better, I agree with you. But wait a bit, what I did was not really correct. I just searched for occurrences of task_struct instead of definition. If I can't reduce the number of lines I have to search for definition to around 2-3, there may not much point to using grep. How can I grep for definition of task_struct? Here is where REs comes in handy.

BTW, findc is a function I use to avoid typing some number of characters.

Let's see, we can reasonably assume that the keyword struct would precede the task_struct where it is defined. So, let's grep for that.

$ findc | xargs grep -EnH "struct task_struct" | wc -l

That is not helping either. The reason is every function definition, extern declarations ..etc of task_struct would have the keyword struct preceding it.

Hmm... Okay. In definition of task_struct, { should succeed task_struct, i.e., the RE should be struct task_struct {. Is that correct? Let's see.

$ findc | xargs grep -EnH "struct task_struct {" 
./include/linux/sched.h:947:struct task_struct {

And you got it. Exactly where it is defined.

The RE I used is not exactly correct. There could be any number of whitespaces between keywords. Even though Linux kernel adheres to its coding standards, a generic RE would look like,

$ findc | xargs grep -EnH "\W*struct\W+task_struct\W*{"
./include/linux/sched.h:947:struct task_struct {

This RE means, "0 or more non-word characters followed by struct, followed by 1 or more non-word characters followed by task_struct followed by 0 or more non-word characters followed by {"

Finding functions

Finding functions is a little more difficult, but it is great to write REs to find them. Let's try finding the function find_pid

[om@testserv ~/src]
$ findc | xargs grep -EHn "find_pid" | wc -l

Assuming that I saw this function while browsing the code, I would know it takes an integer/long argument and returns a struct pid *. Let's formulate an RE to find this.

$ findc | xargs grep -EnH "find_pid\W*\(((int)|(long))\W+"
./include/linux/pid.h:90:extern struct pid *FASTCALL(find_pid(int nr));
./kernel/pid.c:238:struct pid * fastcall find_pid(int nr)

The RE means "find_pid followed by 0 or more non-word characters followed by ( followed by int or long followed by 1 or more non-word characters". This is not a complete expression for a function, but it does find you the function definition.

KernelNewbies: FAQ/CodeBrowsing (last edited 2021-01-10 22:44:21 by RandyDunlap)