aboutsummaryrefslogtreecommitdiff
path: root/lib/Support/Unix/Unix.h
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-06-16 00:09:41 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-06-16 00:09:41 +0000
commit0b8b3ba21ee7c1a16ac844965dbace820b263bc0 (patch)
tree4c7caff6f6d792c7acba5a062a1760d635909f0e /lib/Support/Unix/Unix.h
parentaf06825460e1905a7739386c28253c13e3653394 (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/Unix.h')
0 files changed, 0 insertions, 0 deletions