Xcode 4 / gdb / How simply watch object properties? - xcode

I am very lost in Xcode 4. Watching a simple variable is a nightmare. I do not figure out how to just "watch a variable value". It was easier in Xcode 3...
I have the following piece of code:
if (labelEast.center.x > (east_oldPosition.x + 50) )
NSLog(#"Time to switch to previous exercise !");
else if (labelEast.center.x < (east_oldPosition.x - 50) )
NSLog(#"Time to switch to next exercise !");
After setting a breakpoint, I am just trying to watch labelEast.center.x (labelEast is a UILabel object). Since I could not find a watch item in a Xcode 4 menu, I am trying to use gdb. I am used to print variable/object values with po (print object). But now, I cannot display labelEast center property because it is inherited from a mother class.
(gdb) po labelEast.center
There is no member named center.
I do not understand why gdb says this whereas the code works fine and sees the property.
Thus I have 2 questions:
How to watch such a property without gdb in a graphical way (as simply as in Visual Studio) ?
How to do the same with gdb ?
Many thanks,
Franz
Unfortunately, I tried it but got this:
po [labelSouth center]
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x1a000356 0x343c7d06 in
objc_msgSend_stret () The program being debugged was signaled while in
a function called from GDB. GDB remains in the frame where the signal
was received. To change this behavior use "set unwindonsignal on"
Evaluation of the expression containing the function (objc_msgSend)
will be abandoned.
And when I try:
(gdb) print labelSouth.center
There is no member named center.
I really suspect there is no access to center property in UILabel. But how can me code run ???

I've hit this thing a few times myself just to remember "oh, that's right, gdb doesn't support dot notation so I have to use getter". Then just do:
(gdb) po [myObject someProperty]
and all is well with the world again. Also rereading your question I see that you're requesting a non object to be printed, hence you have to give gdb a hint of what type of property you want to print:
(gdb) p (CGRect)[myView frame]
(gdb) p (CGPoint)[myView center]
and so on.

Related

OpenEdge Progress-4GL development: how to know from an error message the procedure I'm running?

As stated in previous questions, I'm quite new at Progress-4GL development.
I've just created a windows (*.w file), together with a procedure file (*.p file), which are based on an include file (*.i file).
I've done something wrong and I get an error message, copy-paste reveals the following:
---------------------------
Fout
---------------------------
** Begin positie voor SUBSTRING, OVERLAY, enz. moet 1 of groter zijn. (82)
---------------------------
OK
---------------------------
As you can see, this is the Dutch translation of error 82:
** Starting position for SUBSTRING, OVERLAY, etc. must be 1 or greater. (82)
The SUBSTRING, OVERLAY, etc, functions require that the start position (second argument) be greater than or equal to 1.
P
I'd like to know which procedure/function is launching this error message. I'm working with the AppBuilder release 11.6 and the corresponding procedure editor, so the debugging possibilities are very limited. One thing I'm thinking of, is taking a dump of the Windows process, in order to determine the call stack, but I'm not sure how to do this. I also tried using Process Explorer and check the stack of the individual stacks of the threads inside the "procwin32.exe" process, but I'm not sure how to proceed.
By the way, I'm regularly adding message boxes to my code, which look as follows (just an example):
MESSAGE "begin procedure combobox-value-changed" VIEW-AS ALERT-BOX.
As you see, the name of the procedure is hardcoded, while in other programming languages (like C++) the procedure/function name can be shown as follows:
OUTPUT("begin procedure %s", __FUNCTION__);
Next to __FUNCTION__, C++ also knows __FILE__ (for filename) and __LINE__ (for line number).
Do such predefined values also exist in Progress 4GL, preferably release 11.6 or previous?
As ABL code is not compiled into Windows byte-code a windows debugger will not be really helpful.
You should start by adding the -debugalert startup parameter to prowin/prowin32.exe. Or add this
ASSIGN SESSION:DEBUG-ALERT = TRUE .
That will add a HELP button to all (error) messages which will open a dialog with the ABL stack trace.
As you'Re using include files, be aware that the line numbers referenced in the stack-trace are based on the debug listing, not the actual source code. So execute
COMPILE myfile.w DEBUG-LIST c:\temp\myfile.debuglist .
to receive the debug-listing file with the correct line numbers.
Are you aware of the visual debugger that's available for the AVM? https://docs.progress.com/de-DE/bundle/openedge-abl-troubleshoot-applications-117/page/Introduction.html
%DLC%\bin\proDebugger.bat
Or the Compile -> Debug menu in the AppBuilder.
It looks a bit antique, but usually does it's job.
Debugging needs to be enabled as an Administrator in proenv:
prodebugenable -enable-all
Of course the grass is greener when you switch to Progress Developer Studio as your IDE.
Regarding the second part of your question. See the PROGRAM-NAME function.
message
program-name(1) skip
program-name(2)
.
Additionally see the {} preprocessor name reference.
message 'file: {&file-name} line: {&line-number}'.

lldb command jump: resume outside the current function?

LLDB command jump lets me resume program execution at a different position from where it has stopped, but it seems to be restricted to addresses inside the current function:
(lldb) jump CLI.cpp:15
error: CLI.cpp:15 is outside the current function.
I'm curious about that, since this restriction is not documented in lldb's help, and the syntax jump <file>:<line> somehow indicates that one could use arbitrary entry points:
(lldb) help jump
('_regexp-jump') Set the program counter to a new address. Expects 'raw'
input (see 'help raw-input'.)
Syntax:
_regexp-jump <line>
_regexp-jump +<line-offset> | -<line-offset>
_regexp-jump <file>:<line>
_regexp-jump *<addr>
'jump' is an abbreviation for '_regexp-jump'
I'm aware that resuming in a different frame/stack may bring the program into an inconsistent state with "wonderful" side effects.
How can I jump to lines outside the current function in lldb (ignoring possible side effects)?
jump is a wrapper command that packages up some common uses of the underlying thread jump into a compact form. That's what all the _regex- commands are in lldb. Do:
(lldb) help command regex
if you want more details on this regex commands, and of course
(lldb) help thread jump
for everything you can do with that command.
The wrapper doesn't have an affordance to allow jumping outside the current function because that is definitely NOT a safe operation, so the default is to assume you made a mistake in typing the line or file name...
The underlying command does have a --force option that allows you to move the pc out of the current function.

Behaviour of debuggers regarding Step Over + Breakpoints

(I'm coding a debugger. But my doubt is also from the point of view of a debugger user)
Many debuggers in many languages (GDB, Eclipse) implement a STEP_OVER command that permits to execute one statement at a time; the difference with STEP_INTO is that it does not perform the stepping down in stack (i.e., called functions), which is often a good thing.
10 : y = f1(x);
11 : z = y + 1;
Now, suppose I step over line 10 above, but a breakpoint is hit inside function f1 (perhaps several levels deep in the call stack). It's not clear what should happen when I resume: should the debugger pause at line 11 (effectively "completing the step over" command)? Or should it forget about it? I believe most (all?) debuggers do the later. Is that the standard/expected behaviour? I myself have found this a little frustrating. Is there a way (in some debugger) to resume execution from the inside breakpoint to the outside stepped-over statement? Or is there some way to do a step-over-ignoring breakpoints?
WinDbg does the latter, and I believe this is standard behavior. If you are worried about a different breakpoint occurring during a step-over command, you could always manually set a breakpoint on line 11 and continue running until line 11 is hit. Alternatively, you could temporarily disable the other breakpoints, but note that the debugger still may break for other reasons as well (such as raising an exception), depending on its configuration.

SPARC window_overflow

Suppose I have 8 windows like this figure: http://www.sics.se/~psm/sparcwin.gif
And I'm right in that situation, WIM points to w7, and I'm in window w0.
Suppose that in this window, I'm going to call some function that recives one parameter. So I set the parameter value to %o1 (to let the function recive it in %i0).
Ok, then I make the call, and the function does a 'save'. WIM in that window bit is 1, so a window_overflow is triggered. What I understood about this, is that the handler save on the stack of window w7 (%sp), the registers %i1,..,%i7,%l0,..,%l7, to let then 'when going back' in the window_underflow recover that window.
My question is... when the window is saved, the originals %i0,...,%i7 of w7 where lost due to now are the parameters of the function that the program in w0 called (because I set %o0,.. in w0 before calling and then make the 'save' fault). So this "system" does not make sense, so I guess I'm missing something.
Another similar question. Suppose my program in w0 does not call a function, but use %o0,%o1,.. as "local" variables, I would have the same problem without even know that I killed %i0,%i1,.. of w7.
ANSWER: I found that the invalid windows is already saved in the stack, so when the 'save' is done, the window_overflow handler would save w6 in the stack (and set WIM to w6). This obviously explains all about my question. I guess I confused myselft when seeing an handler example of this trap and not remembering that in V8 it always decrements CWP without checking WIM.

How to break on __NSAutoreleaseNoPool

I'm getting peppered with
*** __NSAutoreleaseNoPool(): Object 0x1961180 of class NSEvent autoreleased with no pool in place - just leaking
warnings during run-time and have no idea what the cause is. Cursory Googles indicate that this is a symbol I can break on with Xcode, but adding it as a symbolic breakpoint via Run>Manage Breakpoints>Add Symbolic Breakpoint, or simply via the breakpoints management window, results in a breakpoint with a - next to it instead of a check, which I take to mean it's a symbol that can't be found.
I've tried adding the symbol "__NSAutoreleaseNoPool" with two underscores, one underscore, and now I'm just feeling stupid. The errors continue to get logged and no breakpoints get hit. Any pointers for breaking on Obj-C symbols or debugging this would be appreciated.
[EDIT: after maybe 10 (10 more, so a couple dozen total, including at least two Xcode restarts) runs I got "Pending breakpoint 9 - "__NSAutoreleaseNoPool" resolved" printed to my console and the breakpoint started working. Is there any way to force a pending breakpoint to actually resolve?]
To actually answer your question, look in NSDebug.h. There you will find a comment of which this is part:
NAME OF ENV. VARIABLE DEFAULT SET TO...
NSDebugEnabled NO "YES"
NSZombieEnabled NO "YES"
NSDeallocateZombies NO "YES"
NSHangOnUncaughtException NO "YES"
and farther down are these comments:
// Functions used as interesting breakpoints in a debugger
// void __NSAutoreleaseNoPool(void *object);
// Called to log the "Object X of class Y autoreleased with no
// pool in place - just leaking" message. If an environment
// variable named "NSAutoreleaseHaltOnNoPool" is set with string
// value "YES", the function will automatically break in the
// debugger (or terminate the process).
// void __NSAutoreleaseFreedObject(void *freedObject);
// Called when a previously freed object would be released
// by an autorelease pool. If an environment variable named
// "NSAutoreleaseHaltOnFreedObject" is set with string value
// "YES", the function will automatically break in the debugger
// (or terminate the process).
So you don't really need to set these breakpoints; just set the appropriate environment variables. You can do the latter either from your e.g. .bashrc or in Xcode 4 you can edit the "Run" section of your "scheme" and set them there -- that's what I do, and it works just fine.
I have the same issue on setting breakpoint on __NSAutoreleaseNoPool().
I finally successfully set the break point use gdb command.
After debugger started, press ctrl+C in debugger console.
Use "br __NSAutoreleaseNoPool" to set the break point and restart the debugger.
It sounds like you're using Cocoa in a thread somewhere and not wrapping the thread body with an autorelease pool. You probably don't need to use breakpoints to find this. Are you doing any detachNewThreadSelector?
The issue here is simple: You are releasing with no pool in place. This usually happens in command line tools written against Foundation. Simply add the following code to your main(): (Irrelevant parts omitted)
int main (…) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
/// Your code goes here.
[pool drain]; // This one might not strictly speaking be neccessary.
[pool release];
return 0;
}
Edit: If you are not creating a command line tool, chances are you are doing something naughty; but nonetheless: If you have code you invoke before NSApplicationMain(), you need to wrap this in the same basic code, draining and releasing the pool before the invocation of NSApplicationMain.
I know this is an old thread. Just wanted to share some light on the right solution.
The right way to have a breakpoint at _autoreleasenopool is using the breakpoint navigator in xcode.(use the key command+6).
In the bottom left portion of the breakpoint navigator click '+' sign and add symbolic breaakpoint. Enter the symbol as objc_autoreleaseNoPool.

Resources