Add gdb deadlock detector script to new folly/experimental/gdb directory
authorKenny Yu <kennyyu@fb.com>
Wed, 20 Sep 2017 03:31:08 +0000 (20:31 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Wed, 20 Sep 2017 03:37:52 +0000 (20:37 -0700)
commit14e3d271b698fac718dcfc56ff9f6ebf93d4fe82
treec138a1aac25ab1629f9e99f89eec0c66680e83da
parent3619b401a7d7e2f1a3454ad04639831f8a2c224b
Add gdb deadlock detector script to new folly/experimental/gdb directory

Summary:
This adds a gdb deadlock detector script into a new directory in folly. I
chose to put it under the `experimental` directory and not the top-level
directory as we have only tested these scripts on x86_64 Linux and not other
types of platforms.

This diff includes:
- a README on the contents of this directory and how to use the scripts
- a script to detect deadlocks

gdb directory
---------------

This new directory will contain a collection of gdb scripts that we have
found helpful. These scripts use the [gdb extension Python API](https://sourceware.org/gdb/current/onlinedocs/gdb/Python.html#Python).

To run the scripts, fire up gdb and load a script with `source -v`. Example:

```
$ gdb -p 123456
(gdb) source -v ./folly/experimental/gdb/deadlock.py
Type "deadlock" to detect deadlocks.
(gdb) deadlock
Found deadlock!
...
```

deadlock detector script
----------------------------

Consider the following program that always deadlocks:

```
void deadlock3() {
  std::mutex m1, m2, m3;
  folly::Baton<> b1, b2, b3;

  auto t1 = std::thread([&m1, &m2, &b1, &b2] {
    std::lock_guard<std::mutex> g1(m1);
    b1.post();
    b2.wait();
    std::lock_guard<std::mutex> g2(m2);
  });

  auto t2 = std::thread([&m3, &m2, &b3, &b2] {
    std::lock_guard<std::mutex> g2(m2);
    b2.post();
    b3.wait();
    std::lock_guard<std::mutex> g3(m3);
  });

  auto t3 = std::thread([&m3, &m1, &b3, &b1] {
    std::lock_guard<std::mutex> g3(m3);
    b3.post();
    b1.wait();
    std::lock_guard<std::mutex> g1(m1);
  });

  t1.join();
  t2.join();
  t3.join();
}
```

Once the process has deadlocked, we can use gdb to find the threads and mutexes involved in the deadlock:

```
$ gdb -p 2174496
(gdb) source -v ./folly/experimental/gdb/deadlock.py
Type "deadlock" to detect deadlocks.
(gdb) deadlock
Found deadlock!
Thread 2 (LWP 2174497) is waiting on mutex (0x00007ffcff42a4c0) held by Thread 3 (LWP 2174498)
Thread 3 (LWP 2174498) is waiting on mutex (0x00007ffcff42a4f0) held by Thread 4 (LWP 2174499)
Thread 4 (LWP 2174499) is waiting on mutex (0x00007ffcff42a490) held by Thread 2 (LWP 2174497)
```

Reviewed By: yfeldblum

Differential Revision: D5860868

fbshipit-source-id: 020a32327a79bb066269fe08113695803ce06c7d
folly/experimental/gdb/README.md [new file with mode: 0644]
folly/experimental/gdb/deadlock.py [new file with mode: 0644]