aboutsummaryrefslogtreecommitdiff
path: root/lib/Support/Unix/Program.inc
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/Program.inc
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/Program.inc')
0 files changed, 0 insertions, 0 deletions