class Crashreport

A class representing a crashreport

This must be initialized with the crashreport as plain text, a path where to look for .dSYM bundlles can be given. The report can be de-symbolized with symbolicate!

Attributes

identifier[R]
report[R]
shortversion[R]
version[R]

Public Class Methods

address_from_report_line(s) click to toggle source

Extracts the address from a crashreport-line

# File lib/symsym.rb, line 66
def self.address_from_report_line(s)
  a = s[/(0x[0-9a-f]+)/, 1]
  return a.hex if a
  nil
end
new(r, dsymfile=nil) click to toggle source

Creates a new Crashreport object

r is the crash report as string. dsymfile is a path where this object will look for a matching .dSYM bundle

# File lib/symsym.rb, line 75
def initialize(r, dsymfile=nil)
  @report = r
  @dsymfile = dsymfile
  @identifier         = @report[/Identifier:\s*(.*)/, 1]
  @shortversion       = @report[/Version:\s*(.*) \((.*)\)/, 1]
  @version            = @report[/Version:\s*(.*) \((.*)\)/, 2]
  findDysmFile(dsymfile)
end

Public Instance Methods

addresses() click to toggle source

returns an array of all adresses found in the crashreport

# File lib/symsym.rb, line 100
def addresses
  return @addresses if @addresses
  @addresses = []
  @report.lines.each do |l|
    a = Crashreport.address_from_report_line(l)
    @addresses << a if a
  end
  @addresses
end
findDysmFile(searchpath) click to toggle source

Find dSYM Bundle

Look for a matching dSYM bundle. Use the current directory when nil

# File lib/symsym.rb, line 87
def findDysmFile(searchpath)
  Find.find(searchpath || '.') do |f|
    if f =~ /.dSYM/
      dsymfile = DsymFile.new(f)
      if dsymfile.matches_report? self
        @dsymfile = dsymfile
        return
      end
    end
  end
end
symbolicate!() click to toggle source

de-symbolizes the crashreport

The get the report with .report aftwards

# File lib/symsym.rb, line 113
def symbolicate!
  return if @isSymbolicated
  buildgdbcommandfile
  gdbout = rungdb
  @symbols = []
  gdbout.lines.each do |l|
    @symbols << Symbolized.new(l)
  end
  
  addresses.each do |a|
    @symbols.each do |s|
      if s.startaddress  && a >= s.startaddress && a <= s.endaddress
        report.gsub!(/(0x.*#{a.to_s(16)}) (.*)/, "#{$1} #{s.symbol} (#{s.filename}:#{s.line})")
      end # address matches
    end # @symbols.each
  end# addresses.each
  @isSymbolicated = true
end

Private Instance Methods

buildgdbcommandfile() click to toggle source

build a command-file for gdb

# File lib/symsym.rb, line 141
def buildgdbcommandfile
  return if @cmdfilepath
  @cmdfilepath = '/tmp/symsymcmd.txt'
  cmdfile = File.new(@cmdfilepath, 'w+')
  self.addresses.each do |l|
    cmdfile << "info line *#{l}\n"
  end
  cmdfile.close
end
rungdb() click to toggle source

runs gdb with the command file created by buildgdbcommandfile

# File lib/symsym.rb, line 134
def rungdb
  gdbcmd = "gdb --batch --quiet -x \"#{@cmdfilepath}\" \"#{@dsymfile}\""
  gdbout = `#{gdbcmd}`
  gdbout
end