mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-01-19 02:36:29 +00:00
Merge branch 'feature/metrics/events-crash-callback' into feature/metrics/develop
# Conflicts: # Classes/BITChannel.h # Classes/BITChannel.m
This commit is contained in:
@@ -40,6 +40,7 @@ FOUNDATION_EXPORT char *BITSafeJsonEventsString;
|
||||
- (BOOL)enqueueTelemetryItem:(BITTelemetryData *)item;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
#endif /* HOCKEYSDK_FEATURE_METRICS */
|
||||
|
||||
@@ -162,27 +162,26 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
// Since we can't persist every event right away, we write it to a simple C string.
|
||||
// This can then be written to disk by a signal handler in case of a crash.
|
||||
bit_appendStringToSafeJsonStream(string, &(BITSafeJsonEventsString));
|
||||
BITSafeJsonEventsString = bit_jsonStreamByAppendingJsonString(BITSafeJsonEventsString, string);
|
||||
_dataItemCount += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void bit_appendStringToSafeJsonStream(NSString *string, char **jsonString) {
|
||||
if (jsonString == NULL) { return; }
|
||||
char * bit_jsonStreamByAppendingJsonString(char *json_stream, NSString *jsonString) {
|
||||
if ((json_stream == NULL) || !json_stream) {
|
||||
|
||||
if (!string) { return; }
|
||||
|
||||
if (*jsonString == NULL || strlen(*jsonString) == 0) {
|
||||
bit_resetSafeJsonStream(jsonString);
|
||||
return strdup("");
|
||||
}
|
||||
|
||||
if (string.length == 0) { return; }
|
||||
if (!jsonString || (jsonString.length == 0)) {
|
||||
return json_stream;
|
||||
}
|
||||
|
||||
char *new_string = NULL;
|
||||
// Concatenate old string with new JSON string and add a comma.
|
||||
asprintf(&new_string, "%s%.*s\n", *jsonString, (int)MIN(string.length, (NSUInteger)INT_MAX), string.UTF8String);
|
||||
free(*jsonString);
|
||||
*jsonString = new_string;
|
||||
|
||||
char *concatenated_string = NULL;
|
||||
// Concatenate old string with new JSON string and add a new line.
|
||||
asprintf(&concatenated_string, "%s%.*s\n", json_stream, (int)MIN(jsonString.length, (NSUInteger)INT_MAX), jsonString.UTF8String);
|
||||
return concatenated_string;
|
||||
}
|
||||
|
||||
void bit_resetSafeJsonStream(char **string) {
|
||||
|
||||
@@ -73,16 +73,16 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/**
|
||||
* A C function that serializes a given dictionary to JSON and appends it to a char string
|
||||
*
|
||||
* @param dictionary A dictionary which will be serialized to JSON and then appended to the string.
|
||||
* @param string The C string which the dictionary's JSON representation will be appended to.
|
||||
* @param existing_json_stream A C string containing JSON items in the JSON Stream format.
|
||||
* @param jsonString A NSString object containing a valid JSON item.
|
||||
*/
|
||||
void bit_appendStringToSafeJsonStream(NSString *string, char *__nonnull*__nonnull jsonStream);
|
||||
char * bit_jsonStreamByAppendingJsonString(char *existing_json_stream, NSString *jsonString);
|
||||
|
||||
/**
|
||||
* Reset BITSafeJsonEventsString so we can start appending JSON dictionaries.
|
||||
*
|
||||
* @param string The string that will be reset.
|
||||
*/
|
||||
* Reset BITSafeJsonEventsString so we can start appending JSON dictionaries.
|
||||
*
|
||||
* @param string The string that will be reset.
|
||||
*/
|
||||
void bit_resetSafeJsonStream(char *__nonnull*__nonnull jsonStream);
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#import "HockeySDK.h"
|
||||
#import "HockeySDKFeatureConfig.h"
|
||||
|
||||
#if HOCKEYSDK_FEATURE_CRASH_REPORTER
|
||||
|
||||
@@ -39,13 +39,20 @@
|
||||
#import "BITHockeyHelper.h"
|
||||
#import "BITHockeyAppClient.h"
|
||||
|
||||
#import "BITCrashManager.h"
|
||||
#import "BITCrashManagerPrivate.h"
|
||||
#import "BITCrashAttachment.h"
|
||||
#import "BITHockeyBaseManagerPrivate.h"
|
||||
#import "BITCrashManagerPrivate.h"
|
||||
#import "BITCrashReportTextFormatter.h"
|
||||
#import "BITCrashDetailsPrivate.h"
|
||||
#import "BITCrashCXXExceptionHandler.h"
|
||||
|
||||
#if HOCKEYSDK_FEATURE_METRICS
|
||||
#import "BITMetricsManagerPrivate.h"
|
||||
#import "BITChannel.h"
|
||||
#import "BITPersistencePrivate.h"
|
||||
#endif
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
// stores the set of crashreports that have been approved but aren't sent yet
|
||||
@@ -81,16 +88,40 @@ static NSString *const kBITFakeCrashDeviceModel = @"BITFakeCrashDeviceModel";
|
||||
static NSString *const kBITFakeCrashAppBinaryUUID = @"BITFakeCrashAppBinaryUUID";
|
||||
static NSString *const kBITFakeCrashReport = @"BITFakeCrashAppString";
|
||||
|
||||
#if HOCKEYSDK_FEATURE_METRICS
|
||||
static char const *BITSaveEventsFilePath;
|
||||
#endif
|
||||
|
||||
static BITCrashManagerCallbacks bitCrashCallbacks = {
|
||||
.context = NULL,
|
||||
.handleSignal = NULL
|
||||
};
|
||||
|
||||
// proxy implementation for PLCrashReporter to keep our interface stable while this can change
|
||||
#if HOCKEYSDK_FEATURE_METRICS
|
||||
static void bit_save_events_callback(siginfo_t *info, ucontext_t *uap, void *context) {
|
||||
// Try to get a file descriptor with our pre-filled path
|
||||
int fd = open(BITSaveEventsFilePath, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (fd < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t len = strlen(BITSafeJsonEventsString);
|
||||
if (len > 0) {
|
||||
// Simply write the whole string to disk
|
||||
write(fd, BITSafeJsonEventsString, len);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Proxy implementation for PLCrashReporter to keep our interface stable while this can change
|
||||
static void plcr_post_crash_callback (siginfo_t *info, ucontext_t *uap, void *context) {
|
||||
if (bitCrashCallbacks.handleSignal != NULL)
|
||||
#if HOCKEYSDK_FEATURE_METRICS
|
||||
bit_save_events_callback(info, uap, context);
|
||||
#endif
|
||||
if (bitCrashCallbacks.handleSignal != NULL) {
|
||||
bitCrashCallbacks.handleSignal(context);
|
||||
}
|
||||
}
|
||||
|
||||
static PLCrashReporterCallbacks plCrashCallbacks = {
|
||||
@@ -99,7 +130,6 @@ static PLCrashReporterCallbacks plCrashCallbacks = {
|
||||
.handleSignal = plcr_post_crash_callback
|
||||
};
|
||||
|
||||
|
||||
// Temporary class until PLCR catches up
|
||||
// We trick PLCR with an Objective-C exception.
|
||||
//
|
||||
@@ -154,8 +184,6 @@ static void uncaught_cxx_exception_handler(const BITCrashUncaughtCXXExceptionInf
|
||||
NSString *_settingsFile;
|
||||
NSString *_analyzerInProgressFile;
|
||||
NSFileManager *_fileManager;
|
||||
|
||||
PLCrashReporterCallbacks *_crashCallBacks;
|
||||
|
||||
BOOL _crashIdenticalCurrentVersion;
|
||||
|
||||
@@ -183,7 +211,6 @@ static void uncaught_cxx_exception_handler(const BITCrashUncaughtCXXExceptionInf
|
||||
|
||||
_plCrashReporter = nil;
|
||||
_exceptionHandler = nil;
|
||||
_crashCallBacks = nil;
|
||||
|
||||
_crashIdenticalCurrentVersion = YES;
|
||||
|
||||
@@ -657,17 +684,18 @@ static void uncaught_cxx_exception_handler(const BITCrashUncaughtCXXExceptionInf
|
||||
return useremail;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Public
|
||||
|
||||
#pragma mark - CrashCallbacks
|
||||
|
||||
/**
|
||||
* Set the callback for PLCrashReporter
|
||||
*
|
||||
* @param callbacks BITCrashManagerCallbacks instance
|
||||
*/
|
||||
- (void)setCrashCallbacks: (BITCrashManagerCallbacks *) callbacks {
|
||||
- (void)setCrashCallbacks:(BITCrashManagerCallbacks *)callbacks {
|
||||
if (!callbacks) return;
|
||||
if (_isSetup) {
|
||||
BITHockeyLog(@"CrashCallbacks need to be configured before calling startManager!");
|
||||
}
|
||||
|
||||
// set our proxy callback struct
|
||||
bitCrashCallbacks.context = callbacks->context;
|
||||
@@ -675,10 +703,17 @@ static void uncaught_cxx_exception_handler(const BITCrashUncaughtCXXExceptionInf
|
||||
|
||||
// set the PLCrashReporterCallbacks struct
|
||||
plCrashCallbacks.context = callbacks->context;
|
||||
|
||||
_crashCallBacks = &plCrashCallbacks;
|
||||
}
|
||||
|
||||
#if HOCKEYSDK_FEATURE_METRICS
|
||||
- (void)configDefaultCrashCallback {
|
||||
BITMetricsManager *metricsManager = [BITHockeyManager sharedHockeyManager].metricsManager;
|
||||
BITPersistence *persistence = metricsManager.persistence;
|
||||
BITSaveEventsFilePath = strdup([persistence fileURLForType:BITPersistenceTypeTelemetry].UTF8String);
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark - Public
|
||||
|
||||
- (void)setAlertViewHandler:(BITCustomAlertViewHandler)alertViewHandler{
|
||||
_alertViewHandler = alertViewHandler;
|
||||
@@ -1146,10 +1181,11 @@ static void uncaught_cxx_exception_handler(const BITCrashUncaughtCXXExceptionInf
|
||||
// can't break this
|
||||
NSError *error = NULL;
|
||||
|
||||
// set any user defined callbacks, hopefully the users knows what they do
|
||||
if (_crashCallBacks) {
|
||||
[self.plCrashReporter setCrashCallbacks:_crashCallBacks];
|
||||
}
|
||||
#if HOCKEYSDK_FEATURE_METRICS
|
||||
[self configDefaultCrashCallback];
|
||||
#endif
|
||||
// Set plCrashReporter callback which contains our default callback and potentially user defined callbacks
|
||||
[self.plCrashReporter setCrashCallbacks:&plCrashCallbacks];
|
||||
|
||||
// Enable the Crash Reporter
|
||||
if (![self.plCrashReporter enableCrashReporterAndReturnError: &error])
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
BITTelemetryContext *mockContext = mock(BITTelemetryContext.class);
|
||||
|
||||
_sut = [[BITChannel alloc]initWithTelemetryContext:mockContext persistence:_mockPersistence];
|
||||
BITSafeJsonEventsString = NULL;
|
||||
}
|
||||
|
||||
#pragma mark - Setup Tests
|
||||
@@ -88,34 +87,46 @@
|
||||
- (void)testAppendStringToSafeJsonStream {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnonnull"
|
||||
bit_appendStringToSafeJsonStream(nil, 0);
|
||||
BITSafeJsonEventsString = bit_jsonStreamByAppendingJsonString(0, nil);
|
||||
#pragma clang diagnostic pop
|
||||
XCTAssertTrue(BITSafeJsonEventsString == NULL);
|
||||
XCTAssertEqual(strcmp(BITSafeJsonEventsString, ""), 0);
|
||||
|
||||
BITSafeJsonEventsString = NULL;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnonnull"
|
||||
bit_appendStringToSafeJsonStream(nil, &BITSafeJsonEventsString);
|
||||
BITSafeJsonEventsString = bit_jsonStreamByAppendingJsonString(NULL, nil);
|
||||
#pragma clang diagnostic pop
|
||||
XCTAssertTrue(BITSafeJsonEventsString == NULL);
|
||||
XCTAssertEqual(strcmp(BITSafeJsonEventsString, ""), 0);
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnonnull"
|
||||
BITSafeJsonEventsString = bit_jsonStreamByAppendingJsonString(nil, nil);
|
||||
#pragma clang diagnostic pop
|
||||
XCTAssertEqual(strcmp(BITSafeJsonEventsString, ""), 0);
|
||||
|
||||
bit_appendStringToSafeJsonStream(@"", &BITSafeJsonEventsString);
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnonnull"
|
||||
BITSafeJsonEventsString = bit_jsonStreamByAppendingJsonString(NULL, @"");
|
||||
#pragma clang diagnostic pop
|
||||
XCTAssertEqual(strcmp(BITSafeJsonEventsString,""), 0);
|
||||
|
||||
bit_appendStringToSafeJsonStream(@"{\"Key1\":\"Value1\"}", &BITSafeJsonEventsString);
|
||||
BITSafeJsonEventsString = bit_jsonStreamByAppendingJsonString("", @"{\"Key1\":\"Value1\"}");
|
||||
XCTAssertEqual(strcmp(BITSafeJsonEventsString,"{\"Key1\":\"Value1\"}\n"), 0);
|
||||
}
|
||||
|
||||
- (void)testResetSafeJsonStream {
|
||||
BITSafeJsonEventsString = NULL;
|
||||
bit_resetSafeJsonStream(&BITSafeJsonEventsString);
|
||||
XCTAssertEqual(strcmp(BITSafeJsonEventsString,""), 0);
|
||||
|
||||
BITSafeJsonEventsString = NULL;
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnonnull"
|
||||
bit_resetSafeJsonStream(NULL);
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnonnull"
|
||||
bit_resetSafeJsonStream(nil);
|
||||
#pragma clang diagnostic pop
|
||||
XCTAssertEqual(BITSafeJsonEventsString, NULL);
|
||||
|
||||
BITSafeJsonEventsString = strdup("test string");
|
||||
bit_resetSafeJsonStream(&BITSafeJsonEventsString);
|
||||
|
||||
Reference in New Issue
Block a user