tracetool 0.4.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/lib/tracetool/android.rb +2 -0
- data/lib/tracetool/android/java.rb +10 -6
- data/lib/tracetool/android/native.rb +19 -16
- data/lib/tracetool/ios.rb +1 -0
- data/lib/tracetool/ios/atos_context.rb +35 -0
- data/lib/tracetool/ios/parser.rb +2 -1
- data/lib/tracetool/ios/scanner.rb +20 -34
- data/lib/tracetool/utils/cli.rb +9 -8
- data/lib/tracetool/utils/parser.rb +50 -19
- data/lib/tracetool/utils/pipe.rb +6 -7
- data/lib/tracetool/utils/string.rb +24 -0
- data/lib/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7b0baff5d5f633d2474acf70b639fad429dd09b5b4cc4f80333ef55f72c1e5d8
|
4
|
+
data.tar.gz: 2851ab0c1b575429400937ad889b0a06fdce6f9ebaf550b05956b7879166d6f6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba21b749c8875fec7e26c70da2899dfb89ea5c0fcfed2a7fc1233b34ee222d5de43cf630fc13998cf3e95335eee152e75e7fdfea8e998867ccfbd3c581eb3a1b
|
7
|
+
data.tar.gz: 7f0236c1c234fa42c8fc68874cbc63e0271c773078c64cf50a5bea4e1d6951757affb02064360590c5668e559633e85b6a237d6dff7d901edfe23fbf7a522888
|
data/lib/tracetool/android.rb
CHANGED
@@ -16,6 +16,7 @@ module Tracetool
|
|
16
16
|
# Find scanner which matches trace format
|
17
17
|
@scanner = SCANNERS.map { |s| s[trace] }.compact.first
|
18
18
|
raise(ArgumentError, "#{trace}\n not android trace?") unless @scanner
|
19
|
+
|
19
20
|
@scanner.process(context)
|
20
21
|
end
|
21
22
|
|
@@ -25,6 +26,7 @@ module Tracetool
|
|
25
26
|
# Or `nil`. If there was no scanning.
|
26
27
|
def parser(files)
|
27
28
|
return unless @scanner
|
29
|
+
|
28
30
|
@scanner.parser(files)
|
29
31
|
end
|
30
32
|
end
|
@@ -5,9 +5,9 @@ module Tracetool
|
|
5
5
|
# Parses java stack traces
|
6
6
|
class JavaTraceParser < Tracetool::BaseTraceParser
|
7
7
|
# Describes java stack entry
|
8
|
-
STACK_ENTRY_PATTERN = /^(\s+at (?<call_description>.+))|((?<error>.+?): (?<message>.+))
|
8
|
+
STACK_ENTRY_PATTERN = /^(\s+at (?<call_description>.+))|((?<error>.+?): (?<message>.+))$/.freeze
|
9
9
|
# Describes java method call
|
10
|
-
CALL_PATTERN = /(?<class>.+)\.(?<method>[^\(]+)\((((?<file>.+\.java):(?<line>\d+))|(?<location>.+))\)
|
10
|
+
CALL_PATTERN = /(?<class>.+)\.(?<method>[^\(]+)\((((?<file>.+\.java):(?<line>\d+))|(?<location>.+))\)$/.freeze
|
11
11
|
|
12
12
|
def initialize(files)
|
13
13
|
super(STACK_ENTRY_PATTERN, CALL_PATTERN, files, true)
|
@@ -15,8 +15,14 @@ module Tracetool
|
|
15
15
|
end
|
16
16
|
# Processes java traces
|
17
17
|
class JavaTraceScanner
|
18
|
-
|
19
|
-
|
18
|
+
# Usually java trace starts with
|
19
|
+
# com.something.SomeClass(: Some message)?
|
20
|
+
RX_FIRST_EXCEPTION_LINE = /^([a-zA-Z.]*)(:.*)?$/.freeze
|
21
|
+
|
22
|
+
# Rest is expanded as
|
23
|
+
# at com.other.OtherClass.someMethod(OtherClass.java:42)
|
24
|
+
# Source marker can be just "Native Method" or "Unknown Source"
|
25
|
+
RX_OTHER_EXCEPTION_LINE = /((at [a-zA-Z$.]+)|(Caused by:)|(\.\.\. [0-9]* more))(.+)?$/.freeze
|
20
26
|
|
21
27
|
def initialize(string)
|
22
28
|
@trace = string
|
@@ -38,8 +44,6 @@ module Tracetool
|
|
38
44
|
def match(string)
|
39
45
|
# Split into lines
|
40
46
|
first, *rest = string.split("\n")
|
41
|
-
|
42
|
-
return if rest.nil? || rest.empty?
|
43
47
|
return unless RX_FIRST_EXCEPTION_LINE.match(first)
|
44
48
|
|
45
49
|
rest.all? { |line| RX_OTHER_EXCEPTION_LINE.match(line) }
|
@@ -5,10 +5,15 @@ module Tracetool
|
|
5
5
|
# Android traces scanner and mapper
|
6
6
|
class NativeTraceParser < Tracetool::BaseTraceParser
|
7
7
|
# Describes android stack entry
|
8
|
+
# rubocop:disable Metrics/LineLength
|
8
9
|
STACK_ENTRY_PATTERN =
|
9
|
-
%r{Stack frame #(?<frame>\d+) (?<address>\w+ [a-f\d]+) (?<lib>[/\w\d
|
10
|
+
%r{Stack frame #(?<frame>\d+) (?<address>\w+ [a-f\d]+) (?<lib>[/\w\d\._!=-]+)( )?(:? (?<call_description>.+))?$}.freeze
|
11
|
+
# rubocop:enable Metrics/LineLength
|
10
12
|
# Describes android native method call (class::method and source file with line number)
|
11
|
-
CALL_PATTERN =
|
13
|
+
CALL_PATTERN = [
|
14
|
+
/((Routine )?(?<method>.+) ((in)|(at)) (?<file>.+):(?<line>\d+))/,
|
15
|
+
/(?<method>.+?) \d+/
|
16
|
+
].freeze
|
12
17
|
|
13
18
|
def initialize(files)
|
14
19
|
super(STACK_ENTRY_PATTERN, CALL_PATTERN, files, true)
|
@@ -30,7 +35,9 @@ module Tracetool
|
|
30
35
|
# @param [String] trace packed stack trace
|
31
36
|
# @return well formed stack trace
|
32
37
|
def unpack(trace)
|
33
|
-
dump_body = prepare(trace)
|
38
|
+
dump_body = prepare(trace)
|
39
|
+
.map
|
40
|
+
.with_index { |line, index| convert_line(line, index) }
|
34
41
|
add_header(dump_body.join("\n"))
|
35
42
|
end
|
36
43
|
|
@@ -48,8 +55,9 @@ module Tracetool
|
|
48
55
|
def convert_line(line, index)
|
49
56
|
frame = index
|
50
57
|
addr = line[/^(-?\d+) (.*)$/, 1]
|
51
|
-
lib = line[/^(-?\d+) (.*)$/, 2].strip
|
52
|
-
' #%
|
58
|
+
lib = (line[/^(-?\d+) (.*)$/, 2] || '').strip # nil safe
|
59
|
+
' #%02<frame>i pc %08<addr>x %<lib>s'
|
60
|
+
.format(frame: frame, addr: addr, lib: lib)
|
53
61
|
end
|
54
62
|
|
55
63
|
# If needed here we'll drop all unneeded leading characters from each
|
@@ -63,14 +71,15 @@ module Tracetool
|
|
63
71
|
# Processes native traces
|
64
72
|
class NativeTraceScanner
|
65
73
|
# Initial sequence of asterisks which marks begining of trace body
|
66
|
-
TRACE_DELIMETER =
|
67
|
-
|
74
|
+
TRACE_DELIMETER =
|
75
|
+
'*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***'.freeze
|
76
|
+
RX_INITIAL_ASTERISKS = /#{TRACE_DELIMETER.gsub('*', '\*')}/.freeze
|
68
77
|
# Contains address line like
|
69
78
|
#
|
70
79
|
# ```
|
71
80
|
# pc 00000000004321ec libfoo.so
|
72
81
|
# ```
|
73
|
-
RX_PC_ADDRESS = /pc \d
|
82
|
+
RX_PC_ADDRESS = /pc \d+/.freeze
|
74
83
|
|
75
84
|
# Format of packed trace.
|
76
85
|
# Consists of one or more trace blocks.
|
@@ -84,7 +93,7 @@ module Tracetool
|
|
84
93
|
# ** symbol offset `/\d+/`
|
85
94
|
#
|
86
95
|
# Last two entries can be missing.
|
87
|
-
RX_PACKED_FORMAT = /^(<<<(
|
96
|
+
RX_PACKED_FORMAT = /^(<<<([-?\d]+ [^ ]+ (.+)?;)+>>>)+$/.freeze
|
88
97
|
|
89
98
|
# @param [String] string well formed native android stack trace
|
90
99
|
# @see https://developer.android.com/ndk/guides/ndk-stack.html
|
@@ -96,13 +105,7 @@ module Tracetool
|
|
96
105
|
# path to symbols dir
|
97
106
|
# @return [String] desymbolicated stack trace
|
98
107
|
def process(ctx)
|
99
|
-
|
100
|
-
symbols = if ctx.arch
|
101
|
-
File.join(symbols, ctx.arch)
|
102
|
-
else
|
103
|
-
Dir[File.join(symbols, '*')].first || symbols
|
104
|
-
end
|
105
|
-
Pipe['ndk-stack', '-sym', symbols] << @trace
|
108
|
+
Pipe['ndk-stack', '-sym', ctx.symbols] << @trace
|
106
109
|
end
|
107
110
|
|
108
111
|
# Create parser for current trace format
|
data/lib/tracetool/ios.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
module Tracetool
|
2
|
+
module IOS
|
3
|
+
# Converts context to atos arguments
|
4
|
+
class AtosContext
|
5
|
+
# If no arch specified will use `arm64`
|
6
|
+
DEFAULT_ARCH = 'arm64'.freeze
|
7
|
+
|
8
|
+
# List of required argument names
|
9
|
+
REQUIRED_ARGUMENTS = %i[load_address xarchive module_name].freeze
|
10
|
+
|
11
|
+
def initialize(ctx)
|
12
|
+
check_arguments(ctx)
|
13
|
+
@load_address = ctx.load_address
|
14
|
+
@binary_path = module_binary(ctx.xarchive, ctx.module_name)
|
15
|
+
@arch = ctx.arch || 'arm64'
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_args
|
19
|
+
%w[-o -l -arch].zip([@binary_path, @load_address, @arch]).flatten
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def module_binary(xarchive, module_name)
|
25
|
+
File.join(xarchive, 'dSYMs', "#{module_name}.app.dSYM", 'Contents', 'Resources', 'DWARF', module_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def check_arguments(ctx)
|
29
|
+
REQUIRED_ARGUMENTS.each do |a|
|
30
|
+
ctx[a] || raise(ArgumentError, "Missing `#{a}` value")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/tracetool/ios/parser.rb
CHANGED
@@ -5,10 +5,11 @@ module Tracetool
|
|
5
5
|
# IOS traces scanner and source mapper
|
6
6
|
class IOSTraceParser < Tracetool::BaseTraceParser
|
7
7
|
# Describes IOS stack entry
|
8
|
-
STACK_ENTRY_PATTERN = /^(?<frame>\d+) (?<binary>[^ ]+) (?<call_description>.+)
|
8
|
+
STACK_ENTRY_PATTERN = /^(?<frame>\d+) (?<binary>[^ ]+) (?<call_description>.+)$/.freeze
|
9
9
|
# Describes source block
|
10
10
|
SOURCE_PATTERN =
|
11
11
|
/^((-?\[(?<class>[^ ]+) (?<method>.+)\])|(?<method>.+)) \(in (?<module>.+)\) \((?<file>.+):(?<line>\d+)\)$/
|
12
|
+
.freeze
|
12
13
|
|
13
14
|
def initialize(files)
|
14
15
|
super(STACK_ENTRY_PATTERN, SOURCE_PATTERN, files, true)
|
@@ -1,38 +1,5 @@
|
|
1
1
|
module Tracetool
|
2
2
|
module IOS
|
3
|
-
# Converts context to atos arguments
|
4
|
-
class AtosContext
|
5
|
-
# If no arch specified will use `arm64`
|
6
|
-
DEFAULT_ARCH = 'arm64'.freeze
|
7
|
-
|
8
|
-
# List of required argument names
|
9
|
-
REQUIRED_ARGUMENTS = %i[load_address xarchive module_name].freeze
|
10
|
-
|
11
|
-
#
|
12
|
-
def initialize(ctx)
|
13
|
-
check_arguments(ctx)
|
14
|
-
@load_address = ctx.load_address
|
15
|
-
@binary_path = module_binary(ctx.xarchive, ctx.module_name)
|
16
|
-
@arch = ctx.arch || 'arm64'
|
17
|
-
end
|
18
|
-
|
19
|
-
def to_args
|
20
|
-
%w[-o -l -arch].zip([@binary_path, @load_address, @arch]).flatten
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def module_binary(xarchive, module_name)
|
26
|
-
File.join(xarchive, 'dSYMs', "#{module_name}.app.dSYM", 'Contents', 'Resources', 'DWARF', module_name)
|
27
|
-
end
|
28
|
-
|
29
|
-
def check_arguments(ctx)
|
30
|
-
REQUIRED_ARGUMENTS.each do |a|
|
31
|
-
ctx[a] || raise(ArgumentError, "Missing `#{a}` value")
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
3
|
# launches atos
|
37
4
|
class IOSTraceScanner
|
38
5
|
# Stack trace line consists of numerous whitespace separated
|
@@ -45,10 +12,29 @@ module Tracetool
|
|
45
12
|
# @return [Array] containing (%binary_name%, %address%) pairs
|
46
13
|
def parse(trace)
|
47
14
|
trace.split("\n").map do |line|
|
48
|
-
line
|
15
|
+
parse_line(line)
|
49
16
|
end
|
50
17
|
end
|
51
18
|
|
19
|
+
# Parse trace line from trace. Which usualy looks like this:
|
20
|
+
# 3 My Module Name 0x0000000102d6e9f4 My Module Name + 5859828
|
21
|
+
# We need to fetch two values: 'My Module Name' and '0x0000000102d6e9f4'.
|
22
|
+
def parse_line(line)
|
23
|
+
parts = line.split(' ')
|
24
|
+
parts.shift # Frame number, not needed
|
25
|
+
|
26
|
+
module_name = ''
|
27
|
+
|
28
|
+
until parts.first.start_with?('0x')
|
29
|
+
module_name += parts.shift
|
30
|
+
module_name += ' '
|
31
|
+
end
|
32
|
+
|
33
|
+
address = parts.shift
|
34
|
+
|
35
|
+
[module_name.chop, address]
|
36
|
+
end
|
37
|
+
|
52
38
|
def process(trace, context)
|
53
39
|
trace = parse(trace)
|
54
40
|
desym = run_atos(context, trace.map(&:last))
|
data/lib/tracetool/utils/cli.rb
CHANGED
@@ -6,8 +6,8 @@ require_relative '../../version'
|
|
6
6
|
module Tracetool
|
7
7
|
# Tracetool cli args parser
|
8
8
|
class ParseArgs
|
9
|
-
# List of supported abis
|
10
|
-
ARCH_LIST = %i[
|
9
|
+
# List of supported abis. Only needed for iOS unpacking
|
10
|
+
ARCH_LIST = %i[arm arm64].freeze
|
11
11
|
#
|
12
12
|
# Return a structure describing the options.
|
13
13
|
#
|
@@ -19,24 +19,25 @@ module Tracetool
|
|
19
19
|
check(options)
|
20
20
|
check_ios(options)
|
21
21
|
options
|
22
|
-
rescue OptionParser::MissingArgument =>
|
23
|
-
io.write ["Error occurred: #{
|
22
|
+
rescue OptionParser::MissingArgument => e
|
23
|
+
io.write ["Error occurred: #{e.message}", '', opt_parser.help].join("\n")
|
24
24
|
io.write "\n"
|
25
|
-
raise(
|
25
|
+
raise(e)
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.check_ios(options)
|
29
29
|
return unless options.platform == :ios
|
30
|
+
|
30
31
|
{
|
31
32
|
'address' => options.address,
|
32
|
-
'module' =>
|
33
|
+
'module' => options.modulename,
|
34
|
+
'arch' => options.arch
|
33
35
|
}.each { |arg, check| raise(OptionParser::MissingArgument, arg) unless check }
|
34
36
|
end
|
35
37
|
|
36
38
|
def self.check(options)
|
37
39
|
{
|
38
|
-
'platform' => options.platform
|
39
|
-
'arch' => options.arch
|
40
|
+
'platform' => options.platform
|
40
41
|
}.each { |arg, check| raise(OptionParser::MissingArgument, arg) unless check }
|
41
42
|
end
|
42
43
|
|
@@ -1,12 +1,16 @@
|
|
1
|
+
require_relative 'string'
|
2
|
+
|
1
3
|
module Tracetool
|
2
4
|
# Base trace parser logic
|
3
5
|
class BaseTraceParser
|
6
|
+
include StringUtils
|
7
|
+
|
4
8
|
attr_reader :entry_pattern, :call_pattern
|
5
9
|
|
6
10
|
def initialize(entry_pattern, call_pattern, build_files, convert_numbers = false)
|
7
11
|
@build_files = build_files
|
8
12
|
@entry_pattern = entry_pattern
|
9
|
-
@call_pattern = call_pattern
|
13
|
+
@call_pattern = call_pattern.is_a?(Array) ? call_pattern : [call_pattern]
|
10
14
|
@convert_numbers = convert_numbers
|
11
15
|
end
|
12
16
|
|
@@ -54,36 +58,63 @@ module Tracetool
|
|
54
58
|
# * method
|
55
59
|
# * file
|
56
60
|
# * line number
|
57
|
-
def scan_call(
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
61
|
+
def scan_call(call_info)
|
62
|
+
call_description = call_info[:call_description]
|
63
|
+
# TODO: Lazy check
|
64
|
+
match = call_description && call_pattern.map { |p| p.match(call_description) }.compact.first
|
65
|
+
if match
|
66
|
+
call = extract_groups(match)
|
67
|
+
# Update file entry with expanded path
|
68
|
+
call[:file] = find_file(call[:file]) if call[:file]
|
69
|
+
|
70
|
+
call_info[:call] = call
|
66
71
|
end
|
67
72
|
|
68
|
-
|
73
|
+
call_info
|
69
74
|
end
|
70
75
|
|
71
76
|
# Find file with specified file name in symbols dir
|
72
|
-
# Can return multiple files if name was
|
77
|
+
# Can return multiple files if name was ambiguous
|
73
78
|
def find_file(file)
|
74
|
-
|
75
|
-
#
|
76
|
-
|
77
|
-
|
78
|
-
files =
|
79
|
+
file_name = File.basename(file)
|
80
|
+
# Firstly we'll drop obvious mismatches where basename of file differs
|
81
|
+
candidates = @build_files.select { |path| File.basename(path) == file_name }
|
82
|
+
# In case when got ambiguous files return all try to find closest match
|
83
|
+
files = find_closest_files(file, candidates)
|
79
84
|
|
80
85
|
# If has only option return first
|
81
86
|
return files.first if files.size == 1
|
82
87
|
# Return original file if files empty
|
83
88
|
return file if files.empty?
|
84
89
|
|
85
|
-
#
|
86
|
-
|
90
|
+
files # Return all files if many matched
|
91
|
+
end
|
92
|
+
|
93
|
+
# Select from candidates list such files
|
94
|
+
# that ends with maximum substring of file
|
95
|
+
# @param [String] file file path to match
|
96
|
+
# @param [Array<String>] candidates list of candidates path
|
97
|
+
# @return [Array<String>] list of files with maximum length matches
|
98
|
+
def find_closest_files(file, candidates)
|
99
|
+
candidates.inject([[], 0]) do |acc, elem|
|
100
|
+
# Current element score is length of longest common postfix
|
101
|
+
elem_score = file.longest_common_postfix(elem).length
|
102
|
+
|
103
|
+
# Unpack accumulator as (list_of_matched_files, max_score)
|
104
|
+
matched, score = acc
|
105
|
+
# Will update if only have better score
|
106
|
+
if elem_score >= score
|
107
|
+
# Current score more than last known score, so now
|
108
|
+
# we drop all previous results and replace them with
|
109
|
+
# current element
|
110
|
+
matched = [] if elem_score > score
|
111
|
+
score = elem_score
|
112
|
+
# Update list of matched
|
113
|
+
matched << elem
|
114
|
+
end
|
115
|
+
|
116
|
+
[matched, score]
|
117
|
+
end.first
|
87
118
|
end
|
88
119
|
|
89
120
|
def extract_groups(match)
|
data/lib/tracetool/utils/pipe.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'open3'
|
2
|
+
|
2
3
|
module Tracetool
|
3
|
-
#
|
4
|
+
# Helper module for launching commands
|
4
5
|
module Pipe
|
5
6
|
# Executes shell command
|
6
7
|
class Executor
|
@@ -14,12 +15,10 @@ module Tracetool
|
|
14
15
|
end
|
15
16
|
|
16
17
|
def <<(args)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
io.read.chomp
|
22
|
-
end
|
18
|
+
out, err, status = Open3.capture3({}, *cmd, stdin_data: args)
|
19
|
+
raise "#{cmd.join(' ')} (exit: #{status.exitstatus}) #{err.chomp}" unless status.success?
|
20
|
+
|
21
|
+
out.chomp
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Tracetool
|
2
|
+
# Set of utility methods for working with strings
|
3
|
+
module StringUtils
|
4
|
+
# Extended string class
|
5
|
+
# rubocop:disable Style/ClassAndModuleChildren
|
6
|
+
class ::String
|
7
|
+
# Return longest common postfix
|
8
|
+
# @param [String] other other string to match
|
9
|
+
# @return [String] longest common postfix
|
10
|
+
def longest_common_postfix(other)
|
11
|
+
sidx = length - 1
|
12
|
+
oidx = other.length - 1
|
13
|
+
|
14
|
+
while sidx >= 0 && oidx >= 0 && (self[sidx] == other[oidx])
|
15
|
+
sidx -= 1
|
16
|
+
oidx -= 1
|
17
|
+
end
|
18
|
+
|
19
|
+
other[(oidx + 1)..-1]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
# rubocop:enable Style/ClassAndModuleChildren
|
23
|
+
end
|
24
|
+
end
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tracetool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ilya.arkhanhelsky
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: powerpack
|
@@ -37,12 +37,14 @@ files:
|
|
37
37
|
- lib/tracetool/android/java.rb
|
38
38
|
- lib/tracetool/android/native.rb
|
39
39
|
- lib/tracetool/ios.rb
|
40
|
+
- lib/tracetool/ios/atos_context.rb
|
40
41
|
- lib/tracetool/ios/parser.rb
|
41
42
|
- lib/tracetool/ios/scanner.rb
|
42
43
|
- lib/tracetool/utils/cli.rb
|
43
44
|
- lib/tracetool/utils/env.rb
|
44
45
|
- lib/tracetool/utils/parser.rb
|
45
46
|
- lib/tracetool/utils/pipe.rb
|
47
|
+
- lib/tracetool/utils/string.rb
|
46
48
|
- lib/tracetool_cli.rb
|
47
49
|
- lib/version.rb
|
48
50
|
homepage: https://github.com/vizor-games/tracetool
|
@@ -64,8 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
66
|
- !ruby/object:Gem::Version
|
65
67
|
version: '0'
|
66
68
|
requirements: []
|
67
|
-
|
68
|
-
rubygems_version: 2.6.13
|
69
|
+
rubygems_version: 3.1.2
|
69
70
|
signing_key:
|
70
71
|
specification_version: 4
|
71
72
|
summary: Tracetool
|