breakpoint with debugger Commend jump in xcode - swift

I made a breakpoint in Xcode with the jump commend to force passing some condition, but when it execute to line 168 it crash with message
"Thread 1: EXC_BAD_ACCESS (code=1, address=0x1)"
why did that happen?
the console logged:
warning: MoreMultitypeCollectionViewCell.swift:178 appears multiple times in this function, selecting the first location:
MoreMultitypeCollectionViewCell.(updateButtonStateCkeck in _9A12557DCAB30EEB52DC7C2EA09487CD)() -> () + 1580 at MoreMultitypeCollectionViewCell.swift:178
MoreMultitypeCollectionViewCell.(updateButtonStateCkeck in _9A12557DCAB30EEB52DC7C2EA09487CD)() -> () + 1600 at MoreMultitypeCollectionViewCell.swift:178
my questions are:
How should I type in lldb to select location?
Is there a better way to force passing into If Statement without change code and rebuild project?
sometimes when I type 'po' in lldb or click print description in variable view, it will show fail message, how is that?

1) In lldb, the equivalent command is thread jump and you can specify an address as well as a line number there.
2) thread jump or the Xcode equivalent is an inherently dangerous operation. If you jump over the initialization of some variable, you will be dealing with bad data now and will likely crash. That sort of thing you can sometimes spot by eye - though Swift is lazy about initialization so the actual initialization of a variable may not happen where you think it does in the source. There are more subtle problems as well. For instance, if you jump over some code that as a byproduct of its operation retains or releases an object, the object will end up under or over retained. The former will cause crashes, the latter memory leaks. These retains & releases are generated by the compiler, so you can't see them in your source code, though you could if you look at the disassembly of the code you are jumping over.
Without looking at the code in question, I can't tell why this particular jump caused a crash.
But you can't 100% safely skip some of the code the compiler choose to emit. Looking at the disassembly you might be able to spot either (a) a better place to stop before the jump - i.e. stop past some retain or release that is causing a problem or jump to an address in the middle of a line so you still call a retain that's needed. You'll have to figure this out by hand.
3) There's not enough info to answer this question.
BTW, your image links don't seem to resolve.

Related

Can you really "rewind/reverse" the debugger in Swift/Xcode?

When you are stepping through Swift code in Xcode (9/10?), there is a green bar on the right with something like:
You are supposed to be able to drag the partial-hamburger-menu upwards to rewind the statement pointer to re-run code. However, every time I try it it moves back as expected, but then 100% of the time I step from that point I get:
Is there a trick to this?
You can move the pointer to the next statement to be executed to either a previously executed statement or a not-yet-executed statement, but in order for that to work the stack needs to be in the correct state, and so do the variables in memory.
In my experience, the outcome is usually a crash.
You'd need to drop down to the assembler code and examine it in order to figure out what's really going on, and might need to patch variables and/or the contents of the stack in order for your code to survive the change of program counter. I've never invested the time to try to do that, however. As a result I find the feature pretty much useless, and have given up on it. (I've worked in assembler a LOT in years past, but never learned enough about ARM assembler to be able to read it well, much less hack registers, memory, and the stack to make moving the program counter work.)

release build variable corruption when using ne10 math library assembly function

has anyone experience the following issue?
A stack variable getting changed/corrupted after calling ne10 assembly function such as ne10_len_vec2f_neon?
e.g
float gain = 8.0;
ne10_len_vec2f_neon(src, dst, len);
after the call to ne10_len_vec2f_neon, the value of gain changes as its memory is getting corrupted.
1. Note this only happens when the project is compiled in release build but not debug build.
2. Does Ne10 assembly functions preserve registers?
3. Replacing the assembly function call to c equivalent such as ne10_len_vec2f_c and both release and debug build seem to work OK.
thanks for any help on this. Not sure if there's an inherent issue within the program or it is really the call to ne10_len_vec2f_neon causing the corruption with release build.enter code here
I had a quick rummage through the master NEON code here:
https://github.com/projectNe10/Ne10/blob/master/modules/math/NE10_len.neon.s
... and it doesn't really touch address-based stack at all, so not sure it's a stack problem in memory.
However based on what I remember of the NEON procedure call standard q4-q7 (alias d8-d15 or s16-s31) should be preserved by the callee, and as far as I can tell that code is clobbering q4-6 without the necessary save/restore, so it does indeed look like it's clobbering the stack in registers.
In the failed case do you know if gain is still stored in FPU registers, and if yes which ones? If it's stored in any of s16/17/18/19 then this looks like the problem. It also seems plausible that a compiler would choose to use s16 upwards for things it needs to keep across a function call, as it avoids the need to touch in-RAM stack memory.
In terms of a fix, if you perform the following replacements:
s/q4/q8/
s/q5/q9/
s/q6/q10/
in that file, then I think it should work; no means to test here, but those higher register blocks are not callee saved.

Why small changes make "Access violation at address xxx" error on this delphi code?

I have 2 pieces of code :
It works normal
with ADOTemp do
begin
SQL.Clear;
SQL.Add('INSERT INTO documents');
SQL.Add('(document_date,fk_id_status,money_direction,');
SQL.Add('paid,addition,saving,fk_id_base,fk_id_user)');
SQL.Add('VALUES ');
SQL.Add('(CONVERT(DATE,GETDATE(),103),:pfk_id_status,:pmoney_direction,');
SQL.Add('0,0,0,'+IntToStr(p_id_base)+',:pfk_id_user)');
Parameters.ParamByName('pfk_id_status').Value := p_id_status;
Parameters.ParamByName('pmoney_direction').Value := p_money_direction;
// Parameters.ParamByName('p').Value := p_id_base;
Parameters.ParamByName('pfk_id_user').Value := fMain.ApplicationVariablers.user_id;
ExecSQL;
end;
It does not work and returns a terrible error
with ADOTemp do
begin
SQL.Clear;
SQL.Add('INSERT INTO documents');
SQL.Add('(document_date,fk_id_status,money_direction,');
SQL.Add('paid,addition,saving,fk_id_base,fk_id_user)');
SQL.Add('VALUES ');
SQL.Add('(CONVERT(DATE,GETDATE(),103),:pfk_id_status,:pmoney_direction,');
SQL.Add('0,0,0,:p,:pfk_id_user)');
Parameters.ParamByName('pfk_id_status').Value := p_id_status;
Parameters.ParamByName('pmoney_direction').Value := p_money_direction;
Parameters.ParamByName('p').Value := p_id_base;
Parameters.ParamByName('pfk_id_user').Value := fMain.ApplicationVariablers.user_id;
ExecSQL;
end;
Error on image, line 1917
It seems that this question is in reference to your earlier question: Delphi, error :"Access violation at address xxxxxxxx. Read of address yyyyyyyy", at AdoQuery.SQL.Text:='''
You had added and accepted an answer there along the lines seen in this question. The error message, an AV in msvcrt.dll is indicative of a serious programming error. Perhaps a heap corruption. Perhaps something else. The change you made that stops the error occurring does not really fix the problem. The problem will still be there, lying dormant. You just got (un)lucky that the change you made appeared to fix the problem.
Access violations are not always reproducible. That's just their nature. When you encounter one you need to understand why it happens. Simply using trial and error to re-organise code from a completely different location will never lead to the real solution.
What you should be doing is tracking down the real cause of the problem. Do that, fix it, and either version of the code above will work. This is probably not the answer you are wanting to get. You may very well not want to accept what I say. But, speaking from experience, until you recognise that you have a more serious problem, you will make no headway here.
Looking at your code in the bitmap...I'm pretty sure you access violation is because of what David just said...you have serious Memory problems in your code...Your not freeing your objects...that you are creating...Anytime you pass a nil reference to Owner in a TComponent Constructor...your telling the compiler...that you know what your doing and will free it when your finished with it...Matter of fact good practice is to always free objects that you declare and use exclusively in the scope of your method.
procedure TForm1.MyMethod;
var
a_MyComp: TMyComp;
begin
a_MyComp := TMyComp.Create(nil);
Try
//use my a_MyComp...
Finally
a_MyComp.Free;
End;
end;
Check out your code in CreateNewDocument...you'll notice that your not freeing your AdoTemp.
-Rick
Access violation exceptions (AVs) tell you that you have made a mistake in the memory access of your program. However, the way access violations work: they are unable to guarantee always detecting the error every time you make a mistake. (Sometimes you get un-lucky and no access violations are raised, but the mistake is still there causing other things to quietly go wrong inside your application.)
You can think of the memory available to your program being represented as below (where "." means the memory is not allocated to anything, and "A" means the memory is allocated to something within your program: e.g. object, local variable, parameter, machine code).
[.......AAA..AAAA.....AA......A...A...........AAA....A.......AA.........AAAAA]
Suppose you create some object; this will require memory to be allocated for the object itself. If the object in turn creates child objects, this will also be allocated in memory. (I'll use "O" and "C")
/-ref--\
[.......AAA..AAAAO....AAC.....A...A.....C.....AAA....A.......AA.........AAAAA]
\-ref------------------/
Note that within the memory allocated to O, it might hold references to its child objects.
Conversely to the above, whenever an object is destroyed, its memory is deallocated. Let us suppose you have made a mistake in your memory access, and something has destroyed one of O's child objects before O has finished using it.
/-ref--\
[.......AAA..AAAAO....AAC.....A...A...........AAA....A.......AA.........AAAAA]
\-ref------------------/
If O now tries to use its second child object, you will get an access violation. However, you might be un-lucky and not get an access violation showing your earlier mistake IF:
You destroy O without it trying to do anything to the second child object.
Or you first create a new object that happens to be allocated in the exact same place the child object was.
The second situation tends to be worse than the first, because every time C2 is used on the assumption that it is the correct child of O: unexpected results are produced and an incorrect values are written in memory. These incorrect values may be important data, or references to other objects (making the problem get worse over time).
So: Whenever yo do get an access violation, thank your lucky stars and hunt down the root cause of the problem.
NB! NB! I cannot stress the importance of the above enough.
Investigating your particular problem
First note, when an exception pauses in the debugger, the code usually points to the next line that would have been executed if not for the exception. (This doesn't affect anything here, because the previous line is also ADOTemp.SQL.Add; - the point is be prepared to consider the previous line as the cause of an exception - and test to confirm it!)
Useful tip: When an exception is thrown within Delphi/Third Party code, it can be useful to build with Debug DCU's or recompile Third Party source with debug information to get closer to the actual line raising the exception. (This can even be useful in situations like this where the error appears to be inside a Microsoft DLL.)
Looking at your screen-shot, the exception is thrown from a brand new instance of TADOQuery. Now there really isn't any sensible explanation for a brand new query to be throwing access violations when simply adding text to its SQL query. This strongly implies a corruption problem as described earlier.
One possibility would be another thread interfering with this one. (NOTE: even if your application isn't multi-threaded, the ADO objects do have built-in support for asynchronous operations.) However, I'm going to ignore that possibility for now because threading issues tend to be less consistent than you've implied this one is.
So, assuming you have a memory access problem somewhere else that is only manifesting here with a brand new TADOQuery (used correctly at least up to the point of the AV) - what other objects are interacting with this query to possibly cause corruption?
ADOTemp.Connection := fMain.ADOConnection;
There is a very strong possibility that commenting out the above line would also eliminate your access violation. So what are the possible problems:
fMain might have been destroyed prematurely and is now a dangling pointer meaning the code to return ADOConnection could do any of a number of unexpected things.
Any of the code backing fMain.ADOConnection may be referencing corrupted memory or dangling pointers; this includes the returned connection itself.
NOTE: One very common cause of invalid memory access is to have a function such as GetADOConnection that does not correctly initialise its Result. So in some cases it returns a 'random' address in memory, resulting in all sorts of unexpected behaviour when something tries to use the connection.
Is your ADOConnection created on a different thread, and being used by multiple threads?
PS: Don't forget to follow Rick's advice, and make sure you destroy the query when you've finished using it. Who knows, there might be an internal bug in ADO that when it runs out of a particular internal resource (due to queries not being destroyed), that causes ADO to start throwing AVs.
NOTE: You should be able to test my theory without altering functionality by simply changing the ADOTemp.Connection := ... line. Simply assign a connection string to the query instead of a connection object. However, if that solves (or more correctly stated: hides) the problem, please follow my advice, and hunt down the root cause of the AV.

“EXC_BAD_ACCESS: Unable to restore previously selected frame” - stack variables not getting cleaned up

With reference to the question here.
The solutions provided in that thread, include:
Being smart about where and how many variables you declare, that would go on the stack.
Disable Guard Malloc if needed.
Also, in general:
3. Make sure you are releasing a variable you have actually allocated memory for!!
I have none of the above issues. There are very few stack-allocated variables that I use within functions, say 2-3 within each. But because the functions are called in a loop several times, it seems to trigger an exception.
And here's the kicker, this is not just happening for statically allocated variables, but stuff on the heap too! I'm getting the page errors on Auto-released declarations of NSNumber variables that I use a couple of inside the loop, as well as a dictionary that I juDIciously alloc and release within the scope of the function, every single time it's called.
So why is this happening, and why the heck are heap variables getting affected? I don't get it at all, please throw some light on this. :)
I'm on IOS5 with XCode 4.2, iPhone/iPad simulator.
Thanks!
Regards,
Dev
Edit: Sample code
- (void)doSomething {
NSInteger fun = 3;
NSInteger time = 4;
NSInteger overload = fun*time;
NSString *string = [NSString stringWithFormat:#"%d",overload];
NSObject *myCustomObject = [[NSObject alloc] init];
[myCustomDictionary setObject:myCustomObject forKey:string];
[myCustomObject release];
//myCustomDictionary is an iVar, alloced in the class's init method, and released in dealloc and not touched anywhere in between
}
//doSomething gets called several times through the course of execution as the state of the view changes, the user interacts with it etc, often 2-3 times during one state change.
The code is purposely vague, but at the same time, it is EXACTLY as simple as in the sample. As is the rest of the code in the entire project. Several functions, each doing a small amount of work, as nicely self contained memory-wise as this one.
I faced EXC_BAD_ACCESS issues before, and at that point had referred to this question. However in my case, I was not creating multiple variables on the stack within a loop, they were getting created repeatedly by a function which gets called several times through the course of the execution. Ideally, the variables should have just got destroyed at the end of function-scope. Not sure why that didn't happen.
Anyway, to resolve that and to prevent multiple allocations from happening, I ended up declaring my stack-allocated variables as all static. That is bad practice, but that's exactly what I had to do to get it working. And it was working until I ended up facing the issue AGAIN with the "doSomething" function.
So the difficulty in "doSomething", was that I did not have only stack-allocated variables getting created, but heap stuff too. So I first started getting EXC_BAD_ACCESS on the NSInteger variables, at which point I tried fixing it again, by declaring them as static. It worked, but now EXC_BAD_ACCESS started occurring on the auto-released variable and finally the custom-allocated variable - which is when I got stumped. I have been following all the rules of memory management, and I'm having stack AND heap variables fubaring all over me. If it was only heap stuff, or stack stuff inside a loop, I could understand there's a mistake SOMEwhere. But here, it's neither, these are perfectly innocent variables getting allocated on the stack inside ONE function that is NOT called in a loop, and regular auto-released variables that never ever get retains or releases thrown at them from another place in the code. What makes it all even worse, is that the failure points are random - not just in this function but practically every one that gets called several times through the course of execution of the project.
Edit2: Turns out, in this case, it's my fault. See my answer for details. Sorry for wasting people's time. :\
We can't really help you without seeing the whole stack trace.
EXC_BAD_ACCESS doesn't mean anything in order to troubleshoot we need to know what the exception is.
Based on my experience when you don't get a stack tarce it means you are double releasing. Zombies is the way to find your double release.
Go to: Product -> Profile and then select "Zombies" from the list.
Run the app and perform any task that causes the crash, if the problem is a double release a pop-up would appear. Select the arrow in the popup and it tells you exactly what object is being double released, and it shows you the retain cycle.
Without any code posted in your question, and seeing that you are using iOS 5 and Xcode 4.2 my best advice for you is, in Xcode, go to Edit>Refactor>Convert to Objective-C ARC and wave all your memory management headaches goodbye.
ARC does all the memory management for you. You do not need to retain, release or write dealloc methods. You don't have to worry about memory management in most cases. You will leave mysterious EXC_BAD_ACCESS crashes behind. The way it works is super efficient. The compiler puts in the retains and releases for you and then optimises. You never even have to see the code.
Ah geez I don't believe this.
The issues faced earlier with the stack-allocated NSInteger variables holds, but in this case, it was entirely my fault.
"doSomething" was part of a long chain of events, that, due to some silly negligence on my part, ends up looping a bunch of times, which is what, rightfully and as it should be, leads to the application running out of memory. Whether it's with the stack variables or with the malloced ones sitting on the heap, with an infinite loop, it's gonna crash one way or another. :)
So the crash is perfectly fair, just got confused in this case with a previous issue that turned out to be unrelated. :(
Sorry for wasting everybody's time.

How do I look at an object in Xcode's debugger?

I have a simple question about debugging on Xcode and GDB.
I often run into an error:
unrecognized selector sent to instance 0x1081ad0
which makes the program load into GDB. Is there an easy way to examine what instance is located in that memory from GDB?
po 0x1081ad0
po = Print Object.
You can even call methods, like
po [myArray objectAtIndex:0]
Note that it only works on objects, so
po 1
will crash your program.
Steven is correct — the gdb command po is a shortcut for print-object, which actually calls -debugDescription (not -description, as you might expect) on the object provided as an argument. In many cases you'll see the same result from both methods, since one calls the other unless overridden. (See the related Note: callout on this Apple technote for details. Note that in their code sample, po $r3 prints the contents of a PowerPC register, but you can use any object pointer/reference, including Intel registers, etc.)
Also, be aware that print-object will only work on valid objects that haven't been deallocated. It won't help at all if you're sending a message to a borked pointer. Given the error you cited, though, it would seem that it's a valid object instance, it just doesn't implement the method you're trying to invoke.
It's also remotely possible that the object has already been destroyed. This answer should help in that case.
Edit:
There are other ways to "examine" objects in the debugger. I asked this SO question about Xcode data formatters, which is one way you can determine how a custom class appears in the Summary column of the debugger. The documentation linked from that question explain how it works. I've found the summary approach to help a lot with seeing the state of an object.
There are a couple of things you can do.
You can insert a break point that will trigger every time you have an exception, so basically create a break point for this (go to breakpoints and create a new one): -[NSException raise]
Alternatively, you can actually see what the object at that mem location is:
info symbol 0x1081ad0 or
info line *0x1081ad0
There's more info at the cocoadev wiki entry for exceptionhandling and debugging tips for objective C at cocoawithlove.
Your instance is not valid. You have release the object somewhere else, but you did not clear out your pointer... enable Zombie detection.