tracetool 0.4.1 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ebe6ba1b66d5457e530be1544b059cf42da169d948a651766ad57fd3c6dac99e
4
- data.tar.gz: 7b1a2cdefc535a9bb851dc212b69eaa34d89720d051936ab7d34442384db150f
3
+ metadata.gz: 99f263206633ce80bd71c6f8afd593272f91cd7b141b5ae0c2508779068eb13d
4
+ data.tar.gz: 831e703f383253e1da501115c1a339443ce4a2f06db802f7a2aa2d18de6d8ca3
5
5
  SHA512:
6
- metadata.gz: d7a9e46d22089eb1b2517edc7664e3bf26ae04e6f82e4b55aaad3e87d9119b293a9d1fdde0a8d072ebadf2ac619487c24ddf099a0184a968e638b90ba34008b3
7
- data.tar.gz: 4a187b23b271f395919265da64dc8d328b7a1b4fa4bcaf8383d33ed8e07d6c8c5dd5253e044db2d70a3efa6e6c604271b49439f7f4d01f163a5fab04761b8c9c
6
+ metadata.gz: a14938e59e1a386382905dec8dd40273c892fa59e1d54afd3bd74a634968bd94dd5af87d3fca7b5429814364e124a13f73f5b0f3bd917d5d5f0a2806194f6017
7
+ data.tar.gz: a7ae18593b8cf4d1dc918fb7fd5cb07483dfd80c28686925fa4e817e2bbd1076497b732d482f8ce7d42ce28b391d30e65f9dfcf6d8a3f353ce409a8d500dfac0
@@ -5,9 +5,10 @@ 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\.=-]+)( )?(:? (?<call_description>.+))?$}
10
- .freeze
10
+ %r{Stack frame #(?<frame>\d+) (?<address>\w+ [a-f\d]+) (?<lib>[/\w\d\._!=-]+)( )?(:? (?<call_description>.+))?$}.freeze
11
+ # rubocop:enable Metrics/LineLength
11
12
  # Describes android native method call (class::method and source file with line number)
12
13
  CALL_PATTERN = [
13
14
  /((Routine )?(?<method>.+) ((in)|(at)) (?<file>.+):(?<line>\d+))/,
@@ -92,7 +93,7 @@ module Tracetool
92
93
  # ** symbol offset `/\d+/`
93
94
  #
94
95
  # Last two entries can be missing.
95
- RX_PACKED_FORMAT = /^(<<<([-\d]+ [^ ]+ (.+)?;)+>>>)+$/.freeze
96
+ RX_PACKED_FORMAT = /^(<<<([-?\d]+ [^ ]+ (.+)?;)+>>>)+$/.freeze
96
97
 
97
98
  # @param [String] string well formed native android stack trace
98
99
  # @see https://developer.android.com/ndk/guides/ndk-stack.html
@@ -104,13 +105,7 @@ module Tracetool
104
105
  # path to symbols dir
105
106
  # @return [String] desymbolicated stack trace
106
107
  def process(ctx)
107
- symbols = File.join(ctx.symbols, 'local')
108
- symbols = if ctx.arch
109
- File.join(symbols, ctx.arch)
110
- else
111
- Dir[File.join(symbols, '*')].first || symbols
112
- end
113
- Pipe['ndk-stack', '-sym', symbols] << @trace
108
+ Pipe['ndk-stack', '-sym', ctx.symbols] << @trace
114
109
  end
115
110
 
116
111
  # Create parser for current trace format
@@ -1,3 +1,4 @@
1
+ require_relative 'ios/atos_context'
1
2
  require_relative 'ios/scanner'
2
3
  require_relative 'ios/parser'
3
4
 
@@ -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
@@ -5,7 +5,7 @@ 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>.+)$/.freeze
8
+ STACK_ENTRY_PATTERN = /^(?<frame>\d+)\t(?<binary>.+)\t(?<call_description>.+)$/.freeze
9
9
  # Describes source block
10
10
  SOURCE_PATTERN =
11
11
  /^((-?\[(?<class>[^ ]+) (?<method>.+)\])|(?<method>.+)) \(in (?<module>.+)\) \((?<file>.+):(?<line>\d+)\)$/
@@ -1,37 +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
- 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
-
35
3
  # launches atos
36
4
  class IOSTraceScanner
37
5
  # Stack trace line consists of numerous whitespace separated
@@ -44,10 +12,29 @@ module Tracetool
44
12
  # @return [Array] containing (%binary_name%, %address%) pairs
45
13
  def parse(trace)
46
14
  trace.split("\n").map do |line|
47
- line.split(' ')[1..2] # Fetch binary name and address
15
+ parse_line(line)
48
16
  end
49
17
  end
50
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
+
51
38
  def process(trace, context)
52
39
  trace = parse(trace)
53
40
  desym = run_atos(context, trace.map(&:last))
@@ -72,12 +59,7 @@ module Tracetool
72
59
  def mix(trace, symbolicated)
73
60
  trace.zip(symbolicated).map.with_index do |pair, i|
74
61
  t, desym = pair
75
- line = []
76
- line << i
77
- line << t.first
78
- line << desym
79
-
80
- line.join(' ')
62
+ "#{i}\t#{t.first}\t#{desym}"
81
63
  end
82
64
  end
83
65
  end
@@ -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[armeabi-v7a armeabi x86 arm64 x86_64].freeze
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,10 +19,10 @@ module Tracetool
19
19
  check(options)
20
20
  check_ios(options)
21
21
  options
22
- rescue OptionParser::MissingArgument => x
23
- io.write ["Error occurred: #{x.message}", '', opt_parser.help].join("\n")
22
+ rescue OptionParser::MissingArgument => e
23
+ io.write ["Error occurred: #{e.message}", '', opt_parser.help].join("\n")
24
24
  io.write "\n"
25
- raise(x)
25
+ raise(e)
26
26
  end
27
27
 
28
28
  def self.check_ios(options)
@@ -30,14 +30,14 @@ module Tracetool
30
30
 
31
31
  {
32
32
  'address' => options.address,
33
- 'module' => options.modulename
33
+ 'module' => options.modulename,
34
+ 'arch' => options.arch
34
35
  }.each { |arg, check| raise(OptionParser::MissingArgument, arg) unless check }
35
36
  end
36
37
 
37
38
  def self.check(options)
38
39
  {
39
- 'platform' => options.platform,
40
- 'arch' => options.arch
40
+ 'platform' => options.platform
41
41
  }.each { |arg, check| raise(OptionParser::MissingArgument, arg) unless check }
42
42
  end
43
43
 
@@ -1,6 +1,7 @@
1
1
  require 'open3'
2
+
2
3
  module Tracetool
3
- # helper module for launching commands
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
- args = args.join("\n") if args.is_a? Array
18
- IO.popen(cmd, 'r+') do |io|
19
- io.write(args)
20
- io.close_write
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
 
@@ -1,7 +1,7 @@
1
1
  module Tracetool
2
2
  # Version constant
3
3
  module Version
4
- VERSION = [0, 4, 1].freeze
4
+ VERSION = [0, 5, 3].freeze
5
5
 
6
6
  class << self
7
7
  # @return [String] version string
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.1
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - ilya.arkhanhelsky
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-25 00:00:00.000000000 Z
11
+ date: 2020-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: powerpack
@@ -37,6 +37,7 @@ 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
@@ -65,8 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
66
  - !ruby/object:Gem::Version
66
67
  version: '0'
67
68
  requirements: []
68
- rubyforge_project:
69
- rubygems_version: 2.7.8
69
+ rubygems_version: 3.1.2
70
70
  signing_key:
71
71
  specification_version: 4
72
72
  summary: Tracetool