<commit_before>#!/usr/bin/python

# Copyright (c) 2014, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.

import re

import lldb
import fblldbbase as fb

def lldbcommands():
  return [
    FBPrintInvocation(),
  ]

class FBPrintInvocation(fb.FBCommand):
  def name(self):
    return 'pinvocation'

  def description(self):
    return 'Print the stack frame, receiver, and arguments of the current invocation. It will fail to print all arguments if any arguments are variadic (varargs).\n\nNOTE: Sadly this is currently only implemented on x86.'

  def options(self):
    return [
            fb.FBCommandArgument(short='-a', long='--all', arg='all', default=False, boolean=True, help='Specify to print the entire stack instead of just the current frame.'),
            ]

  def run(self, arguments, options):
    target = lldb.debugger.GetSelectedTarget()

    if not re.match(r'.*i386.*', target.GetTriple()):
      print 'Only x86 is currently supported (32-bit iOS Simulator or Mac OS X).'
      return

    thread = target.GetProcess().GetSelectedThread()

    if options.all:
      for frame in thread:
        printInvocationForFrame(frame)
        print '---------------------------------'
    else:
      frame = thread.GetSelectedFrame()
      printInvocationForFrame(frame)

def printInvocationForFrame(frame):
  print frame

  symbolName = frame.GetSymbol().GetName()
  if not re.match(r'[-+]\s*\[.*\]', symbolName):
    return

  self = findArgAtIndexFromStackFrame(frame, 0)
  cmd = findArgAtIndexFromStackFrame(frame, 1)

  commandForSignature = '[(id)' + self + ' methodSignatureForSelector:(char *)sel_getName((SEL)' + cmd + ')]'
  signatureValue = fb.evaluateExpressionValue('(id)' + commandForSignature)

  if signatureValue.GetError() is not None and str(signatureValue.GetError()) != 'success':
    print "My sincerest apologies. I couldn't find a method signature for the selector."
    return

  signature = signatureValue.GetValue()

  arg0 = stackStartAddressInSelectedFrame(frame)
  commandForInvocation = '[NSInvocation _invocationWithMethodSignature:(id)' + signature + ' frame:((void *)' + str(arg0) + ')]'
  invocation = fb.evaluateExpression('(id)' + commandForInvocation)

  if invocation:
    prettyPrintInvocation(frame, invocation)
  else:
    print frame

def stackStartAddressInSelectedFrame(frame):
  # Determine if the %ebp register has already had the stack register pushed into it (always the first instruction)
  frameSymbol = frame.GetSymbolContext(0).GetSymbol()
  frameStartAddress = frameSymbol.GetStartAddress().GetLoadAddress(lldb.debugger.GetSelectedTarget())

  currentPC = frame.GetPC()

  offset = currentPC - frameStartAddress

  if offset == 0:
    return int(frame.EvaluateExpression('($esp + 4)').GetValue())
  elif offset == 1:
    return int(frame.EvaluateExpression('($esp + 8)').GetValue())
  else:
    return int(frame.EvaluateExpression('($ebp + 8)').GetValue())


def findArgAtIndexFromStackFrame(frame, index):
  return fb.evaluateExpression('*(int *)' + str(findArgAdressAtIndexFromStackFrame(frame, index)))

def findArgAdressAtIndexFromStackFrame(frame, index):
  arg0 = stackStartAddressInSelectedFrame(frame)
  arg = arg0 + 4 * index
  return arg

def prettyPrintInvocation(frame, invocation):
  object = fb.evaluateExpression('(id)[(id)' + invocation + ' target]')
  description = fb.evaluateExpressionValue('(id)' + invocation).GetObjectDescription()
  argDescriptions = description.splitlines(True)[4:]

  print 'NSInvocation: ' + invocation
  print 'self: ' + fb.evaluateExpression('(id)' + object)

  if len(argDescriptions) > 0:
    print '\n' + str(len(argDescriptions)) + ' Arguments:' if len(argDescriptions) > 1 else '\nArgument:'

    index = 2
    for argDescription in argDescriptions:
      s = re.sub(r'argument [0-9]+: ', '', argDescription)

      lldb.debugger.HandleCommand('eobjc void *$v')
      lldb.debugger.HandleCommand('eobjc (void)[' + invocation + ' getArgument:&$v atIndex:' + str(index) + ']')

      address = findArgAdressAtIndexFromStackFrame(frame, index)

      encoding = s.split(' ')[0]
      description = ' '.join(s.split(' ')[1:])

      readableString = argumentAsString(frame, address, encoding)

      if readableString:
        print readableString
      else:
        if encoding[0] == '{':
          encoding = encoding[1:]
        print (hex(address) + ', address of ' + encoding + ' ' + description).strip()

      index += 1<commit_msg>Remove old unused code from FBInvocationCommands.py<commit_after>#!/usr/bin/python

# Copyright (c) 2014, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the BSD-style license found in the
# LICENSE file in the root directory of this source tree. An additional grant
# of patent rights can be found in the PATENTS file in the same directory.

import re

import lldb
import fblldbbase as fb

def lldbcommands():
  return [
    FBPrintInvocation(),
  ]

class FBPrintInvocation(fb.FBCommand):
  def name(self):
    return 'pinvocation'

  def description(self):
    return 'Print the stack frame, receiver, and arguments of the current invocation. It will fail to print all arguments if any arguments are variadic (varargs).\n\nNOTE: Sadly this is currently only implemented on x86.'

  def options(self):
    return [
            fb.FBCommandArgument(short='-a', long='--all', arg='all', default=False, boolean=True, help='Specify to print the entire stack instead of just the current frame.'),
            ]

  def run(self, arguments, options):
    target = lldb.debugger.GetSelectedTarget()

    if not re.match(r'.*i386.*', target.GetTriple()):
      print 'Only x86 is currently supported (32-bit iOS Simulator or Mac OS X).'
      return

    thread = target.GetProcess().GetSelectedThread()

    if options.all:
      for frame in thread:
        printInvocationForFrame(frame)
        print '---------------------------------'
    else:
      frame = thread.GetSelectedFrame()
      printInvocationForFrame(frame)

def printInvocationForFrame(frame):
  print frame

  symbolName = frame.GetSymbol().GetName()
  if not re.match(r'[-+]\s*\[.*\]', symbolName):
    return

  self = findArgAtIndexFromStackFrame(frame, 0)
  cmd = findArgAtIndexFromStackFrame(frame, 1)

  commandForSignature = '[(id)' + self + ' methodSignatureForSelector:(char *)sel_getName((SEL)' + cmd + ')]'
  signatureValue = fb.evaluateExpressionValue('(id)' + commandForSignature)

  if signatureValue.GetError() is not None and str(signatureValue.GetError()) != 'success':
    print "My sincerest apologies. I couldn't find a method signature for the selector."
    return

  signature = signatureValue.GetValue()

  arg0 = stackStartAddressInSelectedFrame(frame)
  commandForInvocation = '[NSInvocation _invocationWithMethodSignature:(id)' + signature + ' frame:((void *)' + str(arg0) + ')]'
  invocation = fb.evaluateExpression('(id)' + commandForInvocation)

  if invocation:
    prettyPrintInvocation(frame, invocation)
  else:
    print frame

def stackStartAddressInSelectedFrame(frame):
  # Determine if the %ebp register has already had the stack register pushed into it (always the first instruction)
  frameSymbol = frame.GetSymbolContext(0).GetSymbol()
  frameStartAddress = frameSymbol.GetStartAddress().GetLoadAddress(lldb.debugger.GetSelectedTarget())

  currentPC = frame.GetPC()

  offset = currentPC - frameStartAddress

  if offset == 0:
    return int(frame.EvaluateExpression('($esp + 4)').GetValue())
  elif offset == 1:
    return int(frame.EvaluateExpression('($esp + 8)').GetValue())
  else:
    return int(frame.EvaluateExpression('($ebp + 8)').GetValue())


def findArgAtIndexFromStackFrame(frame, index):
  return fb.evaluateExpression('*(int *)' + str(findArgAdressAtIndexFromStackFrame(frame, index)))

def findArgAdressAtIndexFromStackFrame(frame, index):
  arg0 = stackStartAddressInSelectedFrame(frame)
  arg = arg0 + 4 * index
  return arg

def prettyPrintInvocation(frame, invocation):
  object = fb.evaluateExpression('(id)[(id)' + invocation + ' target]')
  description = fb.evaluateExpressionValue('(id)' + invocation).GetObjectDescription()
  argDescriptions = description.splitlines(True)[4:]

  print 'NSInvocation: ' + invocation
  print 'self: ' + fb.evaluateExpression('(id)' + object)

  if len(argDescriptions) > 0:
    print '\n' + str(len(argDescriptions)) + ' Arguments:' if len(argDescriptions) > 1 else '\nArgument:'

    index = 2
    for argDescription in argDescriptions:
      s = re.sub(r'argument [0-9]+: ', '', argDescription)

      address = findArgAdressAtIndexFromStackFrame(frame, index)

      encoding = s.split(' ')[0]
      description = ' '.join(s.split(' ')[1:])

      readableString = argumentAsString(frame, address, encoding)

      if readableString:
        print readableString
      else:
        if encoding[0] == '{':
          encoding = encoding[1:]
        print (hex(address) + ', address of ' + encoding + ' ' + description).strip()

      index += 1
{'fraction_non_alphanumeric': 0.1273615635179153, 'fraction_numerical': 0.008034744842562433, 'mean_word_length': 3.9870059556036814, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6322428', 'n_tokens_mistral': 2807, 'n_tokens_neox': 2609, 'n_words': 735}