This is an archive of the discontinued LLVM Phabricator instance.

Delay calling ObjC class list read utility functions very early in process startup
ClosedPublic

Authored by jasonmolenda on Nov 30 2022, 3:44 PM.

Details

Summary

When you are very early in process startup, before the system libraries have been initialized, and you run a simple expression, on Darwin systems, the Objective-C runtime plugin will run two utility functions to fetch the list of Objective-C class names in the inferior process. These function calls can cause problems when the process launch is this early, and the user expression may have been a simple one like "p globalvar=1" which would be harmless and not require a jitted expression.

This patch adds code to debugserver to use libdyld calls to find the process launch state, returns it in a JSON reply for a "jGetDyldProcessState" packet. This is passed up to DynamicLoaderMacOS::IsFullyInitialized() which checks for three specific process states that happen early in process startup, before system library initialization is completed.

Thread::SafeToCallFunctions() currently, on macOS, checks to see if the current thread is in __select, and does not run utility functions if it is. This patch updates SafeToCallFunctions() to also call DynamicLoader::IsFullyInitialized(), and avoid running utility functions if that is the case.

Then there are updates to AppleObjCRuntimeV2 to check the threads for SafeToCallFunctions() before scanning for dynamic objective-c classes, or the static shared cache objective-c classes.

I added a test case which stops process launch on the first malloc() call, runs a simple expression, and confirms (via the types log) that we did not read the objc class lists. Then it continues to main(), runs the simple expression again, and confirms (via types log) that it did read the objc class list.

The patch looks a bit big, mostly from piping the data from MachProcess::GetDyldProcessState() up to DynamicLoaderMacOS::IsFullyInitialized() through a handful of layers.

Diff Detail

Event Timeline

jasonmolenda created this revision.Nov 30 2022, 3:44 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 30 2022, 3:44 PM
jasonmolenda requested review of this revision.Nov 30 2022, 3:44 PM
JDevlieghere added inline comments.Nov 30 2022, 5:02 PM
lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
2519–2520

[begin bikeshedding]
Could we be more descriptive? Right now this sounds unactionable, which to be fair, it kind of is.

How about "could not execute support code to read Objective-C class data because it's not yet safe to do so and will be retried later.
[end bikeshedding]

Regardless we should say "class data" to match the other warnings or change those to say "class names".

Update patch to use Jonas' suggested wording of the warning we will issue when the objc class scanner functions cannot run yet, to make it clearer that they will run later and to match the style of the other warnings.

JDevlieghere accepted this revision.Dec 6 2022, 11:07 AM

LGTM

lldb/tools/debugserver/source/RNBRemote.h
111–140

Nit, since you're touching this, why not align it with 'QStartNoAckMode'?

This revision is now accepted and ready to land.Dec 6 2022, 11:07 AM
jasonmolenda added inline comments.Dec 6 2022, 11:15 AM
lldb/tools/debugserver/source/RNBRemote.h
111–140

clang-format decided to go on a little adventure here, when I added a line to this table. I didn't want to fight with it, so I just let it have its fun.