-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reimplement deadlock analysis and extend with MHP #655
Conversation
Also, I think we now get to the point, where we can probably not just ignore double locking anymore. While it may be undefinied behavior in pthreads, I think double locking a mutex that is not configured to support it, also constitutes a deadlock in some philosophical sense, right? |
Otherwise no Lock/Unlock events get emitted.
That's a good point indeed, especially since recursive mutexes don't self-deadlock (although for the new privatizations we assume they do AFAIK). That should probably be addressed separately too, to have tracking of mutex types and then we could relatively easily simply even warn about that default undefined behavior. This is related to #176. |
No, iirc we simply assume all mutexes are recursive in the implementation, and in the paper we don't deal with them at all. |
This is better than the special meaning of unknown_exp
Turns out our framework is so great that adding common lockset and MHP information to locking events to exclude some deadlocks was very straightforward, so I added that into this PR. With our existing mutex, mhp and threadJoins analyses, we can deal with the example from here: https://arxiv.org/abs/1607.06927 (also added as regression test). |
I am still adding some examples and checking some smaller things. When I'm done with that (hopefully later today), I'd be cool with merging it and then fixing the issues with Must vs May locks in #662 as you suggested. |
I think the most problematic issue we still have here is threads that end while holding locks. Any future attempt to acquire that lock may result in a deadlock. (Not sure if this is a deadlock according to some definitions that require each thread to be waiting on a resource, but I still think this something we should attempt to catch, maybe we could do it an a separate PR though). Also, I wasted a lot of time trying to come up with an example where one has a deadlock despite not all locking operations pairwise may-happen-in parallel, which turns out was a waste of time. |
type access = | ||
| Memory of memory_access (** Memory location access (race). *) | ||
| Point (** Program point and state access (MHP), independent of memory location. *) | ||
[@@deriving ord, hash] (* TODO: fix ppx_deriving_hash on variant with inline record *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you already fixed this in ppx_deriving_hash
by now, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, but I didn't yet make a new release just for that nor add an opam pin to Goblint to annoy everyone. There's no downside to having a separate named record type here, so I'd just leave it as is for now and change in sometime in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think how easy it was to enhance this with MHP information is a good sign we went for the right design here, and as always, I'm impressed with the speed with which you implemented this Simmo!
Not sure if we want to solve the issue with threads ending while holding mutexes here or make a new issue and PR for it? |
I think we should |
This is the reason why 15-deadlock-mhp2 doesn't have a deadlock, right? It had no annotations, so I added them, hopefully correctly. |
Yes! |
CHANGES: Goblint "lean" release after a lot of cleanup. * Remove unmaintained analyses: OSEK, ARINC, shapes, containment, deadlocksByRaces (goblint/analyzer#460, goblint/analyzer#736, goblint/analyzer#812, goblint/analyzer#474). * Add interactive analysis (goblint/analyzer#391). * Add server mode (goblint/analyzer#522). * Add Compilation Database support (goblint/analyzer#406, goblint/analyzer#448). * Add floating point domain, unrolled array domain and improved struct domains (goblint/analyzer#734, goblint/analyzer#761, goblint/analyzer#577, goblint/analyzer#419). * Add static loop unrolling and heap variable unrolling (goblint/analyzer#563, goblint/analyzer#722). * Improve race detection with may-happen-in-parallel analysis (goblint/analyzer#529, goblint/analyzer#518, goblint/analyzer#595). * Reimplement lockset and deadlock analyses (goblint/analyzer#659, goblint/analyzer#662, goblint/analyzer#650, goblint/analyzer#655). * Add pthread extraction to Promela (goblint/analyzer#220). * Add location spans to output (goblint/analyzer#428, goblint/analyzer#449). * Improve race reporting (goblint/analyzer#550, goblint/analyzer#551). * Improve dead code reporting (goblint/analyzer#94, goblint/analyzer#353, goblint/analyzer#785). * Refactor warnings (goblint/analyzer#55, goblint/analyzer#783). * Add JSON schema for configuration (goblint/analyzer#476, goblint/analyzer#499). * Refactor option names (goblint/analyzer#28, goblint/analyzer#192, goblint/analyzer#516, goblint/analyzer#675). * Add bash completion (goblint/analyzer#669). * Add OCaml 4.13 and 4.14 support, remove OCaml 4.09 support (goblint/analyzer#503, goblint/analyzer#672).
CHANGES: Goblint "lean" release after a lot of cleanup. * Remove unmaintained analyses: OSEK, ARINC, shapes, containment, deadlocksByRaces (goblint/analyzer#460, goblint/analyzer#736, goblint/analyzer#812, goblint/analyzer#474). * Add interactive analysis (goblint/analyzer#391). * Add server mode (goblint/analyzer#522). * Add Compilation Database support (goblint/analyzer#406, goblint/analyzer#448). * Add floating point domain, unrolled array domain and improved struct domains (goblint/analyzer#734, goblint/analyzer#761, goblint/analyzer#577, goblint/analyzer#419). * Add static loop unrolling and heap variable unrolling (goblint/analyzer#563, goblint/analyzer#722). * Improve race detection with may-happen-in-parallel analysis (goblint/analyzer#529, goblint/analyzer#518, goblint/analyzer#595). * Reimplement lockset and deadlock analyses (goblint/analyzer#659, goblint/analyzer#662, goblint/analyzer#650, goblint/analyzer#655). * Add pthread extraction to Promela (goblint/analyzer#220). * Add location spans to output (goblint/analyzer#428, goblint/analyzer#449). * Improve race reporting (goblint/analyzer#550, goblint/analyzer#551). * Improve dead code reporting (goblint/analyzer#94, goblint/analyzer#353, goblint/analyzer#785). * Refactor warnings (goblint/analyzer#55, goblint/analyzer#783). * Add JSON schema for configuration (goblint/analyzer#476, goblint/analyzer#499). * Refactor option names (goblint/analyzer#28, goblint/analyzer#192, goblint/analyzer#516, goblint/analyzer#675). * Add bash completion (goblint/analyzer#669). * Add OCaml 4.13 and 4.14 support, remove OCaml 4.09 support (goblint/analyzer#503, goblint/analyzer#672).
The refactoring of deadlock analysis for #650 turned into an almost complete rewrite. Extending with common lockset and MHP information was very straightforward.
Changes
Cil.location
withNode
for locking events. This makes it incrementally more stable.Deadlock
message category.access
information, which is independent of memory location (common lockset, MHP).This is directly on master, but I will take care of the merge into #391 when this lands. I already know that will require a few changes to adapt this to #634, which is only on interactive).
Example
Here's how
./regtest.sh 15 03
outputs the three-mutex locking cycle: