KernelNewbies
  • Comments
  • Immutable Page
  • Menu
    • Navigation
    • RecentChanges
    • FindPage
    • Local Site Map
    • Help
    • HelpContents
    • HelpOnMoinWikiSyntax
    • Display
    • Attachments
    • Info
    • Raw Text
    • Print View
    • Edit
    • Load
    • Save
  • Login

Kernel Hacking

  • Frontpage

  • Kernel Hacking

  • Kernel Documentation

  • Kernel Glossary

  • FAQ

  • Found a bug?

  • Kernel Changelog

  • Upstream Merge Guide

Projects

  • KernelJanitors

  • KernelMentors

  • KernelProjects

Community

  • Why a community?

  • Regional Kernelnewbies

  • Personal Pages

  • Upcoming Events

References

  • Mailing Lists

  • Related Sites

  • Programming Links

Wiki

  • Recent Changes

  • Site Editors

  • Side Bar

  • Tips for Editors

  • Hosted by WikiWall

Navigation

  • RecentChanges
  • FindPage
  • HelpContents

Upload page content

You can upload content for the page named below. If you change the page name, you can also upload content for another page. If the page name is empty, we derive the page name from the file name.

File to load page content from
Page name
Comment

Revision 1 as of 2009-12-30 11:24:56
KernelNewbies:
  • roelkluin
  • gres_examples

To search for an erroneous pattern like this:

for (i = 0; i < n; i++) {}
...
if (i > n) ...

This is wrong because at the end of the loop i equals n and cannot be greater than n. The most simple way to match this is:

gres -A40 "^ for \(" \
"for \( (@V) = @d ;
         \1 < @d ;
         \1 \+\+ \)
    \{.8.\}
@n
if \( \1 > \3 \)"

Also, @d has parentheses, that's why we have to use \3, not \2 for back-reference to match the second @d.

For me - I currently have kernel version 2.6.33-rc2 - this results after about 10 seconds in a match (simplified here):

---[ vi drivers/mmc/host/s3cmci.c +1209 ]---
        /* Set clock */
        for (mci_psc = 0; mci_psc < 255; mci_psc++) {
                ...
        }

        if (mci_psc > 255)
                mci_psc = 255;
        ...

Quite harmless so I left it. Let's extend the example, similar errors will occur with:

for (i = 0; i != MAX; i++) {}
...
if (i <= MAX) ...

To catch such errors we could use a pattern like this:

gres -A40 "^ for \(" \
"for \( (@V) = (@d|@K) ;
         \1 (<|\!=) (@d|@K) ;
         (\+\+ \1|\1 \+\+|\1 = \1 \+ 1|\1 = 1 \+ \1) \)
    \{.8.\}
@n
if \( \1 (>|<=) \5 \)"

The @K matches definitions. This did not result in more errors in this kernel version, so lets extend it even more. Similar problems may occur when we have a pattern like:

while (foo() && ++i < MAX && bar()) {}
...
if (baz() || i > MAX) ...

This can be matched by:

gres -A40 "^ (for|while) \(" \
"(for \([^;]*;|while \() (\(-..\)[&|])*
         \+* (@V) (<|\!=) (@d|@w) ([&|]\(-..\))*
         (; (\+\+ \6|\6 \+\+|\6 = \6 \+ 1|\6 = 1 \+ \6))? \)
    \{.8.\}
@n
if \( (\(-..\)[&|])* \6 (>|<=) \8 ([&|]\(-..\))* \)"

This results (after about half a minute on my computer) in the additional matches:

---[ vi arch/sparc/mm/init_64.c +786 ]---
        ...
        start += PAGE_SIZE;
        while (start < end) {
                ...
                if (...)
                        break;
                start += PAGE_SIZE;
        }

        if (start > end)
                start = end;
        ...
---[ vi drivers/atm/horizon.c +626 ]---
        while (...) ...
        ...
        if (...) ...
        ...
        while (div < CR_MAXD) {
                div++;
                if (...) {
                        ...
                        goto got_it;
                }
        }
got_it:
        if (div > CR_MAXD || ...) ...

The second one was difficult to see in the output due to a prior while loop. The first one, in contrast, is a false positive: the addition of PAGE_SIZE can cause `start' to be bigger than `end'. In the case of a while loop the chosen pattern with `\+*' allows a postfix increment, but does not ensure that an increment occurs, an addition can occur just as well. We can exclude the false positive by adding an exclusion pattern:

gres -A40 "^ (for|while) \(" \
"while \( (\(-..\)[&|])* (@V) (<|\!=) (@d|@w) ([&|]\(-..\))* \) (\{\{-..\} \n)? \5 ([+*|]=|= \5 \+)@n
if \( (\(-..\)[&|])* \5 (>|<=) \7 ([&|]\(-..\))* \)" \
"(for \([^;]*;|while \() (\(-..\)[&|])*
         \+* (@V) (<|\!=) (@d|@w) ([&|]\(-..\))*
         (; (\+\+ \6|\6 \+\+|\6 = \6 \+ 1|\6 = 1 \+ \6))? \)
    \{.8.\}
@n
if \( (\(-..\)[&|])* \6 (>|<=) \8 ([&|]\(-..\))* \)"

Similarly one can define an erroneous pattern for decrementing loops:

gres -A40 "^ (for|while) \(" \
"while \( (\(-..\)[&|])* (@V) (>|\!=) (@d|@w) ([&|]\(-..\))* \) (\{\{-..\} \n)? \5 (-=|= \5 -)@n
if \( (\(-..\)[&|])* \5 (<|>=) \7 ([&|]\(-..\))* \)" \
"(for \([^;]*;|while \() (\(-..\)[&|])*
         -* (@V) (>|\!=) (@d|@w) ([&|]\(-..\))*
         (; (-- \6|\6 --|\6 = \6 - 1|\6 = 1 - \6))? \)
    \{.8.\}
@n
if \( (\(-..\)[&|])* \6 (<|>=) \8 ([&|]\(-..\))* \)"
  • MoinMoin Powered
  • Python Powered
  • GPL licensed
  • Valid HTML 4.01