I saw this question: How can I programatically get the list of frameworks and libraries included in an ios project? here, which tries to answer similar question. However, I've two questions on this
The answer in above link (or see code below) - does it provide all frameworks or "only" frameworks that are linked to the project.
for (NSBundle *framework in [NSBundle allFrameworks])
NSLog(@"%@",framework.bundlePath.lastPathComponent);
if I see a framework appearing in above code, how can I find its usage in my code. I see many frameworks being referred to in above code, but I'm not able to figure out where exactly are they used. As per my knowledge, few of them are not used - is there a proper way to find this out.
Update 1:
I made a simple new app with absolutely no code in it. Then, I executed the for
loop above and found that, it also presented me with all the frameworks - which means, the code above simply prints all the frameworks and not the one that I am essentially be using in my app. But, does it mean that all frameworks that are printed are linked to the app?
The dynamic loader dyld(3)
provides this information. This code will print all loaded frameworks and shared libraries as well:
#include <stdio.h>
#include <dlfcn.h>
#include <mach-o/dyld.h>
int main() {
uint32_t c = _dyld_image_count();
for(uint32_t i = 0; i < c; ++i) {
printf("%d: %s\n", i, _dyld_get_image_name(i));
}
return 0;
}
EDIT: allFrameworks
lists only frameworks which are linked to your app, and which contain at least one Objective-C class (see https://developer.apple.com/documentation/foundation/nsbundle/1408056-allframeworks).
Searching for referrers is should be very difficult in general. If you are just looking for a single function, you can add a static implementation of the function and call the loaded variant from it. This technique is used for overwriting __cxa_throw
for instance, but it should also work for other functions:
static cxa_throw_t sCxa_throw = 0;
extern "C" void __cxa_throw(void *inException, void *inPvtinfo, void (*inDestination)(void *)) {
if (sCxa_throw == NULL) {
sCxa_throw = (cxa_throw_t)dlsym(RTLD_NEXT, "__cxa_throw");
}
sCxa_throw(inException, inPvtinfo, inDestination);
}
The variable sCXA_throw
contains the reference to the dynamic version of this function while the loader uses the static version. Inside of this function you can determine the callers with unwinding the stack with libunwind.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With