Skip to content

Abort in cleanup leads to unwinding failure #61945

Closed
@nikic

Description

@nikic

Consider the following example:

#include <cstdlib>
#include <cstdio>

struct Abort {
  ~Abort() {
    puts("cleanup");
    abort();
  }
};

__attribute__((noinline))
static void abort_in_dtor() {
  Abort abort;
  throw "test";
}

int main() {
  try {
    abort_in_dtor();
  } catch (...) {
    puts("caught");
  }
}

This should print "cleanup" followed by abort. Instead this happens when using Clang 17:

terminate called after throwing an instance of 'char const*'
Aborted (core dumped)

The reason for this is that we now (correctly) infer that abort_in_dtor() is nounwind. However, as phase 1 unwind skips cleanups, this means that the unwind walk will try to go past a nounwind frame, which may not have an LSDA entry, resulting in some form of unwinding failure. (In this specific case we return _URC_END_OF_STACK, but a similar case in Rust results in _URC_FATAL_PHASE1_ERROR.)

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions