diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2012-06-16 00:09:41 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2012-06-16 00:09:41 +0000 |
commit | 0b8b3ba21ee7c1a16ac844965dbace820b263bc0 (patch) | |
tree | 4c7caff6f6d792c7acba5a062a1760d635909f0e /lib/Support/Unix/Memory.inc | |
parent | af06825460e1905a7739386c28253c13e3653394 (diff) |
Harden the Unix signals code to be more async signal safe.
This is likely only the tip of the ice berg, but this particular bug
caused any double-free on a glibc system to turn into a deadlock! It is
not generally safe to either allocate or release heap memory from within
the signal handler. The 'pop_back()' in RemoveFilesToRemove was deleting
memory and causing the deadlock. What's worse, eraseFromDisk in PathV1
has lots of allocation and deallocation paths. We even passed 'true' in
a place that would have caused the *signal handler* to try to run the
'system' system call and shell out to 'rm -rf'. That was never going to
work...
This patch switches the file removal to use a vector of strings so that
the exact text needed for the 'unlink' system call can be stored there.
It switches the loop to be a boring indexed loop, and directly calls
unlink without looking at the error. It also works quite hard to ensure
that calling 'c_str()' is safe, by ensuring that the non-signal-handling
code path that manipulates the vector always leaves it in a state where
every element has already had 'c_str()' called at least once.
I dunno exactly how overkill this is, but it fixes the
deadlock-on-double free issue, and seems likely to prevent any other
issues from sneaking up.
Sorry for not having a test case, but I *really* don't know how to test
signal handling code easily....
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158580 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/Unix/Memory.inc')
0 files changed, 0 insertions, 0 deletions