break with gdb on label in ObjectiveC - objective-c

can I have gdb break on the label "gdbStatement:" in this example Code:
...
op1 = op2 = op3 = op4 = nil;
op1 = [ops firstObject];
if(jj>1)op2 = [ops oai:1];
if(jj>2)op3 = [ops oai:2];
if(jj>3)op4 = [ops oai:3];
gdbStatement:
// Wertzuweisungen
if([stmt isZuweisung]){
// ausser bei mutable Targets, die erweitert werden oder im Fehlerfall hier drin kein continue, weil am Ende s1 weiterverarbeitet wird;
NSString *val1,*s1;
double varVal=0;
...
I know how to break on line numbers and functions. But can't find how to break on labels.

FSF or apple gdb? The below applies to FSF gdb.
Assuming that the code is in a method, there appears to be no way to specify a breakpoint on a label in a method,
The syntax for specifying a breakpoint on a label is break function:label
but the Objective-C linespec parser in FSF gdb does not parse this, so break -[aClass aMethod]:aLabel doesn't work
One could reasonably assume that you could mangle the method specify a function breakpoint on the symbol name, like 'break _i_aClass__aMethod:label', but that doesn't currently work either for a reason I do not yet understand.
tried with gdb 7.3 and 7.6.

Related

XCTAssertEqual not working for double values

I am writing some unit tests for a map coordinate function that I am writing. Unfortunately, there's something going on with XCTest that I am unable to nail down that is causing my test to fail:
NSString *testValue = #"121°31'40\"E";
double returnValue = coordinateStringToDecimal(testValue);
static double expectedValue = 121.5277777777778;
XCTAssertEqual(returnValue, expectedValue, #"Expected %f, got %f", expectedValue, returnValue);
I did read this similar question to troubleshoot. However, I am able to validate that the numbers and types are the same. Here is the console output of checking the type of each value:
(lldb) print #encode(__typeof__(returnValue))
(const char [2]) $5 = "d"
(lldb) print #encode(__typeof__(expectedValue))
(const char [2]) $6 = "d"
The Variables View in the debugger is showing them to be the same:
The interesting thing is the console output of comparing them in lldb:
(lldb) print (returnValue == expectedValue)
(bool) $7 = false
The types are the same and the actual numbers are the same. Why else would my assert be failing???
Because you are dealing with floating point numbers, there will always be a certain degree of inaccuracy, even between double values. In these cases, you need to use a different assertion: XCTAssertEqualWithAccuracy. From the docs:
Generates a failure when a1 is not equal to a2 within + or - accuracy. This test is for scalars such as floats and doubles, where small differences could make these items not exactly equal, but works for all scalars.
Change your assert to something like this:
XCTAssertEqualWithAccuracy(returnValue, expectedValue, 0.000000001);
Or in Swift 4:
XCTAssertEqual(returnValue, expectedValue, accuracy: 0.000000001, "expected better from you")
In Nimble:
expect(expectedValue).to(beCloseTo(returnValue, within: 0.000000001))
In Swift 4 accuracy was removed from the function name - now its an overload of XCTAssertEqual:
XCTAssertEqual(returnValue, expectedValue, accuracy: 0.000000001, "expected better from you")

Getting around LLDB printing problems e.g. CLLocationCoordinate2D and recognizing Macros in debugger

LLDB has various problems printing struct fields of double type, as documented here:
strange-behavior-in-lldb-when-printing-a-double-type-struct-member.
In my own case I tried to print a struct of type CLLocationCoordinate2D. As of Xcode 4.5.2 the error in printing CLLocationCoordinate2D persists.
Looking for ways around this bug I came across a nice macro, LOG_EXPR, in this blog:
http://vgable.com/blog/2010/08/19/the-most-useful-objective-c-code-ive-ever-written/
It does a great job of logging types into the debugger, but can't be called from the debugger.
Has anyone figured out a way to do something like LOG_EXPR while debugging in the LLDB command line interface, or any other improved printing that will work on arbitrary structs from the command line, other than switching back to GDB?
Here's what happens when I type in LLDB:
(lldb) p (CLLocationCoordinate2D)[self mapSetPointLatLon]
(CLLocationCoordinate2D) $4 = {
(CLLocationDegrees) latitude = 42.4604
(CLLocationDegrees) longitude = 42.4604
(double) easting = 42.4604
(double) northing = -71.5179
}
Notice the redundant and wrong lines added by lldb.
Here's what happens (at the same breakpoint) when I compile LOG_EXPR into my code:
Line of Code (not debugger):
LOG_EXPR(self.mapSetPointLatLon);
produces the correct output in the debugger output:
2013-01-26 14:02:17.555 S6E11[79116:c07] self.mapSetPointLatLon = {latitude=42.4604,longitude=-71.5179}
At the same breakpoint if I try to invoke LOG_EXPR from the command line, this is what happens:
(lldb) expr LOG_EXPR(self.mapSetPointLatLon);
error: use of undeclared identifier 'LOG_EXPR'
error: 1 errors parsing expression
(lldb)
Here's another example, since it turns out there is a case when you can get the debugger to do the right thing.
Here's my code fragment where I assign the struct 2 ways:
CLLocationCoordinate2D defloc = CLLocationCoordinate2DMake(kStartingLat, kStartingLon);
[[self.verticalPagingViewController mapPagingViewController] setMapSetPointLatLon: defloc];
If I just print the variable it works.
(lldb) p defloc
(CLLocationCoordinate2D) $1 = {
(CLLocationDegrees) latitude = 42.4604
(CLLocationDegrees) longitude = -71.5179
}
If I'm casting the type of the return value of an accessor method, it fails.
(lldb) p (CLLocationCoordinate2D)[[self.verticalPagingViewController mapPagingViewController] mapSetPointLatLon]
(CLLocationCoordinate2D) $2 = {
(CLLocationDegrees) latitude = 0
(CLLocationDegrees) longitude = 0
(double) easting = 0
(double) northing = 0
}

LLDB equivalent of GDB's macros

I have a very useful macro defined in .gdbinit
define rc
call (int)[$arg0 retainCount]
end
Is there anyway to define the same macro for lldb ?
You can do that with the following command definition in lldb:
command regex rc 's/(.+)/print (int)[%1 retainCount]/'
Example:
(lldb) rc indexPath
print (int)[indexPath retainCount]
(int) $2 = 2
You can put that into ~/.lldbinit (and restart Xcode).
One should think that something like
command alias rc print (int)[%1 retainCount]
should work, but as explained in I can't get this simple LLDB alias to work the %1 expansion does not work with expression, and command regex is a workaround.
Incidentally, on architectures where function arguments are passed in registers (x86_64, armv7), lldb defines a series of register aliases that map to the register used to pass the integral values -- arg1, arg2, etc. For instance,
#include <stdio.h>
int main ()
{
char *mytext = "hello world\n";
puts (mytext);
return 0;
}
and we can easily see what argument is passed in to puts without having to remember the ABI conventions,
4 char *mytext = "hello world\n";
-> 5 puts (mytext);
6 return 0;
7 }
(lldb) p mytext
(char *) $0 = 0x0000000100000f54 "hello world\n"
(lldb) br se -n puts
Breakpoint created: 2: name = 'puts', locations = 1, resolved = 1
(lldb) c
Process 2325 resuming
Process 2325 stopped
libsystem_c.dylib`puts:
-> 0x7fff99ce1d9a: pushq %rbp
0x7fff99ce1d9b: movq %rsp, %rbp
0x7fff99ce1d9e: pushq %rbx
0x7fff99ce1d9f: subq $56, %rsp
(lldb) p/x $arg1
(unsigned long) $2 = 0x0000000100000f54
(lldb)
x86_64 and armv7 both pass the first "few" integral values in registers - beyond that they can get stored on the stack or other places and these aliases don't work. lldb doesn't currently provide similar convenience aliases for floating point arguments. But for the most common cases, this is covers what people need.

How to find parsing error with ParseKit framework

I was wondering if there were a way to get back how far into an assembly a PKParser has parsed before encountering a syntax error.
reference: http://parsekit.com/
I'm using a grammar that basically describes a prefix notation expression language.
For example:
given your standard prefix notation expression grammar and a string "(+ a - b c))"
I'd like to retrieve that [(,+,a] where matched, so I can give the user some idea of where to look to fix their error, but the completeMatchFor and bestMatchFor don't return anything I can use to find this info.
Ideally I'd like to say that a '(' was expected, but it's not necessary for a grammar as simple as what I'm using.
From the book mentioned as the user manual, it seemed as if I would need to create a custom parser for this, but I was hoping that maybe I'd simply missed something in the framework.
Thoughts?
Developer of ParseKit here.
There are two features in ParseKit which can be used to help provide user-readable hints describing parse errors encountered in input.
-[PKParser bestMatchFor:]
The PKTrack class
It sounds like you're aware of the -bestMatchFor: method even if it's not doing what you expect in this case.
I think the PKTrack class will be more helpful here. As described in Metsker's book, PKTrack is exactly like PKSequence except that its subparsers are required, and an error is thrown (with a helpful error message) when all of its subparsers are not matched.
So here's a grammar for your example input:
#start = '(' expr ')' | expr;
expr = ('+' | '-') term term;
term = '(' expr ')' | Word;
Any productions listed contiguously are a Sequence -- but could instead be a Track.
The benefit of changing these Sequences to be Tracks is that an NSException will be thrown with a human-readable parse error message if the input doesn't match. The downside is that you must now wrap all usages of your factory-generated parser in a try/catch block to catch these Track exceptions.
The problem currently (or before now, at least) is that the PKParserFactory never produced a parser using Tracks. Instead, it would always use Sequences.
So I've just added a new option in head of trunk at Google Code (you'll need to udpate).
#define USE_TRACK 0
in
PKParserFactory.m
It's 0 by default. If you change this define to 1, Tracks will be used instead of Sequences. So given the grammar above and invalid input like this:
(+ a - b c))
and this client code:
NSString *g = // fetch grammar above
PKParser *p = [[PKParserFactory factory] parserFromGrammar:g assembler:self];
NSString *s = #"(+ a - b c))";
#try {
PKAssembly *res = [p parse:s];
NSLog(#"res %#", res);
}
#catch (NSException *exception) {
NSLog(#"Parse Error:%#", exception);
}
you will get a nice-ish human-readable error:
Parse Error:
After : ( + a
Expected : Alternation (term)
Found : -
Hope that helps.
I'm wrestling with this issue too. In order for -bestMatchFor: to be useful in identifying error conditions, there should be methods in PKAssembly's public interface indicating if there are more tokens/characters to be parsed. -completeMatchFor: is able to determine error state because it has access to the private -hasMore method. Perhaps PKAssembly's -hasMore method should be public.
I looked at PKTrack but since I want to handle errors programmatically, it wasn't useful to me.
My conclusion is I either write my own custom Track parser or I alter the framework and expose -hasMore. Are there other ways to handle errors?
Until I figure out a better way to detect errors, I've added the following to the file containing the implementation of my custom parser:
#interface PKAssembly ()
- (BOOL)hasMore;
- (id)peek;
#end
#implementation PMParser
...
#end
In my parse method:
PKAssembly* a = [PKTokenAssembly assemblyWithString:s];
PKAssembly* best = [self bestMatchFor:a];
PMParseNode* node = nil;
BOOL error = NO;
NSUInteger errorOffset = 0;
if (best == nil) // Anything recognized?
{
error = YES;
}
else
{
if ([best hasMore]) // Partial recognition?
{
PKToken* t = [best peek];
error = YES;
errorOffset = t.offset;
}
node = [best pop];
}
If an error occurred, errorOffset will contained the location of the unrecognized token.

How can I automatically add properties in Objective-C?

When adding new properties to classes, I find myself typing the same things over and over in xcode:
add TYPE *NAME; (in .h interface)
add #property (nonatomic, retain) TYPE *NAME; (in .h)
add #synthesize NAME; (in .m)
add [NAME release]; (in .m dealloc)
(I'm in a non-garbage collected environment.)
How can I do this automatically?
That sounds about right. IIRC, the Objective-C 2.0 doc says you might be able to leave out step #1, but otherwise I don't know of any shortcuts.
You could probably write a user script to do so within Xcode. See http://www.mactech.com/articles/mactech/Vol.23/23.01/2301XCode/index.html.
According to the Developer Documentation in 64bit runtimes you can leave out step 1.
You could look at Andrew Pang's RMModelObject - I haven't used it, but it acts as a object base class that simplifies model creation.
I haven't used it, but here's some of what's highlighted in the readme:
no need to declare instance variables,
no need to write accessor methods,
free NSCopying protocol support (-copyWithZone:),
free NSCoding protocol support (-initWithCoder:, -encodeWithCoder:),
free -isEqual: and -hash` implementation,
no need to write -dealloc in most cases.
Here's another solution which I modified from
this article (also see the initial article)
The version in the blog was searching for variables outside of the variable declaration block and was matching method names too. I have done a crude fix to only search for variables before the first '}'. This will break if there are multiple interface declarations in the header file.
I set the output to "Replace Document Conents" and input as "Entire Document"
....
#!/usr/bin/python
thisfile = '''%%%{PBXFilePath}%%%'''
code = '''%%%{PBXAllText}%%%'''
selmark = '''%%%{PBXSelection}%%%'''
import re
if thisfile.endswith('.h'):
variableEnd = code.find('\n', code.find('}'))
properties = []
memre = re.compile('\s+(?:IBOutlet)?\s+([^\-+#].*? \*?.*?;)')
for match in memre.finditer(code[:variableEnd]):
member = match.group(1)
retain = member.find('*') != -1 and ', retain' or ''
property = '#property (nonatomic%s) %s' % (retain,member)
if code.find(property) == -1:
properties.append(property)
if properties:
print '%s\n\n%s%s%s%s' % (code[:variableEnd],selmark,'\n'.join(properties),selmark,code[variableEnd:])
elif thisfile.endswith('.m'):
headerfile = thisfile.replace('.m','.h')
properties = []
retains = []
propre = re.compile('#property\s\((.*?)\)\s.*?\s\*?(.*?);')
header = open(headerfile).read()
for match in propre.finditer(header):
if match.group(1).find('retain') != -1:
retains.append(match.group(2))
property = '#synthesize %s;' % match.group(2)
if code.find(property) == -1:
properties.append(property)
pindex = code.find('\n', code.find('#implementation'))
if properties and pindex != -1:
output = '%s\n\n%s%s%s' % (code[:pindex],selmark,'\n'.join(properties),selmark)
if retains:
dindex = code.find('\n', code.find('(void)dealloc'))
output += code[pindex:dindex]
retainsstr = '\n\t'.join(['[%s release];' % retain for retain in retains])
output += '\n\t%s' % retainsstr
pindex = dindex
output += code[pindex:]
print output
There is Kevin Callahan's Accessorizer. From the web page:
Accessorizer selects the appropriate
property specifiers based on ivar type
- and can also generate explicit accessors (1.0) automagically ... but
Accessorizer does much, much more ...