Learning how to code on Mac OS X for me is mainly about familiarizing myself with Xcode and I have this weird problem:
when I debug code and I move the debugger arrowhead from one line to another, I always get EXC_BAD_ACCESS. Consider the following example:
int main (int argc, char** argv)
{
printf("Test1\n");
printf("Test2\n");
printf("Test3\n");
}
I start stepping over line by line and I can see the output strings being displayed in the Output window. When the code reaches third printf() statement, I take the green arrowhead and drag it back to the first printf() statement. What I woud expect is that the execution would resume on this line, but after stepping over, I get EXC_BAD_ACCESS in __vfprintf:
EXC_BAD_ACCESS(code = 1, address = 0x6)
I have tried several similar dummy examples with the same result. I feel like missing something too obvious to notice it.
Regards,
Ondrej
Related
Basically, I have rewritten code that kept giving me a segmentation fault (core dump) error when running, and I decided to check each step to rule out issues.
My code works, until I try accessing/using the last line of the input files data. I do the same things to this line as to the line previous, but it's suggesting somethings wrong.
Here is my code for the file I/O and data handling:
The input file itself is simply:
20 20
10 10 u
5 5 d
In line 27, you dereference the uninitialised playerDirInput, which is undefined behaviour:
playerDir = (char)playerDirInput[0];
That's probably the cause of your crash. If that code block is meant to mirror the following one, it looks like you just haven't read the third item on that line, which is where playerDirInput is probably meant to come from. That would be something like:
fgets(line, 8, f);
playerRowChar = strtok(line, " ");
playerRow = atoi(playerRowChar);
playerColChar = strtok(NULL, " "); // <- fixed this, see below.
playerCol = atoi(playerColChar);
playerDirInput = strtok(NULL, " "); // <- add this.
playerDir = (char)playerDirInput[0];
However, I would suggest you instead opt for the simpler sscanf version, which would go something like (including a check to ensure you get the three items):
fgets(line, 8, f);
if (sscanf(line, "%d %d %c", &playerRow, &playerCol, &playerDir) != 3) {
handleErrorIntelligently();
}
I tend to prefer fgets followed by sscanf, rather than fscanf. The latter can fail in such a way that you're not sure where the input stream pointer ends up as. With fgets, you always know you've read a line (or can easily detect that you read a partial line and adjust for it).
Other potential problems you should look at:
On line 25, this strtok should be of the NULL type, not line. The latter will simply re-read the first item on that line wheras you want the next item.
You really should check functions that can return problematic values (such as NULL from strtok). Otherwise, using them can cause issues. That depends on the data you're reading, of course, so may not necessarily be a problem if you control that.
I'm really new to programming Objective-C and programming in general, so forgive me if this is a super obvious question:
I'm wondering if Objective-C runs code line by line. What I mean by that is if it processes one line before moving onto another, or if it just runs the next line regardless of whether the previous line is finished or not.
For example,
int difference = number1 - number2;
if (difference < 0) {
difference = difference + 10;
}
result = difference;
Say that number1 = 3 and number2 = 7. When I run this code, will it go line by line and run the if block before line 5 and give me result = 6, or will it start running the if block and line 5 at the same time and give me result = -4?
Thanks in advance!
EDIT: Changed modulo to addition because of Obj-C quirk.
As far as your thinking goes you may as well assume that it runs line by line.
In fact the compiler may put the code into a more efficient order (i.e. making sure that divisions aren't too close together, as this could make things slow). However even when the compiler does re-order things it makes sure that a result is calculated before it is needed. When you build the code in a fully optimised fashion (release mode) if you debug it you can see that the code has actually been re-ordered (the debugger jumps when you wouldn't expect it to). However as far as thinking about your code goes it's safe to assume that it runs it in the order you write it.
If you are new to programming, all programming languages you will meet at the beginning of your learning will execute statements sequentially. It means that the next one happens only after the previous one ends. However, languages like Objective C are not line-oriented and what matters are not lines but statements, like assignment ending with semicolon! or if statement.
it may be obvious with the new Xcode Debugger, but, i couldn't see the actual value:
int i=0; //i put a breakpoint on this line
i=1;
i=2;
When the app stopped on the first line, i put the mouse cursor on the i and something should refer me the correct value, means 0, but this was not the case. I also try to print the value on the console:
print i
But i got this:
(int) $1 = <unsufficient data for value (only 0 of 4 bytes available)>
Although i am sure po is not for primitives, i tried it too:
po i
Nothing from the above ways has worked to me.
i just had the same problem. this fixed it for me:
go to "edit scheme", then "Run", then "Info", then "build Configuration" and select "Debug" instead of "Release".
#Apple: BTW it should be called "insufficient" :-)
I'm writing a simple QR code generator (just for fun and to learn some Obj-C), and I'm working on tracing the outline of connected "modules" (i.e. the black squares that make up a QR code). This is in order to have nicer vector output than simply making a bunch of rects for each module.
Long story short, my outline-tracing code works - BUT ONLY if I make sure to call NSLog in a specific place! If I remove the NSLog-call, the code loops! I'm literally doing nothing but logging. And it doesn't matter what I log; I just have to call NSLog or things break.
The tracing algorithm is simple enough: Go clockwise around the shape of connected modules. When you hit a corner, turn right until you're back to following the outline of the shape. Stop when you reach the starting point again. The shape can have two modules that share a corner-point. The tracing-loop will thus hit that point twice. This is expected, and the code handles it correctly - if I call NSLog.
Otherwise, the code will say that a certain point is a corner the first time it sees it, and not a corner the second time, which causes the tracing to loop around. Detecting if something's a corner-point is not dependent on anything except the x and the y coordinates of the point and an array of module objects - but neither the modules nor the array changes while the tracing is going on, so given the same x,y you should always get the same result. And it does – if I call NSLog.
Without NSLog, the coordinates – e.g. (10,9) – is corner on moment, and a moment later (10,9) is suddenly not a identified as a corner. But with an NSLog-call, (10,9) is correctly seen as a corner-point every time.
Again: I change absolutely nothing; I just log something - anything! And suddenly it works. It's like it's saying that 2 == 2 is true or false, unless I tell it to log 2 and 2, in which case 2 == 2 is always true, as it should be.
Here's the flaky code. It's hard to understand out of context, but there's a lot of context, so I hope this is enough. Everything is integers (no fuzzy floating point values).
do { // start going around the shape
// If this isn't here or simply commented out, the code loops.
NSLog(#"foobar"); // doesn't matter what I log - I just need to log something
// Branch: Is current x,y a corner-point? This should
// always return the same result given the same X and Y
// values, but it only does if NSLog is there!
if( [self cornerAtX:x Y:y] ) {
// add the point to the path
[path addPoint:NSMakePoint(x, y)];
// rotate the direction clockwise, until
// the direction is following the edge of the
// the shape again.
do {
dt = dx;
dx = -dy;
dy = dt;
} while( ![self boundaryFromX:x Y:y inDirectionX:dx Y:dy] );
}
// continue along direction
x += dx;
y += dy;
} while( !(sx == x && sy == y) ); // we're back to the start of the shape, so stop
If anyone can tell me why NSLog can make code work (or rather: Why not using NSLog makes working code break), I'd be happy to hear it! I hope someone can make sense of it.
Make sure cornerAtX:Y: always returns something—i.e., that there's no code path that fails to return a value.
Otherwise, it may very well “return” whatever the last function you called returns, in which case calling NSLog (which doesn't return a value, but may ultimately call a function that does) causes it to “return” something different, which may always be something that's considered true.
The compiler should warn you if you fail to return a value from a function or method that you declared as doing so. You should listen to it. Turn on all the warnings you can get away with and fix all of them.
You should also turn on the static analyzer (also included in that post), as it, too, may tell you about this bug, and if it does, it will tell you step-by-step how it's happening.
There's not much to go on here, but I'd guess that it's either an uninitialized variable or some sort of memory stomping. NSLog probably uses both stack and heap memory, so it could affect those.
Have you tried replacing NSLog with some other meaningless operation? If that will also work then I suppose problem is linked to [self cornerAtX: x Y: y].
Another possibility is that the problem is time-related. NSLog takes time to execute, so if QR code is loaded in another thread you can see this kind of behavior.
I was wondering if there is an effective way to debug problems in xcode while coding in Objective-C. I create webpages constantly and code in jquery and javascript where you can set various alert boxes in different places in your code to determine if your script is properly executing sections. Can you do something like that in xcode to make sure that your script is executing methods properly and creating variables properly?
Thanks
Use the debugger - that's what it is there for! Set breakpoints by clicking in the grey are next to the line of code you want to break on. When this line of code is going to be excuted, the debugger will kick in and highlight the current place in execution. You can hover the cursor over variables in the IDE to examine their values, view the current call-stack (to see here this code has been called from) and get a list of local variables to help track program state. You can modify variable properties here too which often makes debugging simpler.
Execute code line by line by 'Stepping Over' (cmd+shift+o), which executes the current line, 'Stepping Into' (cmd_shift+i) which steps into the current line of code (if it is a function), or 'Stepping Out' to return back up the call stack.
If you want to stick to 'old-school' printf style debugging, go with NSLoging output to console.
NSLog(#"this text appears");
prints the following to the console:
this text appears
To print some basic variable values:
CGFloat pi = 3.14;
NSString *aFloatString = [NSString stringWithFormat:#"%.2f", pi];
NSLog(#"pi is equal to: %#", aFloatString);
Prints:
pi is equa to: 3.14
Standard c formatters can be used in NSLog i.e %d for int, %.2f for a float to 2 decimal places etc. Use %# for NSString*s.
Remember that NSLog will remain in production code unless you #IFDEF it out of release builds (or something similar), so if you don't want a performance hit, or embarrassing console logs to accompany the app you will want to remove them.
I've been known to litter functions that dump the following to console - and it isn't good:
OUTPUT:
Number of vertices is: 1200
<Requested reduction>
Can I kick it?
....
....
YES. I. CAN!
Number of vertices is: 800
Could have done with removing things like that :|
yes, the debugger can do all the things you want to do (just set some breakpoints - right click where you want them - then build&debug)
You can try writing to the console.
NSLog(#"Some status message here");
NSLog(#"The value of myObject is:%#", myObject);
To view the output of your application, while running with Xcode, click Run->Console and you will see all of the output from your application.