Sometimes when looking at someone else's large Objective-C program, it is hard to know where to begin.
In such situations, I think it would be helpful to log every call to every non-Apple method.
Is there a way to do that? Basically, make one change in some central place, and log every method that is called. Preferably limited to non-Apple methods.
You can set the environment variable NSObjCMessageLoggingEnabled to YES. This will write a log of all message sends in the folder /tmp/msgSends-xxx.
You could add a symbolic breakpoint to objc_msgSend(), and have it log the second parameter without stopping.
How to do it for your own methods only though is a toucher task. Maybe if you could inspect the class name being called and do some magic to have a conditional breakpoint for only calls where the class' prefix matches your own?
I don't think logging every single call is practical enough to be useful, but here's a suggestion in that direction.
On a side note, if it's a large program, it better have some kind of documentation or an intro comment for people to get started with the code.
In any case, every Cocoa application has an applicationDidFinishLaunching... method. It's a good place to start from. Some apps also have their principal (or 'main window') class defined in the Info.plist file. Both these things might give you a hint as to what classes (specifically, view controllers) are the most prominent ones and what methods are likely to have long stack-traces while the program is running. Like a game-loop in a game engine, or some other frequently called method. By placing a breakpoint inside such a method and looking at the stack-trace in the debugger, you can get a general idea of what's going on.
If it's a UI-heavy app, looking at its NIB files and classes used in them may also help identify parts of app's functionality you might be looking for.
Another option is to fire up the Time Profiler instrument and check both Hide missing symbols and Hide system libraries checkboxes. This will give you not only a bird's eye view on the methods being called inside the program, but also will pin-point the most often called ones.
By interacting with your program with the Time Profiler recording on, you could also identify different parts of the program's functionality and correlate them with your actions pretty easily.
Instruments allows you to build your own "instruments", which are really just DTrace scripts in disguise. Use the menu option Instrument >> Build New Instrument and select options like which library you'd like to trace, what you'd like to record when you hit particular functions, etc. Go wild!
That's an interesting question. The answer would be more interesting if the solution supported multiple execution threads and there were some sort of call timeline that could report the activity over time (maybe especially with user events plotted in somehow).
I usually fire up the debugger, set a breakpoint at the main entry point (e.g. - applicationDidFinishLaunching:withOptions:) and walk it in the debugger.
On OSX, there are also some command-line tools (e.g. sample and heap) that can provide some insight.
It seems like some kind of integration with instruments could be really cool, but I am not aware of something that does exactly what you're wanting (and I want it now too after thinking about it).
If one were to log a thread number, and call address, and some frame details, it seems like the pieces would be there to plot the call timeline. The logic for figuring out the appropriate library (Apple-provided or third party) should exist in Apple's symbolicatecrash script.
Related
I would like to create a wxPython app such that:
If I run a second instance of that app (e.g., call the Python script from the shell a second time), no new instance should be created.
Instead, the toplevel frame of the already running instance should be raised and focussed.
The first point can be easily implemented by wx.SingleInstanceChecker (see the example code there), but at least the example code only gives a way for making the second instance of the app abort, but not raise the existing app's main frame.
I am using wxPython-Phoenix with Python 3.
Claritication: I would much prefer an out-of-the-box solution like wx.SingleInstanceChecker (that is, not implement my own locking and IPC solution).
You can use any kind of IPC to send a message asking the other program to do whatever needs to be done (just raise its top level window or maybe handle the command line options passed to the second instance). In C++ there are wxConnection and the related wxServer and wxClient classes that can be used for this, but I'm not sure if they're wrapped by wxPython -- however you could use any Python IPC module instead, if they aren't.
As has been pointed out, the "correct" way to do this is IPC because you have a new process that is supposed to affect a change (raise and focus) in another process.
What you seem to want is to take advantage of the IPC channel that wx.SingleInstanceChecker is already using to do your work. Unfortunately, you can't. That class is implemented in the wxWidgets c++ code and therefore there are no Python bindings to the internal workings of the class.
However, you can probably abuse wx.SingleInstanceChecker to do what you want. In your program, you can set up a timer at some rapid interval (say, 250ms) that will constantly check IsAnotherRunning() from your main process. Therefore, when your second process starts up, the first will notice and can raise itself to the front. You would just have to wait for a little bit in the secondary process before it exits, to give the first time to notice.
As soon as you hit "Play" what happens in the background of the software? The code is already compiled and ready at this point. So when I press "Play" the code gets executed. What other things occur along with this?
I have this question as an assignment and would really like to know. Thanks. :)
Actually everything is loaded by script. This graph explains the process. Also the links below can be useful for you to understand all the background process.
Execution Order of Event Functions
Overview: Script compilation
Asking what happens when you press Play is like asking Coke to reveal the drink recipe. This is what they sell. You got that as assignment, fact is you can say anything and your teacher would lie to tell you wrong, since he does not know either (except if he works for a company that bought the source code of the engine).
What you can say, is that the OpenGl/DirectX API is initialised, registration of all event to the OS like Input, application data and so on, then all the Engine functioning, registering of the needed classes in memory, init of the physics, parsing of the opening scene YAML file, creation of the content and placement in space, for each item, if a MonoBehaviour, registration of all callbacks, all the debug code related to profiler and stack tracing, crash reports and many more...
Those are the obvious ones and I cannot have any clue of what is going on without using a tool to decompose the code. Problem, it is against the EULA and then illegal.
I am trying to brainstorm how to go about creating a program that will be actively running alongside my application and will watch for messageboxes to be shown in the application and take all the information(text, buttons, parameters) included with that messagebox and house them as an object in a global variable available throughout my application.
Is there anyway to tell programatically in my application that a messagebox is about to appear and to take any information related to it and place it in an object? Aside from having to scan the code, which isn't what I'm looking for especially since there's many places messageboxes will appear, this would give incorrect information.
Or is there a better way to go about this? All I'm looking for is information associated with the messagebox that is about to appear(and not show the messagebox then)
Any tips or websites I could reference is greatly appreciated!!!
Create your own class that takes in the same parameters as the standard messagebox.show and then calls the messagebox.show passing the parameters on. When you are ready, you can then put some code before the standard call that will capture the information.
I always create my own messagebox.show so I can control it. It's nice to have a standard title and there maybe time that you need to do special stuff with it, like log the messages.
BTW, because of scoping, if your class is in the same project, yours will be used instead of the standard, unless you fully qualified it: system.windows.forms.messagebox.show().
When attached to the debugger via Xcode, LLDB provides a useful view of local variables (the bottom left of the screenshot):
I found an LLDB command frame variable (and gdb's info locals) that provides a list of the local variables (as seen in the right side of the screenshot above).
My hope is that this functionality is possible to perform on the device at runtime. For example, I can access the stack trace using backtrace_symbols(), the current selector via _cmd, and a few others.
Has anyone had experience in this area? Thanks in advance.
Xcode/LLDB can show you this information because they have access to debug information in the binary, called a symbol table, which help it understand what memory locations correspond to which names in your source code. This is all outside the Objective-C runtime, and there's no interface in the runtime to get at it.
There's another reason why this won't work, though. When you're building code to run in the debugger, compiler optimizations are turned off, so all the variables you reference in your code are there.
When you build for release, though, generally the compiler optimizations get in there and re-arrange all your carefully named local variables to make things run faster. They might not even ever get stored in memory, just in CPU registers. Or they might not exist at all, if the optimizer can prove to itself that it doesn't need them.
My advice is to think again about the larger problem you're trying to solve...
I'm writing an OS X launch agent (which watches, as it happens, for FSEvents);
it therefore has no UI and is not started from a bundle – it's just a program.
The relevant documentation and sample
code
illustrates persisting FS event IDs between invocations, and does so using
NSUserDefaults. This is clear the Right Thing To Do(TM).
The documentation for NSUserDefaults in the
Preferences and Settings Programming Guide
would appear to be the appropriate thing to read.
This shows only the Application and Global domains as being persistent, but (fairly
obviously) only the Application domain is writable for an application. However
the preferences in the application domain are keyed on the
ApplicationBundleIdentifier, which a launch agent won't have. So I'm at a loss
how such an agent should persist state.
All I can think of is that the Label in the launchd job can act as the
ApplicationBundleIdentifier – it at least has the correct form. But I can't see any
hint that that's correct, in the documentation.
The obvious (unix-normal) thing to do would be to write to a dot-file
in $HOME, but that's presumably not the Cocoa Way. Google searches
on 'osx daemon preferences', and the like, don't show up anything useful,
or else my google-fu is sadly lacking today. Googling for 'set application
bundle identifier' doesn't turn up anything likely, either.
NSUserDefaults:persistentDomainForName looks like it should be relevant,
but I can't work out its intentions from its method documentation.
I've found one question here which seems relevant, but while it's tantalisingly close, it doesn't say where the daemon gets its identifier from.
I've limited experience with Objective-C and Cocoa, which means that by
now I rather suspect I'm barking up the wrong tree, but don't really know where
to look next.
You can (and imo should) have an Info.plist even in a single-file executable.(see http://www.red-sweater.com/blog/2083/the-power-of-plist)
However, NSUserDefaults is a little more questionable. Conceptually, it's intended for user settings, rather than internal state. However, there's no real reason it wouldn't be suited to this, so I'd probably go ahead and do so.