This is an archive of the discontinued LLVM Phabricator instance.

sanitizer: add support for trace coverage
ClosedPublic

Authored by dvyukov on Nov 11 2015, 6:21 AM.

Details

Reviewers
kcc
jdoerfert
Summary

Trace coverage mode collects all covered PCs into a per-thread, in-memory buffer. This mode replaces experimental and unused basic block tracing.
No logic is inlined into instrumented code, compiler only inserts callbacks into runtime.
This mode is meant to be used at least for Linux kernel, but can be useful for user-space as well.

Diff Detail

Event Timeline

dvyukov updated this revision to Diff 39910.Nov 11 2015, 6:21 AM
dvyukov retitled this revision from to sanitizer: add support for trace coverage.
dvyukov updated this object.
dvyukov added a reviewer: kcc.
dvyukov added a subscriber: llvm-commits.

I did not implement actual user-space runtime support, as we don't have agreement on this part yet. Kernel does not require any runtime support, it will have its own. I've sketched what I would do include/sanitizer/coverage_interface.h, but I don't have any concrete plans regarding user-space usage at the moment.

kcc accepted this revision.Nov 11 2015, 9:56 AM
kcc edited edge metadata.

LGTM with two nits.
Thanks!

include/sanitizer/coverage_interface.h
69

here and below use int instead of bool.
This API can theoretically be used in C

lib/Transforms/Instrumentation/SanitizerCoverage.cpp
80

typo: Tacing

This revision is now accepted and ready to land.Nov 11 2015, 9:56 AM
kcc added a comment.Nov 12 2015, 3:33 PM

I see you have not submitted this yet...
And I have an afterthought....

The tracing that we have now (https://github.com/google/sanitizers/wiki/AddressSanitizerBasicBlockTracing)
is more complex but it actually provides more functionality at almost same cost.

  1. It uses consecutive BB ids instead of PCs. This will buy us cheaper analysis because with consecutive ids we can use a bit set.
  1. It will allow us to implement coverage frontier:

at compile time, we create a static table that stores the Control Flow Graph of the function using the pairs of IDs.
at run-time, we load this table and we can find the edges that belong to the frontier (i.e. the edges that were never executed but that have one preceding edge that was executed)
(I have a patch for that lying somewhere).
This will be much harder to achieve with raw PCs.

dvyukov marked 2 inline comments as done.Nov 13 2015, 9:48 AM
In D14572#288470, @kcc wrote:

I see you have not submitted this yet...
And I have an afterthought....

The tracing that we have now (https://github.com/google/sanitizers/wiki/AddressSanitizerBasicBlockTracing)
is more complex but it actually provides more functionality at almost same cost.

  1. It uses consecutive BB ids instead of PCs. This will buy us cheaper analysis because with consecutive ids we can use a bit set.
  1. It will allow us to implement coverage frontier:

at compile time, we create a static table that stores the Control Flow Graph of the function using the pairs of IDs.
at run-time, we load this table and we can find the edges that belong to the frontier (i.e. the edges that were never executed but that have one preceding edge that was executed)
(I have a patch for that lying somewhere).
This will be much harder to achieve with raw PCs.

... and what do you propose?

kcc added a comment.Nov 13 2015, 11:04 AM
In D14572#288470, @kcc wrote:

I see you have not submitted this yet...
And I have an afterthought....

The tracing that we have now (https://github.com/google/sanitizers/wiki/AddressSanitizerBasicBlockTracing)
is more complex but it actually provides more functionality at almost same cost.

  1. It uses consecutive BB ids instead of PCs. This will buy us cheaper analysis because with consecutive ids we can use a bit set.
  1. It will allow us to implement coverage frontier:

at compile time, we create a static table that stores the Control Flow Graph of the function using the pairs of IDs.
at run-time, we load this table and we can find the edges that belong to the frontier (i.e. the edges that were never executed but that have one preceding edge that was executed)
(I have a patch for that lying somewhere).
This will be much harder to achieve with raw PCs.

... and what do you propose?

More like asking your opinion: can we implement tracing that produces IDs instead of PCs such that

  • it works for your use case in the kernel
  • reasonably simple to implement (probably simpler than my current code)
  • also allows to implement coverage frontier
dvyukov closed this revision.Apr 15 2021, 1:17 AM