SourceForge Logo Smatch Logo

Using smatch.pm!!!

1. Introduction

There are 2 main parts to a Smatch script: pattern matching in the code and tracing state transitions down the code paths. The smatch.pm module is meant to make tracing the code paths easy.

There are not too many functions you need to know about actually. Here is a listing in no particular order:

     563~/progs/gcc/cvs/pristine.$ grep sub\ [a-z] smatch.pm 
     sub get_filename {
     sub get_lineno {
     sub get_cur_func {
     sub get_func_pos {
     sub set_state {
     sub set_true_path {
     sub set_false_path {
     sub get_state {
     sub get_start_line {
     sub state_names {
     sub add_merge_function($) {
     sub abandon_merge($$$) {
     sub get_data {

2. General Purpose Functions

Each .sm file is made up of lots of stuff that looks like this:

     SM include/asm/bitops.h 43 end_func
For this particular line: get_data() returns "end_func".
get_filename() returns "include/asm/bitops.h".
get_lineno() returns 43.
get_cur_func() returns "sched_find_first_bit".
get_func_pos() returns "sched_find_first_bit(3)".

3. Managing States

There are three places of interest when tracing state changes: Normal code, branching code and merging code.

If a state change happens in normal code then we use the function set_state() to specify the new state. We can either specify the name of the state that changes or allow smatch.pm to supply a name. The respective formats are:

     set_state("foo", "bar");
     set_state("baz");
Sometimes the state change happens at a branch position. For example, if you have code that looks like this:
     if (locked(a)){
Then we might say something like this:
     set_true_path("a", "locked");
     set_false_path("a", "unlocked");
The if statement may have an else statement or it may not. Either way smatch.pm takes care of that. While statements are basically the same as if statements except there is never an else statement.

Smatch.pm automatically handles merging states and for some cases that is good enough. However there are times when it is nice to specify your own merge rules.

To do that create a function that takes three parameters:

     sub merger($$$) {
     my ($name, $one, $two) = @_;
     
     ...[code]...

     }
The first parameter is the name of the state, and the other parameters are the two states to merge. From the last example it could be something like:
     $name:  "a"
     $one:   "locked"
     $two:   "unlocked"
In that case we would probably want to return "undefined". Once we written the merge function then we say:
     add_merge_function("merger")
The other function to handle merging abandon_merge() is only meant for libraries and isn't used yet. Don't worry about it.

Once we have stored some states the function get_state() can tell us what the state currently is.

If we have stored a lot of state names then we can get a list of all the state names using the function state_names()

The last function used to manage states is get_start_line() which records which line the state was first set. This is usefull information for error messages.

4. Printing Error Messages

This is how error messages usually are printed.

    sub error_msg($$) {
	my $state = shift;
	my $msg = shift;
	print get_filename(), " ", get_start_line($state), " ", get_lineno(), " ", get_func_pos(), " $msg\n";
    }
I normally take a list of error messages only look at error messages with different starting lines. That cuts down on duplicate messages for the same error.

get_func_pos() is a type of finger print that can be tracked over different kernel versions. It means that a change in the file can happen but unless something happens in that particular function we can still recognize a bug as one that has been seen before.

5. Conclusion

Writing Smatch scripts is pretty easy. Sometimes it's interesting to write silly scripts just to see what sort of results they will find. Don't worry too much about being thorough or avoiding false positives for the first draft; just slap it together and see what happens.

If you need help writing scripts or you want features added to Smatch then email smatch-discuss@lists.sf.net