Skip to content

Commit b9f96bc

Browse files
cpepinfacebook-github-bot
authored andcommitted
Removing FSEvents code from FBCrashLogNotifier
Summary: ## Context As mentioned [here](https://fb.workplace.com/groups/1042353022615812/permalink/2767866986731065/) by RE prod eng, they freqently kill fseventsd when it starts using too many resources. They don't currently do anything to ensure that it restarts correctly, and it doesn't appear as though they have it in their priorities. What this means for us, is CrashLog collection is extremely unreliable (seems like ~30% of the time FSEvents is down), which means we can't observe the diagnostics folders. ## This diff - Strips FBCrashLogNotifier of FSEvents logic, and funnels everything into a `resolveUntil` block which is effectively polling the known diagnostics locations. - Fixes a bug(?) where the polling implementation wasn't handling the `onlyNew` flag. I don't think this is an issue in practice as I'm not seeing anywhere in the code where we actually want to collect older crashlogs. - Updates the FBSimulatorControlTests to target MacOSX, and replaces the assertion for iPhone8 to iPhone16 (which is something we actually have). Differential Revision: D68713530 fbshipit-source-id: 1d9907af3dbf2da51de345d1c58cb0d2457062d0
1 parent 83f6ee7 commit b9f96bc

File tree

3 files changed

+4
-140
lines changed

3 files changed

+4
-140
lines changed

FBControlCore/Crashes/FBCrashLogNotifier.m

+2-138
Original file line numberDiff line numberDiff line change
@@ -13,133 +13,9 @@
1313
#import "FBControlCoreLogger.h"
1414
#import "FBControlCoreError.h"
1515

16-
#if defined(__apple_build_version__)
17-
18-
#import <CoreServices/CoreServices.h>
19-
#include <sys/stat.h>
20-
21-
@interface FBCrashLogNotifier_FSEvents : NSObject
22-
23-
@property (nonatomic, copy, readonly) NSArray<NSString *> *directories;
24-
@property (nonatomic, strong, readonly) FBCrashLogStore *store;
25-
@property (nonatomic, strong, readonly) id<FBControlCoreLogger> logger;
26-
@property (nonatomic, strong, readonly) dispatch_queue_t queue;
27-
@property (nonatomic, assign, readwrite) FSEventStreamRef eventStream;
28-
29-
@end
30-
31-
typedef NS_ENUM(NSUInteger, FBCrashLogNotifierFileEvent) {
32-
FBCrashLogNotifierFileEventUnknown = 0,
33-
FBCrashLogNotifierFileEventAdded = 1,
34-
FBCrashLogNotifierFileEventRemoved = 2,
35-
};
36-
37-
static FBCrashLogNotifierFileEvent GetEventType(FSEventStreamEventFlags flag, NSString *filePath) {
38-
if (flag & kFSEventStreamEventFlagItemRemoved) {
39-
return FBCrashLogNotifierFileEventRemoved;
40-
} else if (flag & kFSEventStreamEventFlagItemCreated) {
41-
return FBCrashLogNotifierFileEventAdded;
42-
} else if (flag & kFSEventStreamEventFlagItemRenamed) {
43-
struct stat buffer;
44-
int value = stat(filePath.UTF8String, &buffer);
45-
return value == 0 ? FBCrashLogNotifierFileEventAdded : FBCrashLogNotifierFileEventRemoved;
46-
}
47-
return FBCrashLogNotifierFileEventUnknown;
48-
}
49-
50-
static void EventStreamCallback(
51-
ConstFSEventStreamRef streamRef,
52-
FBCrashLogNotifier_FSEvents *notifier,
53-
size_t numEvents,
54-
NSArray<NSString *> *eventPaths,
55-
const FSEventStreamEventFlags *eventFlags,
56-
const FSEventStreamEventId *eventIds
57-
){
58-
for (size_t index = 0; index < numEvents; index++) {
59-
NSString *path = eventPaths[index];
60-
FSEventStreamEventFlags flag = eventFlags[index];
61-
switch (GetEventType(flag, path)) {
62-
case FBCrashLogNotifierFileEventAdded:
63-
[notifier.store ingestCrashLogAtPath:path];
64-
continue;
65-
case FBCrashLogNotifierFileEventRemoved:
66-
[notifier.store removeCrashLogAtPath:path];
67-
continue;
68-
default:
69-
continue;
70-
}
71-
}
72-
}
73-
74-
@implementation FBCrashLogNotifier_FSEvents
75-
76-
- (instancetype)initWithDirectories:(NSArray<NSString *> *)directories store:(FBCrashLogStore *)store logger:(id<FBControlCoreLogger>)logger
77-
{
78-
self = [super init];
79-
if (!self) {
80-
return nil;
81-
}
82-
83-
_directories = directories;
84-
_store = store;
85-
_logger = logger;
86-
_queue = dispatch_queue_create("com.facebook.fbcontrolcore.crash_logs.fsevents", DISPATCH_QUEUE_SERIAL);
87-
88-
return self;
89-
}
90-
91-
- (BOOL)startListening:(BOOL)onlyNew
92-
{
93-
if (self.eventStream) {
94-
return YES;
95-
}
96-
97-
FSEventStreamContext context = {
98-
.version = 0,
99-
.info = (void *) CFBridgingRetain(self),
100-
.retain = CFRetain,
101-
.release = CFRelease,
102-
.copyDescription = NULL,
103-
};
104-
105-
NSMutableArray<NSString *> *pathsToWatch = NSMutableArray.array;
106-
for (NSString *reportPath in self.directories) {
107-
if ([[NSFileManager defaultManager] fileExistsAtPath:reportPath]) {
108-
[pathsToWatch addObject:reportPath];
109-
}
110-
}
111-
112-
FSEventStreamRef eventStream = FSEventStreamCreate(
113-
NULL, // Allocator
114-
(FSEventStreamCallback) EventStreamCallback, // Callback
115-
&context, // Context
116-
CFBridgingRetain(pathsToWatch), // Paths to watch
117-
onlyNew ? kFSEventStreamEventIdSinceNow : 0, // Since When
118-
0, // Latency
119-
kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagFileEvents | kFSEventStreamCreateFlagNoDefer
120-
);
121-
FSEventStreamSetDispatchQueue(eventStream, self.queue);
122-
Boolean started = FSEventStreamStart(eventStream);
123-
if (!started) {
124-
NSLog(@"FS Event Stream could not be started");
125-
return NO;
126-
}
127-
128-
self.eventStream = eventStream;
129-
return YES;
130-
}
131-
132-
@end
133-
134-
#endif
135-
13616
@interface FBCrashLogNotifier ()
13717

138-
#if defined(__apple_build_version__)
139-
@property (nonatomic, strong, readonly) FBCrashLogNotifier_FSEvents *fsEvents;
140-
#else
14118
@property (nonatomic, copy, readwrite) NSDate *sinceDate;
142-
#endif
14319

14420
@end
14521

@@ -155,12 +31,7 @@ - (instancetype)initWithLogger:(id<FBControlCoreLogger>)logger
15531
}
15632

15733
_store = [FBCrashLogStore storeForDirectories:FBCrashLogInfo.diagnosticReportsPaths logger:logger];
158-
159-
#if defined(__apple_build_version__)
160-
_fsEvents = [[FBCrashLogNotifier_FSEvents alloc] initWithDirectories:FBCrashLogInfo.diagnosticReportsPaths store:_store logger:logger];
161-
#else
16234
_sinceDate = NSDate.date;
163-
#endif
16435

16536
return self;
16637
}
@@ -179,12 +50,8 @@ + (instancetype)sharedInstance
17950

18051
- (BOOL)startListening:(BOOL)onlyNew
18152
{
182-
#if defined(__apple_build_version__)
183-
return [self.fsEvents startListening:onlyNew];
184-
#else
185-
self.sinceDate = NSDate.date;
53+
self.sinceDate = onlyNew ? NSDate.date : [NSDate distantPast];
18654
return YES;
187-
#endif
18855
}
18956

19057
- (FBFuture<FBCrashLogInfo *> *)nextCrashLogForPredicate:(NSPredicate *)predicate
@@ -195,9 +62,6 @@ - (BOOL)startListening:(BOOL)onlyNew
19562
failFuture];
19663
}
19764

198-
#if defined(__apple_build_version__)
199-
return [FBCrashLogNotifier.sharedInstance.fsEvents.store nextCrashLogForMatchingPredicate:predicate];
200-
#else
20165
dispatch_queue_t queue = dispatch_queue_create("com.facebook.fbcontrolcore.crashlogfetch", DISPATCH_QUEUE_SERIAL);
20266
return [FBFuture
20367
onQueue:queue resolveUntil:^{
@@ -210,9 +74,9 @@ - (BOOL)startListening:(BOOL)onlyNew
21074
describeFormat:@"Crash Log Info for %@ could not be obtained", predicate]
21175
failFuture];
21276
}
77+
[self.store ingestCrashLogAtPath:crashInfo.crashPath];
21378
return [FBFuture futureWithResult:crashInfo];
21479
}];
215-
#endif
21680
}
21781

21882
@end

FBSimulatorControlTests/Tests/Integration/FBSimulatorCrashLogTests.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ - (void)testAppCrashLogIsFetched
5151
XCTAssertNil(error);
5252
XCTAssertNotNil(crashLog);
5353
XCTAssertEqualObjects(crashLog.identifier, @"TableSearch");
54-
XCTAssertTrue([[NSString stringWithContentsOfFile:crashLog.crashPath encoding:NSUTF8StringEncoding error:nil] containsString:@"NSFileManager stringWithFormat"]);
54+
XCTAssertTrue([[NSString stringWithContentsOfFile:crashLog.crashPath encoding:NSUTF8StringEncoding error:&error] containsString:@"\"app_name\":\"TableSearch\""]);
5555
}
5656

5757
@end

FBSimulatorControlTests/Utilities/FBSimulatorControlTestCase.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ + (FBSimulatorBootConfiguration *)defaultBootConfiguration
105105
- (void)setUp
106106
{
107107
self.continueAfterFailure = NO;
108-
self.simulatorConfiguration = [FBSimulatorConfiguration.defaultConfiguration withDeviceModel:FBDeviceModeliPhone8];
108+
self.simulatorConfiguration = [FBSimulatorConfiguration.defaultConfiguration withDeviceModel:FBDeviceModeliPhone16];
109109
self.bootConfiguration = [[FBSimulatorBootConfiguration alloc] initWithOptions:FBSimulatorControlTestCase.bootOptions environment:@{}];
110110
self.deviceSetPath = FBSimulatorControlTestCase.defaultDeviceSetPath;
111111
}

0 commit comments

Comments
 (0)