in idb_companion/Server/FBIDBServiceHandler.mm [1642:1711]
Status FBIDBServiceHandler::xctrace_record(ServerContext *context,grpc::ServerReaderWriter<idb::XctraceRecordResponse, idb::XctraceRecordRequest> *stream)
{@autoreleasepool{
__block idb::XctraceRecordRequest recordRequest;
__block pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
__block bool finished_writing = NO;
dispatch_queue_t queue = dispatch_queue_create("com.facebook.idb.xctrace.record", DISPATCH_QUEUE_SERIAL);
// @lint-ignore FBOBJCDISCOURAGEDFUNCTION
dispatch_sync(queue, ^{
idb::XctraceRecordRequest request;
stream->Read(&request);
recordRequest = request;
});
FBXCTraceRecordConfiguration *configuration = translate_xctrace_record_configuration(recordRequest.start());
NSError *error = nil;
id<FBDataConsumer> consumer = [FBBlockDataConsumer asynchronousDataConsumerOnQueue:queue consumer:^(NSData *data) {
idb::XctraceRecordResponse response;
response.set_log(data.bytes, data.length);
pthread_mutex_lock(&mutex);
if (!finished_writing) {
stream->Write(response);
}
pthread_mutex_unlock(&mutex);
}];
id<FBControlCoreLogger> logger = [FBControlCoreLoggerFactory compositeLoggerWithLoggers:@[
[FBControlCoreLoggerFactory loggerToConsumer:consumer],
_target.logger,
]];
FBXCTraceRecordOperation *operation = [[_target startXctraceRecord:configuration logger:logger] block:&error];
if (!operation) {
pthread_mutex_lock(&mutex);
finished_writing = YES;
pthread_mutex_unlock(&mutex);
return Status(grpc::StatusCode::INTERNAL, error.localizedDescription.UTF8String);
}
// @lint-ignore FBOBJCDISCOURAGEDFUNCTION
dispatch_sync(queue, ^{
idb::XctraceRecordResponse response;
response.set_state(idb::XctraceRecordResponse::State::XctraceRecordResponse_State_RUNNING);
stream->Write(response);
idb::XctraceRecordRequest request;
stream->Read(&request);
recordRequest = request;
});
NSTimeInterval stopTimeout = recordRequest.stop().timeout() ?: DefaultXCTraceRecordStopTimeout;
if (![[operation stopWithTimeout:stopTimeout] succeeds:&error]) {
pthread_mutex_lock(&mutex);
finished_writing = YES;
pthread_mutex_unlock(&mutex);
return Status(grpc::StatusCode::INTERNAL, error.localizedDescription.UTF8String);
}
NSArray<NSString *> *postProcessArgs = extract_string_array(recordRequest.stop().args());
// @lint-ignore FBOBJCDISCOURAGEDFUNCTION
dispatch_sync(queue, ^{
idb::XctraceRecordResponse response;
response.set_state(idb::XctraceRecordResponse::State::XctraceRecordResponse_State_PROCESSING);
stream->Write(response);
});
NSURL *processed = [[FBInstrumentsOperation postProcess:postProcessArgs traceDir:operation.traceDir queue:queue logger:logger] block:&error];
pthread_mutex_lock(&mutex);
finished_writing = YES;
pthread_mutex_unlock(&mutex);
if (!processed) {
return Status(grpc::StatusCode::INTERNAL, error.localizedDescription.UTF8String);
}
return drain_writer([FBArchiveOperations createGzippedTarForPath:processed.path queue:queue logger:_target.logger], stream);
}}