Skip to content

Commit

Permalink
Allow stripping of file cleanup code
Browse files Browse the repository at this point in the history
Summary:
The linker currently cannot strip the file cleanup code because it is
called on fatal errors and signals (when a the LLVM signal handler is
installed). To allow it to be stripped, add a layer of indirection
through a function pointer, which is only populated by
`RemoveFileOnSignal`. This way, the cleanup code is only considered
reachable when `RemoveFileOnSignal` is actually used, and it can be
stripped otherwise.

Reviewed By: tmikov

Differential Revision: D53535800

fbshipit-source-id: ae26197a66bc154dd83eb304b4c731eabac10873
  • Loading branch information
neildhar authored and facebook-github-bot committed Feb 12, 2024
1 parent 09eab96 commit b686d8f
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions external/llvh/lib/Support/Unix/Signals.inc
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ public:
};
static std::atomic<FileToRemoveList *> FilesToRemove = ATOMIC_VAR_INIT(nullptr);

/// Provide the interrupt function to clean up FilesToRemove if it is populated.
/// We use a nullable static function pointer for this to allow the linker to
/// strip the file removal code if RemoveFileOnSignal is never called.
static std::atomic<InterruptFunctionType> FilesToRemoveInterruptFunc = ATOMIC_VAR_INIT(nullptr);

/// Clean up the list in a signal-friendly manner.
/// Recall that signals can fire during llvm_shutdown. If this occurs we should
/// either clean something up or nothing at all, but we shouldn't crash!
Expand Down Expand Up @@ -327,7 +332,8 @@ static RETSIGTYPE SignalHandler(int Sig) {
sigprocmask(SIG_UNBLOCK, &SigMask, nullptr);

{
RemoveFilesToRemove();
if(auto *fn = FilesToRemoveInterruptFunc.load())
fn();

if (std::find(std::begin(IntSigs), std::end(IntSigs), Sig)
!= std::end(IntSigs)) {
Expand All @@ -353,7 +359,8 @@ static RETSIGTYPE SignalHandler(int Sig) {
}

void llvh::sys::RunInterruptHandlers() {
RemoveFilesToRemove();
if(auto *fn = FilesToRemoveInterruptFunc.load())
fn();
}

void llvh::sys::SetInterruptFunction(void (*IF)()) {
Expand All @@ -367,6 +374,7 @@ bool llvh::sys::RemoveFileOnSignal(StringRef Filename,
// Ensure that cleanup will occur as soon as one file is added.
static ManagedStatic<FilesToRemoveCleanup> FilesToRemoveCleanup;
*FilesToRemoveCleanup;
FilesToRemoveInterruptFunc = RemoveFilesToRemove;
FileToRemoveList::insert(FilesToRemove, Filename.str());
RegisterHandlers();
return false;
Expand Down

0 comments on commit b686d8f

Please sign in to comment.