SourceKitService Consumes CPU and Grinds Xcode to a Halt - ios

This is NOT a Beta issue. I am on Xcode 6.0.1, production release. The issue I am having is that when I try to do a Build or Run the code I am working on, Xcode becomes unresponsive for large periods of time and the SourceKitService consumes upwards of 400% of the CPU (according to Activity Monitor). This issue is new as of the last few days, although, oddly, I had been on Xcode 6.0 since it was officially released on Sept 17. I upgraded to 6.0.1 hoping it would contain a fix for this issue.
Any idea as to what the problem could be?

Ran into this problem with Xcode 6.1.1 earlier this afternoon (not beta, official released version). I had been running some code on Playground and was suspecting that to be the cause. CPU was pegged to nearly 100%, and Xcode was unable to complete builds.
So here's what I did:
1. Opened "Activity Monitor", which showed SourceKitService as the main CPU hog.
2. Within "Activity Monitor", double-clicked on the SourceKitService and clicked on "Open Files and Ports" section, which showed it was working on files under the /Users/myname/Library/Developer/Xcode/DerivedData/ModuleCache/ directory for a specific folder.
3. Deleted the specified folder (from a command-line, using rm -rf). The cache is regenerated based on Can I safely delete contents of Xcode Derived data folder? .
4. Using Activity Monitor again, Force-Quit SourceKitServer. Saw the now-all-too-familiar sign within Xcode saying that SourceKitService had crashed (so that's why SourceKitService sounded familiar!).
5. Repeated step 3.
The Mac is peaceful, again. No data was lost and Xcode didn't even have to be restarted (which I had tried unsuccessfully). Bottom line is that ModuleCache seems to be getting SourceKitService in a loop and deleting the folder seems to fix it. Hope this works for you too.
Bootnote:By the way, the cause for SourceKitService issue was that I had too long an array declaration in my Swift class. I had over 200 entries in an array. Reduced it to 30 and the error went away. So the issue may have arisen due to some kind of stack overflow in apple code (pun intended).

I was seeing the problem because I was declaring an array with about 60 elements that looked like this:
let byteMap = [
["ECG" : (0,12)],
["PPG" : (12,3)],
["ECG" : (15,12)],
["PPG" : (27,3)],
["ECG" : (30,12)]
By explicitly annotating the type like this:
let byteMap : [String: (Int, Int)] = [
["ECG" : (0,12)],
["PPG" : (12,3)],
["ECG" : (15,12)],
["PPG" : (27,3)],
["ECG" : (30,12)],
I was able to make it stop. I think it must have something to do with Swift's type-inference and type-checking that makes it go into a loop when it encounters a longish array.
This was in Xcode 6.2. I also deleted the ModuleCache as described above and now everything is good.

This problem happened like 10 times, 8 times it happened when I connected an actual device and didn't run through simulator.
I am not so sure if my solution is a good one, but for me I believe the problem was due to switching between simulator and an actual device. It may sound weird but it was as if it was creating interference between cache files.
What solved my problem:
Clean Build Folder:( on Xcode) Alt + Shift + Command + K
Reset Content and Settings: (on
Simulator) Command + Shift + K.
Waited a bit longer than normal and overload Xcode with constant clicks
So basically before you try to run on any new device, just delete any cache.
EDIT
I just had the problem without any device connection. I just quit Xcode and opened it again and the problem was gone. Not sure my guess is it could be some re-indexing issue after you fetch/pull merge new code.

I resolved another issue that was causing SourceKitService use up to 13GB of memory...
I had String(format line with lots of arguments:
return String(format: "%d,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f", samples.count,sum1.x,sum1.y,sum1.z,sum1.rx,sum1.ry,sum1.rz,sum2.x,sum2.y,sum2.z,sum2.rx,sum2.ry,sum2.rz,sum3.x,sum3.y,sum3.z,sum3.rx,sum3.ry,sum3.rz)
when replaced with this it worked fine (no memory build up and normal CPU consumption)
var output: String = ""
output += String(format: "%d,", samples.count)
output += String(format: "%.3f,%.3f,%.3f,", sum1.x, sum1.y, sum1.z)
output += String(format: "%.3f,%.3f,%.3f,", sum1.rx, sum1.ry, sum1.rz)
output += String(format: "%.3f,%.3f,%.3f,", sum2.x, sum2.y, sum2.z)
output += String(format: "%.3f,%.3f,%.3f,", sum2.rx, sum2.ry, sum2.rz)
output += String(format: "%.3f,%.3f,%.3f,", sum3.x, sum3.y, sum3.z)
output += String(format: "%.3f,%.3f,%.3f", sum3.rx, sum3.ry, sum3.rz)
return output

The problem still occurs in XCode 10.0. You can fix it by disabling "Show Source Control changes" in Source Control options.

I spend 4 hours to figure out problems in a long compilation of my project.
The first try takes 42 min to compile.
I clear all cache from /Users/myname/Library/Developer/Xcode/DerivedData/ModuleCache/ as was suggested by #LNI, after restart SourceKitService and apply few changes for code:
1)
To
var initDictionary:[String:AnyObject] = [
"details" : "",
"duration" : serviceDuration,
"name" : serviceName,
"price" : servicePrice,
"typeId" : typeID,
"typeName" : typeName,
"url" : "",
"serviceId" : serviceID,
"imageName" : ""
]
From
var initDictionary= [
"details" : "",
"duration" : serviceDuration,
"name" : serviceName,
"price" : servicePrice,
"typeId" : typeID,
"typeName" : typeName,
"url" : "",
"serviceId" : serviceID,
"imageName: "" ]
2) To
if let elem = obj.property,
let elem2 = obj.prop2,
etc
{
// do stuf here
}
From
let value1 = obj.property ?? defaultValue
3)
To
let serviceImages = images.filter { $0.serviceId == service.id }
let sorted = serviceImages.sort { $0.sort > $1.sort }
From
let serviceImages = images.filter { $0.serviceId == service.id }. sort { $0.sort > $1.sort }
As result compile time - 3 min, not so fast but better for 42 min.
As result, before SourceKitService - take ~5,2Gb of memory and after ~0.37Gb

I had the same problem with SourceKitService.
I solved. NEVER ADD SUBVIEWS WITH FOR LOOP.
To detect issue I use:
https://github.com/RobertGummesson/BuildTimeAnalyzer-for-Xcode

I've been running into this issue with Xcode 9, and explored several solutions. For me, disabling Source Control seemed to do the trick.
Xcode -> Preferences -> Source Control -> uncheck "Enable Source Control"
If this doesn't work, I would recommend using the renice command at the terminal. More on that here
disabling Source Control
Other steps that I attempted, but did not help:
Close Xcode -> Delete Derived Data
cycling machine
"clean" project

https://www.logcg.com/en/archives/2209.html
SourceKitService took charge of Swift's type inference work.
private lazy var emojiFace = ["?", "?", "?", "?"]
change to explicitly type
private lazy var emojiFace:[String] = ["?", "?", "?", "?"]
SourceKitService CPU usage immediately drop down。

For me it worked to delete the Derived Data. Select 'Product' from the menu and hold the Alt-key and select 'Clean Build Folder'. Shortkey: Alt + Shift + Command + K

Quit Xcode
Run in Terminal:
rm -rf ~/Library/Developer/Xcode/DerivedData/ModuleCache/*
Note the difference between LNI's accepted answer and this one:
It's always better not to crash than to crash. Especially, when it comes to Xcode processes/components.
I'm not an Apple developer, but partial deleting the cache can break its integrity. I didn't notice any significant delays after cleaning all the cache.

Don't create dictionary in swift without specifying data types or with [String:Any]
If we use 'Any' type the compiler might run into an infinite loop for checking the data type.
It won't create any compiling error, it will make our mac to freeze at 'compiling swift source files' with acquiring much memory for the tasks named 'swift' & 'SourceKitService'.

I ran into something similar combining multiple ?? operators to provide a default for optional string values.
I was experimenting with the debug code below when the fan on my trusty mid-2010 MacBook Pro began running hard. SourceKitService was sucking up every CPU cycle it could get. Commenting and uncommenting the offending line made it very clear what SourceKitService was choking on. It looks like using more than one ?? operator to provide a default is an issue on an old machine. The work around is just don't do it. Break it up into multiple assignments which makes some ugly debug code even uglier.
placeMark is an instance of CLPlacemark. The properties used here return optional strings.
I was using Xcode Version 8.3.2 (8E2002) running on OS 10.12.4 (16E195)
// one term is not an issue
let debugString1 = (placeMark.locality ?? "")
// two terms pushes SourceKitService CPU use to 107% for about 60 seconds then settles to 0%
let debugString1 = (placeMark.locality ?? "") + ", " + (placeMark.administrativeArea ?? "")
// three terms pushes SourceKitService CPU use to 187% indefinitely
let debugString1 = (placeMark.locality ?? "") + ", " + (placeMark.administrativeArea ?? "") + (placeMark.postalCode ?? "")
// ugly but it's safe to use
var debugString1 = placeMark.locality ?? ""
debugString1 = debugString1 + ", " + (placeMark.administrativeArea ?? "")
debugString1 = debugString1 + " " + (placeMark.postalCode ?? "")

Converting long Arrays to Functions seem to resolve the problem for me:
var color: [UIColor] {
return [
UIColor(...),
UIColor(...),
...
]
}
to:
func color() -> [UIColor] {
return [
UIColor(...),
UIColor(...),
...
]
}

I have faced such an issue. Source kit service was using 10 gb of usage. Swift process in activity monitor reaches over 6 GB usage. I was using following code:
var details : [String : Any] = ["1":1,
"2":2,
"3":3,
"4":4,
"5":5,
"6":6,
"7":7,
"8":8,
"9":9,
"10":10,
"11":11,
"12":12,
"13":13,
"14":14,
"15":15,
"16":16]
I have changed code to following to solve this issue:
var details : [String : Any] = [:]
details["1"] = 1
details["2"] = 2
details["3"] = 3
details["4"] = 4
details["5"] = 5
details["6"] = 6
details["7"] = 7
details["8"] = 8
details["9"] = 9
details["10"] = 10
details["11"] = 11
details["12"] = 12
details["13"] = 13
details["14"] = 14
details["15"] = 15
details["16"] = 16

Faced the same issue on Xcode 7.2 (7C68)
The solution was to implement a method of a protocol, which my class had in the definition.

This is still an issue in xcode Version 7.3.1 (7D1014)
the cause for me was, like LNI pointed it out, a too long array, not so long actually.
I fixed my problem by breaking the array into various arrays like this:
let firstLevel = [
[1, 0, 1, 0, 1],
[0, 0, 0, 0, 0],
[1, 0, 1, 0, 1],
[0, 0, 0, 0, 0],
[1, 0, 1, 0, 1],
[0, 0, 0, 0, 0]
]
let secondLevel = [
[0, 0, 0, 0, 0],
[0, 1, 0, 1, 0],
[0, 0, 0, 0, 0],
[0, 1, 0, 1, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
]
let thirdLevel = [
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]
]
let map = [firstLevel, secondLevel, thirdLevel]

I had the same problem with XCode 8.2.1 (8C1002) and the following code:
import UIKit
import AVFoundation
import Photos
import CoreMotion
import Foundation
class TestViewController: UIViewController
{
let movieFileOutput = AVCaptureMovieFileOutput()
var anz_total_frames = 0, anz_total_miss = 0
#IBOutlet weak var tfStatistics: UITextView!
func showVideoStatistics()
{
let statisticText:String = "frames: \(self.anz_total_frames)" + String.newLine +
"frames/s: \(self.anz_total_frames / self.movieFileOutput.recordedDuration.seconds)" + String.newLine +
"miss: " + formatText4FramesPercent(self.anz_total_miss) + String.newLine +
"nicht erkannt: " + formatText4FramesPercent(self.anz_total_miss) + String.newLine +
"nicht erkannt: " + formatText4FramesPercent(self.anz_total_miss) + String.newLine +
"nicht erkannt: " + formatText4FramesPercent(self.anz_total_miss) + String.newLine +
"nicht erkannt: " + formatText4FramesPercent(self.anz_total_miss) + String.newLine +
"nicht erkannt: " + formatText4FramesPercent(self.anz_total_miss) + String.newLine +
"nicht erkannt: " + formatText4FramesPercent(self.anz_total_miss) + String.newLine +
"nicht erkannt: " + formatText4FramesPercent(self.anz_total_miss) + String.newLine +
"nicht erkannt: " + formatText4FramesPercent(self.anz_total_miss) + String.newLine +
"nicht erkannt: " + formatText4FramesPercent(self.anz_total_miss) + String.newLine +
"nicht erkannt: " + formatText4FramesPercent(self.anz_total_miss) + String.newLine
self.tfStatistics.text = statisticText
}
func formatText4FramesPercent(_ anz:Int) -> String
{
let perc = Double(anz)*100.0/Double(anz_total_frames)
return String(perc.format(".1") + "%")
}
}
and these extensions:
extension String {
var localized: String {
return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
}
static var newLine: String {
return "\r\n"
}
}
extension Int {
func format(_ f: String) -> String {
return String(format: "%\(f)d", self)
}
}
extension Double {
func format(_ f: String) -> String {
return String(format: "%\(f)f", self)
}
}
I solved it by commenting this line in TestViewController:
"frames/s: \(self.anz_total_frames / self.movieFileOutput.recordedDuration.seconds)" + String.newLine +
Took me more than an hour to find it, I hope a can save some time of somebody else.
I filed a bug report to Apple with number 30103533

I was facing the same problem after migrating the project to swift 3, find out solution it was taking time because of dictionaries and array created without data type.

This behavior appeared in my project when I accidentally declared a class that inherited from itself. Xcode 8.2.1, using Swift 3.

I also had this issue, in my case I was declaring a big array like this:
var myArray: [(String, Bool?)]?
myArray = [("someString", someBool),
("someString", someBool),
("someString", someBool),
("someString", someBool),
("someString", someBool)
.
.
("someString", someBool)]
I solved the problem by adding the items 1 per line instead of all at the same time:
var myArray = [(String, Bool?)]()
myArray.append(("someString", someBool))
myArray.append(("someString", someBool))
myArray.append(("someString", someBool))
myArray.append(("someString", someBool))
myArray.append(("someString", someBool))
.
.
.
this fixed the problem.

For Objective-C projects:
I had the same problem, and there's zero Swift code in our project, so it wasn't the type inference checker.
I tried every other solution here and nothing worked - what FINALLY fixed it for me was rebooting the computer in recovery mode and running the disk repair. I can finally work in peace again!
I'm guessing that it happened because of some broken symlinks, probably pointing towards each other and making the service run around in an endless loop.

I'm having a similar issue with Xcode 8.2.1 - with a section of 1,000+ lines of code commented-out via /* */. Commenting-out the section caused the issue, and removing the commented-out code fixed it.

run in terminal:
killall Xcode
rm -rf ~/Library/Developer/Xcode/DerivedData/ModuleCache
open /Applications/Xcode.app
you could also create a terminal command using this alias:
echo alias xcodeFix='killall Xcode;rm -rf ~/Library/Developer/Xcode/DerivedData/ModuleCache;open /Applications/Xcode.app' >> ~/.profile
source ~/.profile
and then just run
xcodeFix

Happened to me on XCode 11.4.1 when calling #dynamicMemberLookup subscripts inside a SwiftUI #ViewBuilder block.

I had the same issue and it was caused by a programming error.
In my case I was implementing the comparable and equatable protocols and the lhs.param and rhs.param did not correspond with parameters of the lhs and rhs classes.

Related

Can't get a certain formula into sheet using script editor google sheets

Hi all I am haveing a problem geting a formula into google sheet using script editor. I can get one in that doesn´t work but not one that does.
This one will put the formula in but the formula doesn´t work
function x1() {
var ss3 = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
ss3.getRange("AF2").setFormula("=IF((AND(OR(I2='YOUR TRIP DWL',I2='MEGA PACK DWL (YT + AA + BONUS)'),L2<=0,AD2<>'')),'Send Email', 'Wait')")
var lr3 = ss3. getLastRow();
var filldownrange3 = ss3.getRange(2, 32, lr3-1);
ss3. getRange("AF2").copyTo(filldownrange3);
}
This one shows an Error in script editor but the furmula work in the cells i manually placed in.
function x1() {
var ss3 = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
ss3.getRange("AF2").setFormula("=IF(((AND(OR(I2="YOUR TRIP DWL",I2="MEGA PACK DWL (YT + AA + BONUS)"),M2<=0,AA2<>"",AE2<>""))), "Send Email", "Wait")")
var lr3 = ss3. getLastRow();
var filldownrange3 = ss3.getRange(2, 32, lr3-1);
ss3. getRange("AF2").copyTo(filldownrange3);
The problem is Line 3 with the formula itself as other fumulas are ok, can anyone shed some light on this, Thanks in advance,
I suggest you try your second version with escaping of the internal double quotes.
IF this hels anyone else with the same problem, I have finally solved this problem by changing the double quotes surounding the formula with single quptes and leaving the double quotes inside the formula, so line 4 reads:
ss3.getRange("AF2").setFormula('=IF(((AND(OR(I2="YOUR TRIP DWL",I2="MEGA PACK DWL (YT + AA + BONUS)"),M2<=0,AA2<>"",AE2<>""))), "Send Email", "Wait")');

AudioKit 4.0 AKPeriodicFunctions Not Starting

Unable to start AK4 AKPeriodic function in XCode 9. In the following excerpt from the "Plucked String" playground, I inserted two log messages to help identify processing events. I never see the "periodic function startup" message in the console log. All I hear is a very short clicking sound.
let scale = [0, 2, 4, 5, 7, 9, 11, 12]
let performance = AKPeriodicFunction(frequency: playRate) {
print("periodic function startup")
var note = scale.randomElement()
let octave = [2, 3, 4, 5].randomElement() * 12
if random(0, 10) < 1.0 { note += 1 }
if !scale.contains(note % 12) { print("ACCIDENT!") }
let frequency = (note + octave).midiNoteToFrequency()
if random(0, 6) > 1.0 {
pluckedString.trigger(frequency: frequency)
}
}
AudioKit.output = reverb
AudioKit.start(withPeriodicFunctions: performance)
print("AK startup")
performance.start()
This is fixed in the develop branch, as per this issue:
https://github.com/AudioKit/AudioKit/issues/1066

Swift Adding HTML to UIWebView, expression was too complex

I'm adding some HTML content to an UIWebView.
This line:
generatedHtml += "<br><p style=\"font-family:'Chevin-Medium';font-size:12px;color:#505050;padding-top:0px;\">" + newsItem.entry.likes + " like this " + newsItem.entry.comments?.count + " comments</p>"
I get:
expressions was too complex to be solved in reasonable time
I'm just doing a count on an array, i don't know how to make that less complex?
The object looks like this:
public class NewsItem: NSObject {
var entry: EntryObject = EntryObject()
}
public class EntryObject: NSObject {
var comments: [Comment]? = []
}
newsItem.entry.comments?.count is an integer, and you can't add an integer to a string using +, you should use string interpolation with \():
" like this \(newsItem.entry.comments?.count) comments</p>"
Or use the String initializer if you need to keep using +:
" like this " + String(newsItem.entry.comments?.count) + " comments</p>"
If the error "too complex" persists, you'll have to break down the statements and use variables instead of inserting the expressions directly.
Try to do by this way
var countComments : Int = 0
//Validate comment counting
if let cComments = newsItem.entry.comments?.count
{
countComments = cComments
}
//... Some code here ...
//Devide to Conquest.
//If is easy to find... Is not hard to fix
generatedHtml += "<br>"
generatedHtml += "<p style=\"font-family:'Chevin-Medium';font-size:12px;color:#505050;padding-top:0px;\">"
generatedHtml += "\(newsItem.entry.likes) "
generatedHtml += "like this \(countComments) comments" //Here you have a valid value
genetatedHtml += "</p>"
But, why?
Maybe you have a problem with the optional value newsItem.entry.comments?.count that can gets you a nil value. Then, first of all, validate the value and be sure about what was returned. Better "0", a valid value than nil
When you split the string creation, the debug working will be more easy to execute. You will can have a better idea where is happening an error.
Maybe it´s not a definitive solution to your problem, but a good way to help you fix it.

Swift issue using max() and min() sequentially while archiving on Xcode

On "Compiling swift files" step while archiving, it said that a particular file had this error:
PHI node has multiple entries for the same basic block with different incoming values!
%31 = phi i64 [ 3, %385 ], [ %386, %385 ], [ 1, %29 ], !dbg !1370
label %385
i64 3
%386 = phi i64 [ %23, %27 ], !dbg !1433
LLVM ERROR: Broken function found, compilation aborted!
After commenting the file's code for a while I found out that the following lines of code were the issue:
var normalizedStrikes = max(1, strikes)
normalizedStrikes = min(normalizedStrikes, 3)
After trying out a lot of things I discovered that I couldn't use max() and then min(), here is what solved the issue for me:
var normalizedStrikes = strikes
if (normalizedStrikes <= 0) {
normalizedStrikes = 1
}
normalizedStrikes = min(normalizedStrikes, 3)
Another very nice thing I've found is that if I change the condition to "< 1", it throws the same error. Good stuff.
var normalizedStrikes = strikes
if (normalizedStrikes < 1) {
normalizedStrikes = 1
}
normalizedStrikes = min(normalizedStrikes, 3)
My question is: why that happened?
Btw I'm using Xcode Version 6.1.1 (6A2008a)
This is resolved as of Xcode 6.3 (6D570).

LLDB Python access of iOS variables?

As part of debugging a problem that might be related to my UIVIews, I want to write a python script to run from LLDB. I had thought to extract all settings for a view in a breakpoint and all view children, to allow me to compare states. I checked out the WWDC video on the topic and then spent time reading things at lldb.llvm.org/scripting.html, and didn't find them very helpful. A web search for examples led to nothing substantially different from those.
My problem is that I'm trying to figure out how to access iOS variables at my breakpoint. The examples I've seen do things like convert numbers and mimic shell commands. Interesting stuff but not useful for my purposes. I've been reading my way through the help info with "script help(lldb.SBValue)" and the like, but it is slow going as the results are huge and it is not clear what the use patterns are. I feel like one decent example of how to traverse a few iOS objects would help me understand the system. Does anyone know of one or can share a snippet of code?
UPDATE:
I wrote this to help me track down a bug in my UIView use. I want to do a bit more work to refine this to see if I could show the whole view tree, but this was sufficient to solve my problem, so I'll put it here to save others some time.
import lldb
max_depth = 6
filters = {'_view':'UIView *', '_layer':'CALayer *', '_viewFlags':'struct'}
def print_value(var, depth, prefix):
""" print values and recurse """
global max_depth
local_depth = max_depth - depth
pad = ' ' * local_depth
name = var.GetName()
typ = str(var.GetType()).split('\n')[0].split('{')[0].split(':')[0].strip()
found = name in filters.keys() # only visit filter items children
if found:
found = (filters.get(name) == typ)
value = var.GetValue()
if value is None or str(value) == '0x00000000':
value = ''
else:
value = ' Val: %s' % value
if var.GetNumChildren() == 0 and var.IsInScope():
path = lldb.SBStream()
var.GetExpressionPath(path)
path = ' pathData: %s' % path.GetData()
else:
path = ''
print '^' * local_depth, prefix, ' Adr:', var.GetAddress(), ' Name:', name, ' Type:', typ, value, path
if var.GetNumChildren() > 0:
if local_depth < 2 or found:
print pad, var.GetNumChildren(), 'children, to depth', local_depth + 1
counter = 0
for subvar in var:
subprefix = '%d/%d' % (counter, var.GetNumChildren())
print_value(subvar, depth - 1, subprefix)
counter += 1
def printvh (debugger, command_line, result, dict):
""" print view hierarchy """
global max_depth
args = command_line.split()
if len(args) > 0:
var = lldb.frame.FindVariable(args[0])
depth = max_depth
if len(args) > 1:
depth = int(args[1])
max_depth = depth
print_value(var, depth, 'ROOT')
else:
print 'pass a variable name and optional depth'
And I added the following to my .lldbinit :
script import os, sys
# So that files in my dir takes precedence.
script sys.path[:0] = [os.path.expanduser("~/lldbpy")]
script import views
command script add -f views.printvh printvh
so that I can just type "printvh self 3" at the LLDB prompt.
Maybe this will help. Here's an example of how to dump simple local variables when a breakpoint is hit. I'm not displaying char* arrays correctly, I'm not sure how I should get the data for these to display it like "frame variable" would display it but I'll figure that out later when I have a free minute.
struct datastore {
int val1;
int val2;
struct {
int val3;
} subdata;
char *name;
};
int main (int argc, char **argv)
{
struct datastore data = {1, 5, {3}, "a string"};
return data.val2;
}
Current executable set to 'a.out' (x86_64).
(lldb) br se -l 13
Breakpoint created: 1: file ='a.c', line = 13, locations = 1
(lldb) br comm add -s python
Enter your Python command(s). Type 'DONE' to end.
> def printvar_or_children(var):
> if var.GetNumChildren() == 0 and var.IsInScope():
> path = lldb.SBStream()
> var.GetExpressionPath(path)
> print '%s: %s' % (path.GetData(), var.GetValue())
> else:
> for subvar in var:
> printvar_or_children(subvar)
>
> print 'variables visible at breakpoint %s' % bp_loc
> for var in frame.arguments:
> printvar_or_children(var)
> for var in frame.locals:
> printvar_or_children(var)
>
> DONE
(lldb) r
variables visible at breakpoint 1.1: where = a.out`main + 51 at a.c:13, address = 0x0000000100000f33, resolved, hit count = 1
argc: 1
*(*(argv)): '/'
data.val1: 1
data.val2: 5
data.subdata.val3: 3
*(data.name): 'a'
Process 84865 stopped
* thread #1: tid = 0x1f03, 0x0000000100000f33 a.out`main + 51 at a.c:13, stop reason = breakpoint 1.1
frame #0: 0x0000000100000f33 a.out`main + 51 at a.c:13
10 int main (int argc, char **argv)
11 {
12 struct datastore data = {1, 5, {3}, "a string"};
-> 13 return data.val2;
(lldb)
Tip - for sanity's sake I worked on the python over in a side text editor and pasted it into lldb as I experimented.
If you use the frame variable command in lldb to explore your variables at a given stop location, that's the same basic way that you can access them via the SBFrame that is provided to your breakpoint python command in the 'frame' object.
Hope that helps to get you started.
Did you try looking at the python LLDB formatting templates stored in:
XCode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python/lldb/formatters/objc

Resources