google / google/EarlGrey

Question: why we need to add EarlGrey.framework to DYLD_INSERT_LIBRARIES

Open
#653 8 comments 0 reactions 0 assignees View on GitHub
Dominant language
Objective-C
Stars
5.7k
Forks
737
Avg merge
1d 20h
Merged PRs (30d)
5

Description

I've read https://github.com/google/EarlGrey/blob/master/docs/ifaq.md and it explained why.

I am wondering if this is necessary, so I did some experiments:

1. I added a module initializer to EarlGray.m:

__attribute__((constructor))
static void initializer(int argc, char** argv, char** envp) {
static int initialized = 0;
if (!initialized) {
// Initialization code.
initialized = 1;
}
}

and setup a breakpoint in it.

2. Run any test in ExampleTest, when the breakpoint is hit, it shows the following call stack:

* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x0000000151817b2f (*hide test name*)`initializer(argc=5, argv=0x00007ffee21268a0, envp=0x00007ffee21268d0) at EarlGrey.m:34
frame #1: 0x00000001336d7c16 dyld_sim`ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) + 420
frame #2: 0x00000001336d7e46 dyld_sim`ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) + 40
frame #3: 0x00000001336d36da dyld_sim`ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 330
frame #4: 0x00000001336d2898 dyld_sim`ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 134
frame #5: 0x00000001336d292c dyld_sim`ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) + 74
frame #6: 0x00000001336c9956 dyld_sim`dyld::runInitializers(ImageLoader*) + 82
frame #7: 0x00000001336cf076 dyld_sim`dlopen + 803
frame #8: 0x000000013e24aa47 libdyld.dylib`dlopen + 86
frame #9: 0x0000000136b00808 CoreFoundation`_CFBundleDlfcnLoadBundle + 152
frame #10: 0x0000000136b00694 CoreFoundation`_CFBundleLoadExecutableAndReturnError + 324
frame #11: 0x00000001342b4ec1 Foundation`-[NSBundle loadAndReturnError:] + 520
frame #12: 0x00000001337a3860 IDEBundleInjection`__XCBundleInjection + 798
frame #13: 0x00000001336d7c16 dyld_sim`ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) + 420
frame #14: 0x00000001336d7e46 dyld_sim`ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) + 40
frame #15: 0x00000001336d36da dyld_sim`ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 330
frame #16: 0x00000001336d2898 dyld_sim`ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) + 134
frame #17: 0x00000001336d292c dyld_sim`ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) + 74
frame #18: 0x00000001336c715d dyld_sim`dyld::initializeMainExecutable() + 166
frame #19: 0x00000001336cac98 dyld_sim`dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) + 4412
frame #20: 0x00000001336c63d4 dyld_sim`start_sim + 136
frame #21: 0x000000013c40cded dyld`dyld::useSimulatorDyld(int, macho_header const*, char const*, int, char const**, char const**, char const**, unsigned long*, unsigned long*) + 2200
frame #22: 0x000000013c40a7a3 dyld`dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) + 436
frame #23: 0x000000013c4063d4 dyld`dyldbootstrap::start(macho_header const*, int, char const**, long, macho_header const*, unsigned long*) + 453
frame #24: 0x000000013c4061d2 dyld`_dyld_start + 54

3. Also add a break point at the beginning main function of App under test, and confirm:
a. it is hit later than loading EarlGray.framework
b. check EarlGray.framework did get loaded by dyld

So looks like once test target is linked against EarlGrey.framework, it get loaded at a very early stage when dyld is loading libraries for AUT. Is library loaded through DYLD_INSERT_LIBRARIES get loaded earlier than this? If true, is there anything EarlGrey is tracking even before main function get running?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.