Good articles to my personal technology blog: https://cainluo.github.io/14971830645415.html


Thread Sanitizer(TSan)

Thread Sanitizer… Actually, I’ve been thinking a lot. Thread hand sanitizer? Thread sweeper? It doesn’t feel right…. So I’m not going to translate it, but we just need to know that this thing is used to solve threading problems, and this is the Objective-C version, if you like the Swift version, you can find the Swift version


Usage scenarios

So when do you use Thread Sanitizer? In fact, after we carefully develop an App, we find that there are intermittent small bugs, which may cause problems such as Crash, and you can not find it, so we can use this thing to try.

So under what circumstances does that happen? I found a relatively official text, you can make do with it.

Typically, these are caused by multiple threads accessing the same address in memory at the same time. Believing in threading problems is a nightmare for many developers. They are difficult to track because errors only occur under certain conditions, so determining the root cause of the problem can be very tricky. The common reason is the so-called race condition.

Data contention occurs when two threads concurrently access the same variable and at least one of the accesses is write.


Thread Sanitizer(TSan) can check for type errors

Thread Sanitizer is awesome, but it’s not a cure-all. It detects only a few errors.

  • Use of uninitialized mutexes
  • Thread leaks (missing phread_johin)
  • Unsafe calls in signal handlers (ex:malloc)
  • Unlock from wrong thread
  • Data race

Open the Thread Sanitizer tool

Thread Sanitizer Tools are opened in The Project’s Edit Scheme -> Diagnostics, not in Developer Tools like Instruments.


Create a project

All things, all want to start from the code, here we are the same, write a small Demo to demonstrate Demo, UI slightly ugly, we make do with see…. Code words, in the project to look up ~

The code for the layout of all the navigation I would like to retrieve is unflattering. I would like to thank you for your unselfish efforts


Arithmetic logic

I’m not going to write that big number here, I’m going to write ten digits,

Here it is easy to store the logic and pass in the result after calculating:

- (void)setMoneyInTheBank {
    
    NSString *amount = [NSString stringWithFormat:@" ¥%ld".self.bankView.amount + 10];
    
    [self.bankView changeLabelContentWithString:amount];
}
Copy the code

Originally, I was going to write the acquisition logic, but here I thought of a situation, fast press save and take, that will happen just in the beginning of the article said the data competition problem, here after thinking, found to use a throw multithreading skills.

- (void)getMoneyOfBanek {
    
    dispatch_async(dispatch_queue_create("com.threadsanitizer.ThreadSanitizer".nil), ^ {if (self.amount <= 0) {
            NSLog(@" How do you get out when you don't have any money?");
            
            return;
        }
        
        // This is to let the line rest a second first ~
        sleep(1);
        
        dispatch_async(dispatch_get_main_queue(), ^{
            
            NSString *amount = [NSString stringWithFormat:@" ¥%ld".self.amount -= 10];

            [self.bankView changeLabelContentWithString:amount];
        });
    });
}
Copy the code

After writing, then run, click save and take, and the following screen will appear:

Is it easy to figure out what the problem is?

Principle of words, probably like you eat, swallow the first mouthful and then swallow the second mouthful, or swallow together, will choke.

By the way:

  • TSan is a tool for checking Runtime Issues (static checking is not supported)
  • Runs only on Swift code written in language version 3 (objective-C compatible as well),
  • It can only run on 64-bit macOS or 64-bit emulators (none of the real devices can be used for debugging).

The project address

The address of the project: https://github.com/CainRun/iOS-10-Characteristic/tree/master/2.Thread%20Sanitizer


The last