Proyectos de Subversion Iphone Microlearning

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// Copyright 2021 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
 
15
#import <Foundation/Foundation.h>
16
 
17
#import "Crashlytics/Crashlytics/Helpers/FIRCLSCallStackTree.h"
18
 
19
#if CLS_METRICKIT_SUPPORTED
20
 
21
@interface FIRCLSFrame : NSObject
22
@property long address;
23
@property long sampleCount;
24
@property long offsetIntoBinaryTextSegment;
25
@property NSString *binaryName;
26
@property NSUUID *binaryUUID;
27
@end
28
 
29
@implementation FIRCLSFrame
30
@end
31
 
32
@interface FIRCLSThread : NSObject
33
@property NSString *threadName;
34
@property BOOL threadBlamed;
35
@property NSArray<FIRCLSFrame *> *frames;
36
@end
37
 
38
@implementation FIRCLSThread
39
@end
40
 
41
@interface FIRCLSCallStackTree ()
42
@property NSArray<FIRCLSThread *> *threads;
43
@property(nonatomic) BOOL callStackPerThread;
44
 
45
@end
46
 
47
@implementation FIRCLSCallStackTree
48
 
49
- (instancetype)initWithMXCallStackTree:(MXCallStackTree *)callStackTree {
50
  NSData *jsonCallStackTree = callStackTree.JSONRepresentation;
51
  if ([jsonCallStackTree length] == 0) return nil;
52
 
53
  NSError *error = nil;
54
  NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonCallStackTree
55
                                                                 options:0
56
                                                                   error:&error];
57
  if (error) {
58
    NSLog(@"Crashlytics: error creating json");
59
    return nil;
60
  }
61
  self = [super init];
62
  if (!self) {
63
    return nil;
64
  }
65
  _callStackPerThread = [[jsonDictionary objectForKey:@"callStackPerThread"] boolValue];
66
 
67
  // Recurse through the frames in the callStackTree and add them all to an array
68
  NSMutableArray<FIRCLSThread *> *threads = [[NSMutableArray alloc] init];
69
  NSArray *callStacks = jsonDictionary[@"callStacks"];
70
  for (id object in callStacks) {
71
    NSMutableArray<FIRCLSFrame *> *frames = [[NSMutableArray alloc] init];
72
    [self flattenSubFrames:object[@"callStackRootFrames"] intoFrames:frames];
73
    FIRCLSThread *thread = [[FIRCLSThread alloc] init];
74
    thread.threadBlamed = [[object objectForKey:@"threadAttributed"] boolValue];
75
    thread.frames = frames;
76
    [threads addObject:thread];
77
  }
78
  _threads = threads;
79
  return self;
80
}
81
 
82
// Flattens the nested structure we receive from MetricKit into an array of frames.
83
- (void)flattenSubFrames:(NSArray *)callStacks intoFrames:(NSMutableArray *)frames {
84
  NSDictionary *rootFrames = [callStacks firstObject];
85
  FIRCLSFrame *frame = [[FIRCLSFrame alloc] init];
86
  frame.offsetIntoBinaryTextSegment =
87
      [[rootFrames valueForKey:@"offsetIntoBinaryTextSegment"] longValue];
88
  frame.address = [[rootFrames valueForKey:@"address"] longValue];
89
  frame.sampleCount = [[rootFrames valueForKey:@"sampleCount"] longValue];
90
  frame.binaryUUID = [rootFrames valueForKey:@"binaryUUID"];
91
  frame.binaryName = [rootFrames valueForKey:@"binaryName"];
92
 
93
  [frames addObject:frame];
94
 
95
  // Recurse through any subframes and add them to the array.
96
  if ([rootFrames objectForKey:@"subFrames"]) {
97
    [self flattenSubFrames:[rootFrames objectForKey:@"subFrames"] intoFrames:frames];
98
  }
99
}
100
 
101
- (NSArray *)getArrayRepresentation {
102
  NSMutableArray *threadArray = [[NSMutableArray alloc] init];
103
  for (FIRCLSThread *thread in self.threads) {
104
    [threadArray addObject:[self getDictionaryRepresentation:thread]];
105
  }
106
  return threadArray;
107
}
108
 
109
- (NSDictionary *)getDictionaryRepresentation:(FIRCLSThread *)thread {
110
  NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
111
  [dictionary setObject:@{} forKey:@"registers"];
112
  NSMutableArray *frameArray = [[NSMutableArray alloc] init];
113
  for (FIRCLSFrame *frame in thread.frames) {
114
    [frameArray addObject:[NSNumber numberWithLong:frame.address]];
115
  }
116
  [dictionary setObject:frameArray forKey:@"stacktrace"];
117
  [dictionary setObject:[NSNumber numberWithBool:thread.threadBlamed] forKey:@"crashed"];
118
  return dictionary;
119
}
120
 
121
- (NSArray *)getFramesOfBlamedThread {
122
  for (FIRCLSThread *thread in self.threads) {
123
    if (thread.threadBlamed) {
124
      return [self convertFramesFor:thread];
125
    }
126
  }
127
  if ([self.threads count] > 0) {
128
    return [self convertFramesFor:self.threads.firstObject];
129
  }
130
  return [NSArray array];
131
}
132
 
133
- (NSArray *)convertFramesFor:(FIRCLSThread *)thread {
134
  NSMutableArray *frames = [[NSMutableArray alloc] init];
135
  for (FIRCLSFrame *frame in thread.frames) {
136
    [frames addObject:@{
137
      @"pc" : [NSNumber numberWithLong:frame.address],
138
      @"offset" : [NSNumber numberWithLong:frame.offsetIntoBinaryTextSegment],
139
      @"line" : @0
140
    }];
141
  }
142
  return frames;
143
}
144
 
145
@end
146
 
147
#endif