deadlock thread

Hi. We have weird trouble related to the multi-threading.

Does anyone have ideas how to resolve or avoid?

Sample Code

// sample.hpp
class Sample {
public:
  Sample();
  ~Sample();
  void Init();
  void Dealloc();
  void OnEvent();
private:
  std::mutex sample_mutex_;
  int counter = 1;
}

// sample.cpp
#include "sample.hpp"
Sample::Sample() {}
Sample::~Sample() {}

void Sample::Init() {
  std::async([]() {
    std::this_thread::sleep_for(std::chrono::seconds(2));
    this->OnEvent();
  });
}

void Sample::Dealloc() {
  std::lock_guard<std::mutex> lock(sample_mutex_);
  counter = 0;
}

void Sample::OnEvent {
  // called from another thread
  std::lock_guard<std::mutex> lock(sample_mutex_);
  counter += 1;
}
// obj_sample.h
@interface ObjSample : NSObject
- (id _Nonnull)init;
@property(nonatomic, readonly) std::shared_ptr<Sample> sample;
@end

// obj_sample.mm
@implementation ObjSample
- (id _Nonnull)init{
  if (self = [super init]) {
    _sample = std::make_shared<Sample>();
    _sample->Init();
  }
  return self;
}

- (void)dealloc {
  sample->Dealloc();
}
@end

What happens

the deadlock happens.

according to the debug navigator with the Xcode, we figured out 2 facts below.

  1. OnEvent does not end although it looks completed.
void Sample::OnEvent {
  // called from another thread
  std::lock_guard<std::mutex> lock(sample_mutex_);
  counter += 1;
} // <= Thread 35: stop here
  1. Sample::Dealloc is run on the same thread of OnEvent.
// debug navigator
Thread 35
2 Sample::Dealloc <- this is weird.
3 Sample::OnEvent

We guess they causes the deadlock.

probability

  • less than 10%

Environment

  • MacOS: 14.3.1(Apple M1)
  • Xcode: 15.3
  • iOS Simulator: 17.0.1

Replies

Your code doesn't show how you create or destroy the ObjSample object. Are you calling ~Sample before the 2 seconds have passed?

Are you calling ~Sample before the 2 seconds have passed?

No. ~Sample is not called.

the actual code is too.

If you run your program outside of Xcode and then, when it deadlocks, kill it like so:

% kill -ABRT YOUR_PID

the system should generate a crash report. Please try that and, assuming it works, post the crash report here. See Posting a Crash Report for advice on how to do that.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"