symsym 0.8.0

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.
Files changed (11) hide show
  1. data/.document +5 -0
  2. data/Gemfile +10 -0
  3. data/Gemfile.lock +15 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.md +42 -0
  6. data/README.rdoc +25 -0
  7. data/Rakefile +39 -0
  8. data/VERSION +1 -0
  9. data/bin/symsym +63 -0
  10. data/lib/symsym.rb +150 -0
  11. metadata +93 -0
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "jeweler", "~> 1.6.0"
10
+ end
@@ -0,0 +1,15 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ jeweler (1.6.0)
6
+ bundler (~> 1.0.0)
7
+ git (>= 1.2.5)
8
+ rake
9
+ rake (0.8.7)
10
+
11
+ PLATFORMS
12
+ ruby
13
+
14
+ DEPENDENCIES
15
+ jeweler (~> 1.6.0)
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Ulrich Zurucker
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,42 @@
1
+ # symsym Crashreport Desymbolizer for Mac OS X
2
+
3
+ symsym is a tool for Mac OS X that allows to de-symbolize crashlogs.
4
+
5
+ ### Install
6
+
7
+ sudo gem install symsym
8
+
9
+ ## Usage
10
+
11
+ symsym will look for a dSYM bundle that matches the bundle identifier, version and short version string found in the crashreport. It will run gdb to desymbolize the addresses in the given crashlog.
12
+ The crashlog can be read from a file or from the Mac OS X pasteboard.
13
+ Output can be to a file, the OS X pasteboard or stdout
14
+
15
+ Use symsym from the command line:
16
+
17
+ * -i read crashreport from given file
18
+ * -o write de-symbolized crashreport to given file
19
+ * -p read crashreport from pasteboard
20
+ * -c write de-symbolized crashreport to pasteboard
21
+ * -d The path where symsym will look for a matching .dSYM bundle - and of course in all subfolders of this path
22
+
23
+ So when you want to replace the crashreport in your pasteboard with the de-symbolized version, go to a directory that contains your dSYM bundles, type
24
+
25
+ symsym -p -c
26
+
27
+ and you are done!
28
+
29
+ _Note:_ gdb needs the application bundle next to the dSYM bundle to be able to desymbolize the crashlog.
30
+
31
+ ## Issues/TODO
32
+
33
+ * Read the architecture from the crashreport
34
+
35
+ ## Contribute
36
+
37
+ * fork me on Github - [https://github.com/sononum/symsym](https://github.com/sononum/symsym)
38
+ * send a pull request
39
+
40
+ ## Copyright
41
+
42
+ Copyright (c) 2011 Ulrich Zurucker. See LICENSE.txt for further details.
@@ -0,0 +1,25 @@
1
+ = symsym
2
+
3
+ symsym is a tool for Mac OS X that allows to de-symbolize crashlogs.
4
+
5
+ === Usage
6
+ symsym will look for a dSYM bundle that matches the bundle identifier, version and short version string found in the crashreport. It will run gdb to desymbolize the addresses in the given crashlog.
7
+ The crashlog can be read from a file or from the Mac OS X pasteboard.
8
+ Output can be to a file, the OS X pasteboard or stdout
9
+
10
+ Use symsym from the command line:
11
+ -i read crashreport from given file
12
+ -o write de-symbolized crashreport to given file
13
+ -p read crashreport from pasteboard
14
+ -c write de-symbolized crashreport to pasteboard
15
+ -d The path where symsym will look for a matching .dSYM bundle - and of course in all subfolders of this path
16
+
17
+ == Issues/TODO
18
+
19
+ * Read the architecture from the crashreport
20
+
21
+ == Copyright
22
+
23
+ Copyright (c) 2011 Ulrich Zurucker. See LICENSE.txt for
24
+ further details.
25
+
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "symsym"
18
+ gem.homepage = "http://github.com/sononum/symsym"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Crashlog symbolizer for Mac OS X}
21
+ gem.description = %Q{symsym can be used to symbolize crashlogs from dSYM files}
22
+ gem.email = "ulizurucker@googlemail.com"
23
+ gem.authors = ["Ulrich Zurucker"]
24
+ gem.executables = ["symsym"]
25
+ gem.default_executable = 'symsym'
26
+ # dependencies defined in Gemfile
27
+ end
28
+ Jeweler::RubygemsDotOrgTasks.new
29
+
30
+
31
+ require 'rake/rdoctask'
32
+ Rake::RDocTask.new do |rdoc|
33
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
34
+
35
+ rdoc.rdoc_dir = 'rdoc'
36
+ rdoc.title = "symsym #{version}"
37
+ rdoc.rdoc_files.include('README*')
38
+ rdoc.rdoc_files.include('lib/**/*.rb')
39
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.8.0
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
+
5
+ require 'optparse'
6
+ require 'symsym'
7
+
8
+ dsymsearchpath = nil
9
+
10
+ options = {}
11
+ options[:dsymsearchpath] = "."
12
+ options[:reportfile] = nil
13
+ options[:copypasteboard] = false
14
+ options[:outputfile] = nil
15
+ report = nil
16
+
17
+ optparse = OptionParser.new do|opts|
18
+ opts.on('-h', '--help', 'Display this screen' ) do
19
+ puts opts
20
+ exit
21
+ end
22
+ opts.on('-i FILE', "Read crashlog from FILE" ) do |p|
23
+ options[:reportfile] = p
24
+ end
25
+ opts.on('-o FILE', "Write symbolized crashlog to FILE") do |p|
26
+ options[:outputfile] = p
27
+ end
28
+ opts.on('-d FILE', "dSYM Search Path - the path where symsym should look for a matching dSYM bundle. If not given, look in ." ) do |p|
29
+ options[:dsymsearchpath] = p
30
+ end
31
+ opts.on('-p', '--pasteboard', "Use pasteboard content as report input") do
32
+ report = `pbpaste`
33
+ end
34
+ opts.on('-c', '--copypasteboard', "Copy the symbolized crashlog to pasteboard") do
35
+ options[:copypasteboard] = true
36
+ end
37
+ end
38
+
39
+ optparse.parse!
40
+
41
+ unless report
42
+ reportfile = options[:reportfile]
43
+ if reportfile && File.exist?(reportfile)
44
+ report = File.new(reportfile).read
45
+ else
46
+ puts "No input crashlog given. Use --help for usage."
47
+ end
48
+ end
49
+
50
+ exit(1) unless report
51
+
52
+ report = Crashreport.new(report, options[:dsymsearchpath])
53
+ report.symbolicate!
54
+
55
+ if (options[:copypasteboard])
56
+ IO.popen('pbcopy', 'r+').puts report.report
57
+ end
58
+
59
+ if (options[:outputfile])
60
+ File.new(options[:outputfile], 'w+').puts report.report
61
+ end
62
+
63
+ puts report.report unless options[:copypasteboard] || options[:outputfile]
@@ -0,0 +1,150 @@
1
+ require 'osx/cocoa'
2
+ require 'find'
3
+
4
+ # DsymFile - wrapper around a .dSYM bundle
5
+ #
6
+ #
7
+ class DsymFile
8
+ attr_reader :identifier, :version, :shortversionstring
9
+
10
+ # Initializes a DsymFile with a path to a dSYM Bundle
11
+ #
12
+ # Extracts CFBundleIdentifier, CFBundleVersion and CFBundleShortVersionString from the Info.plist file inside the bundle
13
+ def initialize(filename)
14
+ @info_plist = OSX::NSDictionary.dictionaryWithContentsOfFile(File.join(filename, 'Contents/Info.plist'))
15
+ return unless @info_plist
16
+ @identifier = @info_plist['CFBundleIdentifier'].to_s
17
+ @version = @info_plist['CFBundleVersion'].to_s
18
+ @shortversionstring = @info_plist['CFBundleShortVersionString'].to_s
19
+ @filename = filename
20
+ end # initialize
21
+
22
+ # Matches Report?
23
+ #
24
+ # Checks if the Bundle Identifier, Bundle Version and Bundle Short Version String of a given Crashreport matches to this dSYM Bundle
25
+ def matches_report?(report)
26
+ false
27
+ true if @identifier =~ /#{report.identifier}/ && @version == report.version && @shortversionstring == report.shortversion
28
+ end
29
+
30
+ # return the filename
31
+ def to_s
32
+ @filename
33
+ end
34
+ end # class DsymFile
35
+
36
+ # Symbolized
37
+ #
38
+ # A symbol of the Crashreport that has been desymbolized with gdb
39
+ class Symbolized
40
+ attr_reader :startaddress, :endaddress, :line, :symbol, :filename
41
+ # Initialize with an output line from gdb. This will extract the addresses, linenumber and source-file
42
+ def initialize(s)
43
+ s.gsub(/Line (\d*) of "(.*)" starts at address (0x[0-9a-f]*) <(.*)> and ends at (0x[0-9a-f]*)/).to_a
44
+ @line = $1
45
+ @filename = $2
46
+ @startaddress = $3.hex if $3
47
+ @symbol = $4
48
+ @endaddress = $5.hex if $3
49
+ end
50
+ end
51
+
52
+ # A class representing a crashreport
53
+ #
54
+ # This must be initialized with the crashreport as plain text, a path where to look for .dSYM bundlles can be given.
55
+ # The report can be de-symbolized with symbolicate!
56
+ class Crashreport
57
+
58
+ @addresses = nil
59
+ @dsymfile = nil
60
+ @isSymbolicated = false;
61
+ @cmdfilepath = nil;
62
+
63
+ attr_reader :identifier, :version, :shortversion, :report
64
+
65
+ # Extracts the address from a crashreport-line
66
+ def self.address_from_report_line(s)
67
+ a = s[/(0x[0-9a-f]+)/, 1]
68
+ return a.hex if a
69
+ nil
70
+ end
71
+
72
+ # Creates a new Crashreport object
73
+ #
74
+ # r is the crash report as string. dsymfile is a path where this object will look for a matching .dSYM bundle
75
+ def initialize(r, dsymfile=nil)
76
+ @report = r
77
+ @dsymfile = dsymfile
78
+ @identifier = @report[/Identifier: (.*)/, 1]
79
+ @shortversion = @report[/Version: (.*) \((.*)\)/, 1]
80
+ @version = @report[/Version: (.*) \((.*)\)/, 2]
81
+ findDysmFile(dsymfile)
82
+ end
83
+
84
+ # Find dSYM Bundle
85
+ #
86
+ # Look for a matching dSYM bundle. Use the current directory when nil
87
+ def findDysmFile(searchpath)
88
+ Find.find(searchpath || '.') do |f|
89
+ if f =~ /.dSYM/
90
+ dsymfile = DsymFile.new(f)
91
+ if dsymfile.matches_report? self
92
+ @dsymfile = dsymfile
93
+ return
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ # returns an array of all adresses found in the crashreport
100
+ def addresses
101
+ return @addresses if @addresses
102
+ @addresses = []
103
+ @report.lines.each do |l|
104
+ a = Crashreport.address_from_report_line(l)
105
+ @addresses << a if a
106
+ end
107
+ @addresses
108
+ end
109
+
110
+ # de-symbolizes the crashreport
111
+ #
112
+ # The get the report with .report aftwards
113
+ def symbolicate!
114
+ return if @isSymbolicated
115
+ buildgdbcommandfile
116
+ gdbout = rungdb
117
+ @symbols = []
118
+ gdbout.lines.each do |l|
119
+ @symbols << Symbolized.new(l)
120
+ end
121
+
122
+ addresses.each do |a|
123
+ @symbols.each do |s|
124
+ if s.startaddress && a >= s.startaddress && a <= s.endaddress
125
+ report.gsub!(/(0x.*#{a.to_s(16)}) (.*)/, "#{$1} #{s.symbol} (#{s.filename}:#{s.line})")
126
+ end # address matches
127
+ end # @symbols.each
128
+ end# addresses.each
129
+ @isSymbolicated = true
130
+ end # symbolicate!
131
+
132
+ private
133
+ # runs gdb with the command file created by buildgdbcommandfile
134
+ def rungdb
135
+ gdbcmd = "gdb --batch --quiet -x \"#{@cmdfilepath}\" \"#{@dsymfile}\""
136
+ gdbout = `#{gdbcmd}`
137
+ gdbout
138
+ end
139
+
140
+ # build a command-file for gdb
141
+ def buildgdbcommandfile
142
+ return if @cmdfilepath
143
+ @cmdfilepath = '/tmp/symsymcmd.txt'
144
+ cmdfile = File.new(@cmdfilepath, 'w+')
145
+ self.addresses.each do |l|
146
+ cmdfile << "info line *#{l}\n"
147
+ end
148
+ cmdfile.close
149
+ end # buildgdbcommandfile
150
+ end # class Crashreport
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: symsym
3
+ version: !ruby/object:Gem::Version
4
+ hash: 63
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 8
9
+ - 0
10
+ version: 0.8.0
11
+ platform: ruby
12
+ authors:
13
+ - Ulrich Zurucker
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-05-09 00:00:00 +02:00
19
+ default_executable: symsym
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ type: :development
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 15
30
+ segments:
31
+ - 1
32
+ - 6
33
+ - 0
34
+ version: 1.6.0
35
+ name: jeweler
36
+ version_requirements: *id001
37
+ description: symsym can be used to symbolize crashlogs from dSYM files
38
+ email: ulizurucker@googlemail.com
39
+ executables:
40
+ - symsym
41
+ extensions: []
42
+
43
+ extra_rdoc_files:
44
+ - LICENSE.txt
45
+ - README.md
46
+ - README.rdoc
47
+ files:
48
+ - .document
49
+ - Gemfile
50
+ - Gemfile.lock
51
+ - LICENSE.txt
52
+ - README.md
53
+ - README.rdoc
54
+ - Rakefile
55
+ - VERSION
56
+ - bin/symsym
57
+ - lib/symsym.rb
58
+ has_rdoc: true
59
+ homepage: http://github.com/sononum/symsym
60
+ licenses:
61
+ - MIT
62
+ post_install_message:
63
+ rdoc_options: []
64
+
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ hash: 3
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ hash: 3
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ requirements: []
86
+
87
+ rubyforge_project:
88
+ rubygems_version: 1.5.2
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: Crashlog symbolizer for Mac OS X
92
+ test_files: []
93
+