All of lore.kernel.org
 help / color / mirror / Atom feed
* [Cocci] Help in interpreting results
@ 2016-11-15 11:13 Reshetova, Elena
  2016-11-15 11:18 ` Julia Lawall
  0 siblings, 1 reply; 10+ messages in thread
From: Reshetova, Elena @ 2016-11-15 11:13 UTC (permalink / raw)
  To: cocci

Good day,

I am very new to coccinelle, and therefore my question is rather basic, but unfortunately I wasn't able to find the info online.
I have a very simple cocci rule:

------------------------------

@r exists@
identifier a;
identifier x;
position p1, p2;
@@

atomic_dec_and_test(&a->x)@p1
...
kfree(a)@p2;

@script:python@
p1 << r.p1;
p2 << r.p2;
@@

print "* file: %s atomic_dec_and_test %s before kfree %s" % (p1[0].file,p1[0].line,p2[0].line)

--------------------------------

I just want to find all occurrences of atomic_dec_and_test(), which are somewhere later in the code flow (maybe called using some intermediate function, such as kfree_rcu() or others) followed by kfree() on the same pointer.

When this rule is applied to Linux kernel tree, it results in 80 of such occurrences found. However, the output is a bit confusing. For example:

...
Skipping:./linux-stable/kernel/rcu/srcu.c
Skipping:./linux-stable/kernel/rcu/rcuperf.c
Skipping:./linux-stable/kernel/rcu/waketorture.c
HANDLING: ./linux-stable/kernel/rcu/rcutorture.c
Skipping:./linux-stable/kernel/rcu/update.c
Skipping:./linux-stable/kernel/rcu/tree.c
Skipping:./linux-stable/kernel/panic.c
Skipping:./linux-stable/kernel/utsname.c
Skipping:./linux-stable/kernel/cgroup_freezer.c
HANDLING: ./linux-stable/kernel/workqueue.c
HANDLING: ./linux-stable/kernel/cgroup.c
....

I understand that "Skipping" means that the pattern was not found in that .c file. But what does "HANDLING" actually mean?
There are 330 of such "HANDLING" happen with above rule and when I manually check some of them, for example linux-stable/kernel/cgroup.c, it is actually the correct case that I want to be found, and it seems to be "HANDLED", but not reported.

I am a bit confused on what is happening. Any help is greatly appreciated!

Best Regards,
Elena.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://systeme.lip6.fr/pipermail/cocci/attachments/20161115/a861f8c3/attachment.html>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Cocci] Help in interpreting results
  2016-11-15 11:13 [Cocci] Help in interpreting results Reshetova, Elena
@ 2016-11-15 11:18 ` Julia Lawall
  2016-11-15 11:58   ` Reshetova, Elena
  0 siblings, 1 reply; 10+ messages in thread
From: Julia Lawall @ 2016-11-15 11:18 UTC (permalink / raw)
  To: cocci



On Tue, 15 Nov 2016, Reshetova, Elena wrote:

>
> Good day,
>
> ?
>
> I am very new to coccinelle, and therefore my question is rather basic, but
> unfortunately I wasn?t able to find the info online.
>
> I have a very simple cocci rule:
>
> ?
>
> ------------------------------
>
> ?
>
> @r exists@
> identifier a;
> identifier x;
> position p1, p2;
> @@
>
> atomic_dec_and_test(&a->x)@p1
> ...
> kfree(a)@p2;
>
> @script:python@
> p1 << r.p1;
> p2 << r.p2;
> @@
>
> print "* file: %s atomic_dec_and_test %s before kfree %s" %
> (p1[0].file,p1[0].line,p2[0].line)
>
> ?
>
> --------------------------------
>
> ?
>
> I just want to find all occurrences of atomic_dec_and_test(), which are
> somewhere later in the code flow (maybe called using some intermediate
> function, such as kfree_rcu() or others) followed by kfree() on the same
> pointer.
>
> ?
>
> When this rule is applied to Linux kernel tree, it results in 80 of such
> occurrences found. However, the output is a bit confusing. For example:
>
> ?
>
> ?
>
> Skipping:./linux-stable/kernel/rcu/srcu.c
> Skipping:./linux-stable/kernel/rcu/rcuperf.c
> Skipping:./linux-stable/kernel/rcu/waketorture.c
> HANDLING: ./linux-stable/kernel/rcu/rcutorture.c
> Skipping:./linux-stable/kernel/rcu/update.c
> Skipping:./linux-stable/kernel/rcu/tree.c
> Skipping:./linux-stable/kernel/panic.c
> Skipping:./linux-stable/kernel/utsname.c
> Skipping:./linux-stable/kernel/cgroup_freezer.c
> HANDLING: ./linux-stable/kernel/workqueue.c
> HANDLING: ./linux-stable/kernel/cgroup.c
>
> ?.
>
> ?
>
> I understand that ?Skipping? means that the pattern was not found in that .c
> file. But what does ?HANDLING? actually mean?
>
> There are 330 of such ?HANDLING? happen with above rule and when I manually
> check some of them, for example linux-stable/kernel/cgroup.c, it is actually
> the correct case that I want to be found, and it seems to be ?HANDLED?, but
> not reported.

You need to separate standard output and standard error.  Skipping and
HANDLING indicate just that the file is totaly irrelevant and so ignored
(Skipping) or possibly relevant and thus parsed and matched against your
rule (HANDLING).  This is just useful for checking that Coccinelle is
progressing.  You may also see information about cases that run for a long
time.  This is all on standard error.  The results from your print
statements will be on standard output.

julia

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Cocci] Help in interpreting results
  2016-11-15 11:18 ` Julia Lawall
@ 2016-11-15 11:58   ` Reshetova, Elena
  2016-11-15 12:38     ` Julia Lawall
  0 siblings, 1 reply; 10+ messages in thread
From: Reshetova, Elena @ 2016-11-15 11:58 UTC (permalink / raw)
  To: cocci

>On Tue, 15 Nov 2016, Reshetova, Elena wrote:
>
>
> Good day,
>
> ?
>
> I am very new to coccinelle, and therefore my question is rather 
> basic, but unfortunately I wasn?t able to find the info online.
>
> I have a very simple cocci rule:
>
> ?
>
> ------------------------------
>
> ?
>
> @r exists@
> identifier a;
> identifier x;
> position p1, p2;
> @@
>
> atomic_dec_and_test(&a->x)@p1
> ...
> kfree(a)@p2;
>
> @script:python@
> p1 << r.p1;
> p2 << r.p2;
> @@
>
> print "* file: %s atomic_dec_and_test %s before kfree %s" %
> (p1[0].file,p1[0].line,p2[0].line)
>
> ?
>
> --------------------------------
>
> ?
>
> I just want to find all occurrences of atomic_dec_and_test(), which 
> are somewhere later in the code flow (maybe called using some 
> intermediate function, such as kfree_rcu() or others) followed by 
> kfree() on the same pointer.
>
> ?
>
> When this rule is applied to Linux kernel tree, it results in 80 of 
> such occurrences found. However, the output is a bit confusing. For example:
>
> ?
>
> ?
>
> Skipping:./linux-stable/kernel/rcu/srcu.c
> Skipping:./linux-stable/kernel/rcu/rcuperf.c
> Skipping:./linux-stable/kernel/rcu/waketorture.c
> HANDLING: ./linux-stable/kernel/rcu/rcutorture.c
> Skipping:./linux-stable/kernel/rcu/update.c
> Skipping:./linux-stable/kernel/rcu/tree.c
> Skipping:./linux-stable/kernel/panic.c
> Skipping:./linux-stable/kernel/utsname.c
> Skipping:./linux-stable/kernel/cgroup_freezer.c
> HANDLING: ./linux-stable/kernel/workqueue.c
> HANDLING: ./linux-stable/kernel/cgroup.c
>
> ?.
>
> ?
>
> I understand that ?Skipping? means that the pattern was not found in 
> that .c file. But what does ?HANDLING? actually mean?
>
> There are 330 of such ?HANDLING? happen with above rule and when I 
> manually check some of them, for example linux-stable/kernel/cgroup.c, 
> it is actually the correct case that I want to be found, and it seems 
> to be ?HANDLED?, but not reported.

>You need to separate standard output and standard error.  Skipping and HANDLING indicate just that the file is totaly irrelevant and so ignored
>(Skipping) or possibly relevant and thus parsed and matched against your rule (HANDLING).  This is just useful for checking that Coccinelle is progressing.  You may also see information about cases that run for a long time.  This is all on standard error.  The > results from your print statements will be on standard output.

Thank you for your promt reply, Julia!
I did get the results with my print statement, this wasn't the issue. But now I understand what rest of output means, thanks to your explanation!

So, "Skipping" means "not a single search token was found in file", "Handling" (without result print) means "one or more tokens were found, processing was done, but rule search pattern wasn't detected".
I was just trying to understand how it works underneath. Thank you again!

Best Regards,
Elena

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Cocci] Help in interpreting results
  2016-11-15 11:58   ` Reshetova, Elena
@ 2016-11-15 12:38     ` Julia Lawall
  2016-11-16  9:36       ` Reshetova, Elena
  0 siblings, 1 reply; 10+ messages in thread
From: Julia Lawall @ 2016-11-15 12:38 UTC (permalink / raw)
  To: cocci

> So, "Skipping" means "not a single search token was found in file", "Handling" (without result print) means "one or more tokens were found, processing was done, but rule search pattern wasn't detected".
> I was just trying to understand how it works underneath. Thank you again!

Exactly.

You may want to run coccinelle/scripts/idutils_index.sh in your code base.
Then if you use the argument --use-idutils it will select the relevant
files up front from the index and be even more efficient.  Skipping means
that it essentialy did a grep and didn't find anything.  If the argument
after --use-idutils does not begin with -, it will think that it is the
name of the index.  The easiest is to just put --use-idutils last.

julia

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Cocci] Help in interpreting results
  2016-11-15 12:38     ` Julia Lawall
@ 2016-11-16  9:36       ` Reshetova, Elena
  2016-11-16  9:46         ` Julia Lawall
  2016-11-16 10:07         ` Julia Lawall
  0 siblings, 2 replies; 10+ messages in thread
From: Reshetova, Elena @ 2016-11-16  9:36 UTC (permalink / raw)
  To: cocci

>You may want to run coccinelle/scripts/idutils_index.sh in your code base.
>Then if you use the argument --use-idutils it will select the relevant files up front from the index and be even more >efficient.  Skipping means that it essentialy did a grep and didn't find anything.  If the argument after --use-idutils does >not begin with -, it will think that it is the name of the index.  The easiest is to just put --use-idutils last.

Thank you for the suggestion! I will try this out. However, I seem to have a different problem that the rule doesn't behave as I would think it should and enabling debug doesn't tell terribly much.

My rule is now this:

@r1 exists@
identifier a, x;
position p1, p2;
identifier fname1 =~ ".*$free.*$";
identifier fname2 =~ ".*$kfree_.*$";
@@

(
 atomic_dec_and_test at p1(&a->x)
|
 atomic_long_dec_and_test at p1(&a->x)
|
 atomic64_dec_and_test at p1(&a->x)
|
 local_dec_and_test at p1(&a->x)
)
...
(
 kfree at p2(a);
|
 fname1 at p2(a | (a, ...));
|
 fname2 at p2(a | (a, ...));
)

@script:python@
p1 << r1.p1;
p2 << r1.p2;
@@

print "* file: %s atomic_dec_and_test variation %s before kfree variation %s" % (p1[0].file,p1[0].line,p2[0].line)

However, it doesn't catch even some simple cases like for example /linux-stable/kernel/audit_tree.c:
starting from line 109:
static void free_chunk(struct audit_chunk *chunk)
{
    int i;

    for (i = 0; i < chunk->count; i++) {
        if (chunk->owners[i].owner)
            put_tree(chunk->owners[i].owner);
    }
    kfree(chunk);
}

void audit_put_chunk(struct audit_chunk *chunk)
{
    if (atomic_long_dec_and_test(&chunk->refs))
        free_chunk(chunk);
}

The above case is a clear kfree() call after atomic_long_dec_and_test() just via intermediate function free_chunk(). Why is it not detected?

Another case:

line 97:
static inline void put_tree(struct audit_tree *tree)
{
    if (atomic_dec_and_test(&tree->count))
        kfree_rcu(tree, head);
}

This should have been caught by fname2 at p2(a | (a, ...)) rule, but it isn't also.

I have a feeling of doing smth basic wrongly...

Best Regards,
Elena.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Cocci] Help in interpreting results
  2016-11-16  9:36       ` Reshetova, Elena
@ 2016-11-16  9:46         ` Julia Lawall
  2016-11-16  9:54           ` Reshetova, Elena
  2016-11-16 10:07         ` Julia Lawall
  1 sibling, 1 reply; 10+ messages in thread
From: Julia Lawall @ 2016-11-16  9:46 UTC (permalink / raw)
  To: cocci



On Wed, 16 Nov 2016, Reshetova, Elena wrote:

> >You may want to run coccinelle/scripts/idutils_index.sh in your code base.
> >Then if you use the argument --use-idutils it will select the relevant files up front from the index and be even more >efficient.  Skipping means that it essentialy did a grep and didn't find anything.  If the argument after --use-idutils does >not begin with -, it will think that it is the name of the index.  The easiest is to just put --use-idutils last.
>
> Thank you for the suggestion! I will try this out. However, I seem to have a different problem that the rule doesn't behave as I would think it should and enabling debug doesn't tell terribly much.
>
> My rule is now this:
>
> @r1 exists@
> identifier a, x;
> position p1, p2;
> identifier fname1 =~ ".*$free.*$";
> identifier fname2 =~ ".*$kfree_.*$";
> @@
>
> (
>  atomic_dec_and_test at p1(&a->x)
> |
>  atomic_long_dec_and_test at p1(&a->x)
> |
>  atomic64_dec_and_test at p1(&a->x)
> |
>  local_dec_and_test at p1(&a->x)
> )
> ...
> (
>  kfree at p2(a);
> |
>  fname1 at p2(a | (a, ...));

I have the impression that you mean for the above to be a disjunction.
But it is being interpreted as a bit or operation.  If you want to put a
disjunction inline, you need \( \| \).

But disjunction is not actually supported on an argument list, so it
wouldn't help in this case.  Actually what you want is just:

fname1 at p2(a, ...);

Coccinelle will be ok with matching the ", ..." to nothing if there is
only one argument.

julia

> |
>  fname2 at p2(a | (a, ...));
> )
>
> @script:python@
> p1 << r1.p1;
> p2 << r1.p2;
> @@
>
> print "* file: %s atomic_dec_and_test variation %s before kfree variation %s" % (p1[0].file,p1[0].line,p2[0].line)
>
> However, it doesn't catch even some simple cases like for example /linux-stable/kernel/audit_tree.c:
> starting from line 109:
> static void free_chunk(struct audit_chunk *chunk)
> {
>     int i;
>
>     for (i = 0; i < chunk->count; i++) {
>         if (chunk->owners[i].owner)
>             put_tree(chunk->owners[i].owner);
>     }
>     kfree(chunk);
> }
>
> void audit_put_chunk(struct audit_chunk *chunk)
> {
>     if (atomic_long_dec_and_test(&chunk->refs))
>         free_chunk(chunk);
> }
>
> The above case is a clear kfree() call after atomic_long_dec_and_test() just via intermediate function free_chunk(). Why is it not detected?
>
> Another case:
>
> line 97:
> static inline void put_tree(struct audit_tree *tree)
> {
>     if (atomic_dec_and_test(&tree->count))
>         kfree_rcu(tree, head);
> }
>
> This should have been caught by fname2 at p2(a | (a, ...)) rule, but it isn't also.
>
> I have a feeling of doing smth basic wrongly...
>
> Best Regards,
> Elena.
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Cocci] Help in interpreting results
  2016-11-16  9:46         ` Julia Lawall
@ 2016-11-16  9:54           ` Reshetova, Elena
  0 siblings, 0 replies; 10+ messages in thread
From: Reshetova, Elena @ 2016-11-16  9:54 UTC (permalink / raw)
  To: cocci


> >You may want to run coccinelle/scripts/idutils_index.sh in your code base.
> >Then if you use the argument --use-idutils it will select the relevant files up front from the index and be even more >efficient.  Skipping means that it essentialy did a grep and didn't find anything.  If the argument after --use-idutils does >not begin with -, it will think that it is the name of the index.  The easiest is to just put --use-idutils last.
>
> Thank you for the suggestion! I will try this out. However, I seem to have a different problem that the rule doesn't behave as I would think it should and enabling debug doesn't tell terribly much.
>
> My rule is now this:
>
> @r1 exists@
> identifier a, x;
> position p1, p2;
> identifier fname1 =~ ".*$free.*$";
> identifier fname2 =~ ".*$kfree_.*$";
> @@
>
> (
>  atomic_dec_and_test at p1(&a->x)
> |
>  atomic_long_dec_and_test at p1(&a->x)
> |
>  atomic64_dec_and_test at p1(&a->x)
> |
>  local_dec_and_test at p1(&a->x)
> )
> ...
> (
>  kfree at p2(a);
> |
>  fname1 at p2(a | (a, ...));

>I have the impression that you mean for the above to be a disjunction.
>But it is being interpreted as a bit or operation.  If you want to put a disjunction inline, you need \( \| \).
>But disjunction is not actually supported on an argument list, so it wouldn't help in this case.  Actually what you want is just:

>fname1 at p2(a, ...);

>Coccinelle will be ok with matching the ", ..." to nothing if there is only one argument.

I tried this before (and quite many other ways I would imagine grammar can do), but it didn't change anything. 
Still the clear cases that I mentioned are not detected. 

>julia

> |
>  fname2 at p2(a | (a, ...));
> )
>
> @script:python@
> p1 << r1.p1;
> p2 << r1.p2;
> @@
>
> print "* file: %s atomic_dec_and_test variation %s before kfree 
> variation %s" % (p1[0].file,p1[0].line,p2[0].line)
>
> However, it doesn't catch even some simple cases like for example /linux-stable/kernel/audit_tree.c:
> starting from line 109:
> static void free_chunk(struct audit_chunk *chunk) {
>     int i;
>
>     for (i = 0; i < chunk->count; i++) {
>         if (chunk->owners[i].owner)
>             put_tree(chunk->owners[i].owner);
>     }
>     kfree(chunk);
> }
>
> void audit_put_chunk(struct audit_chunk *chunk) {
>     if (atomic_long_dec_and_test(&chunk->refs))
>         free_chunk(chunk);
> }
>
> The above case is a clear kfree() call after atomic_long_dec_and_test() just via intermediate function free_chunk(). Why is it not detected?
>
> Another case:
>
> line 97:
> static inline void put_tree(struct audit_tree *tree) {
>     if (atomic_dec_and_test(&tree->count))
>         kfree_rcu(tree, head);
> }
>
> This should have been caught by fname2 at p2(a | (a, ...)) rule, but it isn't also.
>
> I have a feeling of doing smth basic wrongly...
>
> Best Regards,
> Elena.
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Cocci] Help in interpreting results
  2016-11-16  9:36       ` Reshetova, Elena
  2016-11-16  9:46         ` Julia Lawall
@ 2016-11-16 10:07         ` Julia Lawall
  2016-11-16 10:32           ` Reshetova, Elena
  1 sibling, 1 reply; 10+ messages in thread
From: Julia Lawall @ 2016-11-16 10:07 UTC (permalink / raw)
  To: cocci



On Wed, 16 Nov 2016, Reshetova, Elena wrote:

> >You may want to run coccinelle/scripts/idutils_index.sh in your code base.
> >Then if you use the argument --use-idutils it will select the relevant files up front from the index and be even more >efficient.  Skipping means that it essentialy did a grep and didn't find anything.  If the argument after --use-idutils does >not begin with -, it will think that it is the name of the index.  The easiest is to just put --use-idutils last.
>
> Thank you for the suggestion! I will try this out. However, I seem to have a different problem that the rule doesn't behave as I would think it should and enabling debug doesn't tell terribly much.
>
> My rule is now this:
>
> @r1 exists@
> identifier a, x;
> position p1, p2;
> identifier fname1 =~ ".*$free.*$";
> identifier fname2 =~ ".*$kfree_.*$";

I'm not very good at regular expressions, but I thought that $ meant end
of string.  So can it work to have $ before free/kfree?  Also, without the
first $, I'm not sure to understand the difference between fname1 and
fname2.  It looks like anything matched by fname2 would also be matched by
fname1.

julia

> @@
>
> (
>  atomic_dec_and_test at p1(&a->x)
> |
>  atomic_long_dec_and_test at p1(&a->x)
> |
>  atomic64_dec_and_test at p1(&a->x)
> |
>  local_dec_and_test at p1(&a->x)
> )
> ...
> (
>  kfree at p2(a);
> |
>  fname1 at p2(a | (a, ...));
> |
>  fname2 at p2(a | (a, ...));
> )
>
> @script:python@
> p1 << r1.p1;
> p2 << r1.p2;
> @@
>
> print "* file: %s atomic_dec_and_test variation %s before kfree variation %s" % (p1[0].file,p1[0].line,p2[0].line)
>
> However, it doesn't catch even some simple cases like for example /linux-stable/kernel/audit_tree.c:
> starting from line 109:
> static void free_chunk(struct audit_chunk *chunk)
> {
>     int i;
>
>     for (i = 0; i < chunk->count; i++) {
>         if (chunk->owners[i].owner)
>             put_tree(chunk->owners[i].owner);
>     }
>     kfree(chunk);
> }
>
> void audit_put_chunk(struct audit_chunk *chunk)
> {
>     if (atomic_long_dec_and_test(&chunk->refs))
>         free_chunk(chunk);
> }
>
> The above case is a clear kfree() call after atomic_long_dec_and_test() just via intermediate function free_chunk(). Why is it not detected?
>
> Another case:
>
> line 97:
> static inline void put_tree(struct audit_tree *tree)
> {
>     if (atomic_dec_and_test(&tree->count))
>         kfree_rcu(tree, head);
> }
>
> This should have been caught by fname2 at p2(a | (a, ...)) rule, but it isn't also.
>
> I have a feeling of doing smth basic wrongly...
>
> Best Regards,
> Elena.
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Cocci] Help in interpreting results
  2016-11-16 10:07         ` Julia Lawall
@ 2016-11-16 10:32           ` Reshetova, Elena
  2016-11-16 10:45             ` Julia Lawall
  0 siblings, 1 reply; 10+ messages in thread
From: Reshetova, Elena @ 2016-11-16 10:32 UTC (permalink / raw)
  To: cocci

> >You may want to run coccinelle/scripts/idutils_index.sh in your code base.
> >Then if you use the argument --use-idutils it will select the relevant files up front from the index and be even more >efficient.  Skipping means that it essentialy did a grep and didn't find anything.  If the argument after --use-idutils does >not begin with -, it will think that it is the name of the index.  The easiest is to just put --use-idutils last.
>
> Thank you for the suggestion! I will try this out. However, I seem to have a different problem that the rule doesn't behave as I would think it should and enabling debug doesn't tell terribly much.
>
> My rule is now this:
>
> @r1 exists@
> identifier a, x;
> position p1, p2;
> identifier fname1 =~ ".*$free.*$";
> identifier fname2 =~ ".*$kfree_.*$";

>I'm not very good at regular expressions, but I thought that $ meant end of string.  So can it work to have $ before free/kfree?  Also, without the first $, I'm not sure to understand the difference between fname1 and fname2.  It looks like >anything matched by fname2 would also be matched by fname1.

Yes, you are right, my memory of regular expression failed here. However, what confused me also here is that I had an explicit kfree match alternative: 

(
  kfree at p2(a);
|
  fname1 at p2(a | (a, ...));
|
fname2 at p2(a | (a, ...));
)

Which didn't result in findings when it was called using some intermediate function. For this piece of code:

 >     if (atomic_long_dec_and_test(&chunk->refs))
>         free_chunk(chunk);

Where free_chunk  calls it turn kfree(chunk).

I got it working now with just one unified identifier, but I would like to understand better how coccinelle works in the above case to not make same mistakes in future. 

>julia

> @@
>
> (
>  atomic_dec_and_test at p1(&a->x)
> |
>  atomic_long_dec_and_test at p1(&a->x)
> |
>  atomic64_dec_and_test at p1(&a->x)
> |
>  local_dec_and_test at p1(&a->x)
> )
> ...
> (
>  kfree at p2(a);
> |
>  fname1 at p2(a | (a, ...));
> |
>  fname2 at p2(a | (a, ...));
> )
>
> @script:python@
> p1 << r1.p1;
> p2 << r1.p2;
> @@
>
> print "* file: %s atomic_dec_and_test variation %s before kfree 
> variation %s" % (p1[0].file,p1[0].line,p2[0].line)
>
> However, it doesn't catch even some simple cases like for example /linux-stable/kernel/audit_tree.c:
> starting from line 109:
> static void free_chunk(struct audit_chunk *chunk) {
>     int i;
>
>     for (i = 0; i < chunk->count; i++) {
>         if (chunk->owners[i].owner)
>             put_tree(chunk->owners[i].owner);
>     }
>     kfree(chunk);
> }
>
> void audit_put_chunk(struct audit_chunk *chunk) {
>     if (atomic_long_dec_and_test(&chunk->refs))
>         free_chunk(chunk);
> }
>
> The above case is a clear kfree() call after atomic_long_dec_and_test() just via intermediate function free_chunk(). Why is it not detected?
>
> Another case:
>
> line 97:
> static inline void put_tree(struct audit_tree *tree) {
>     if (atomic_dec_and_test(&tree->count))
>         kfree_rcu(tree, head);
> }
>
> This should have been caught by fname2 at p2(a | (a, ...)) rule, but it isn't also.
>
> I have a feeling of doing smth basic wrongly...
>
> Best Regards,
> Elena.
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Cocci] Help in interpreting results
  2016-11-16 10:32           ` Reshetova, Elena
@ 2016-11-16 10:45             ` Julia Lawall
  0 siblings, 0 replies; 10+ messages in thread
From: Julia Lawall @ 2016-11-16 10:45 UTC (permalink / raw)
  To: cocci



On Wed, 16 Nov 2016, Reshetova, Elena wrote:

> > >You may want to run coccinelle/scripts/idutils_index.sh in your code base.
> > >Then if you use the argument --use-idutils it will select the relevant files up front from the index and be even more >efficient.  Skipping means that it essentialy did a grep and didn't find anything.  If the argument after --use-idutils does >not begin with -, it will think that it is the name of the index.  The easiest is to just put --use-idutils last.
> >
> > Thank you for the suggestion! I will try this out. However, I seem to have a different problem that the rule doesn't behave as I would think it should and enabling debug doesn't tell terribly much.
> >
> > My rule is now this:
> >
> > @r1 exists@
> > identifier a, x;
> > position p1, p2;
> > identifier fname1 =~ ".*$free.*$";
> > identifier fname2 =~ ".*$kfree_.*$";
>
> >I'm not very good at regular expressions, but I thought that $ meant end of string.  So can it work to have $ before free/kfree?  Also, without the first $, I'm not sure to understand the difference between fname1 and fname2.  It looks like >anything matched by fname2 would also be matched by fname1.
>
> Yes, you are right, my memory of regular expression failed here. However, what confused me also here is that I had an explicit kfree match alternative:
>
> (
>   kfree at p2(a);
> |
>   fname1 at p2(a | (a, ...));
> |
> fname2 at p2(a | (a, ...));
> )
>
> Which didn't result in findings when it was called using some intermediate function. For this piece of code:
>
>  >     if (atomic_long_dec_and_test(&chunk->refs))
> >         free_chunk(chunk);
>
> Where free_chunk  calls it turn kfree(chunk).
>
> I got it working now with just one unified identifier, but I would like to understand better how coccinelle works in the above case to not make same mistakes in future.

Coccinelle is intraprocedural.  If you want interprocedural information,
you have to use a feature known as iteration.  There is an example in
demos/iteration.cocci (or python_iteration.cocci if you prefer python to
ocaml), and it is presented in this talk:

Advanced SmPL: http://coccinelle.lip6.fr/papers/cocciwk4_talk2.pdf

If the regexp is good enough for you in the short term, you may want to
stick with that.

julia

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-11-16 10:45 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-15 11:13 [Cocci] Help in interpreting results Reshetova, Elena
2016-11-15 11:18 ` Julia Lawall
2016-11-15 11:58   ` Reshetova, Elena
2016-11-15 12:38     ` Julia Lawall
2016-11-16  9:36       ` Reshetova, Elena
2016-11-16  9:46         ` Julia Lawall
2016-11-16  9:54           ` Reshetova, Elena
2016-11-16 10:07         ` Julia Lawall
2016-11-16 10:32           ` Reshetova, Elena
2016-11-16 10:45             ` Julia Lawall

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.