This adds a new LC_NOTE to ObjectFileMachO to represent additional metadata about threads in the corefile. Mach-O corefiles have each thread represented by an LC_THREAD which can only contain an array of register context "flavors" (pre-defined register sets by the kernel). This LC_NOTE has a JSON dictionary with metadata to add to each thread.
struct thread_extrainfo { char json_dictionary[]; // must be nul '\0' terminated c-string };
The JSON dictionary must have a threads key, and the value is an array. The array must have the same number of elements as there are LC_THREADs in the corefile, even if the entries are empty. Initially, only the thread_id key is supported. If a thread's dictionary does not specify a thread_id, lldb will make up a value for it.
An example:
{"threads":[{"thread_id":18427013},{"thread_id":18427037},{"thread_id":18427038}]}
which then looks like
(lldb) thr li Process 0 stopped thread #1: tid = 0x1192c85, 0x0000000185b19ea8 libsystem_kernel.dylib`__semwait_signal + 8 * thread #2: tid = 0x1192c9d, 0x0000000100000d6c a.out`crash_worker(in=0x0000000000000000) at main.cpp:15:18, stop reason = ESR_EC_DABORT_EL0 (fault address: 0x0) thread #3: tid = 0x1192c9e, 0x0000000185b19ea8 libsystem_kernel.dylib`__semwait_signal + 8
in lldb.
This patch adds support to ObjectFileMachO's process save-core to emit this metadata, and support to ObjectFileMachO, ProcessMachCore, ThreadMachCore to read & use those thread IDs when provided.
I expect to be adding additional thread attributes in the near future -- name, queue name, maybe a stop reason? -- they will be simple additions this format, but I'm hoping to get feedback on the format itself now. This is the first time we've had an LC_NOTE that did not use a strict binary representation with required format - by putting JSON in there, we do not have strict definitions of what is allowed to be included in the dictionary, but I think there are enough different use cases that this is the right choice for this one.
Thanks for factoring this out!