They were using the current task, but that's not always the case.
LLDB, for example, calls mach_vm_region_recurse with the map of the task
it's debugging.
std::stoul is base 10 by default, so we were trying to process hex
values as decimal values(producing incorrect values, as expected).
Also, memoryRegionInfo now returns a structure with the info rather than
having everything passed in as a reference, just like memoryInfo was
recently changed to do as well. This should make easier to add more info
fields later.
This is only a subset of its actual behavior, but this is all that the
LKM supported and everything (read: LLDB) seemed to run fine with that,
so that should be enough for us as well.
This is actually a valid state for `thread_block_parameter` to enter.
If the caller gave us a continuation but we were unable to wait, we
should simply invoke the continuation with the wait result, much like
we would if we were returning the result.
Unmanaged calls are those that can come from unmanaged processes,
i.e. processes that the server does not control. They can also come from
managed processes, but they don't have to.
This commit does not introduce any unmanaged calls, however.
During local development, I created one and later decided to discard it.
However, this does seem like a useful feature, so it's being added with
this commit.
The main debugging code added is for keeping track of port names and
their associated IPC objects, as well as keeping track of the members of
port sets.
Additionally, when extended debugging is enabled, the server can now
wait for a debugger with the new env var `DSERVER_WAIT4DEBUGGER`.
The AsyncWriter class was originally written for some additional
debugging code I wrote but later decided wouldn't really be useful.
I kept the AsyncWriter class, however, as it seems it might be useful
for future code (it's basically fire-and-forget asynchronous writing).
Note that it has not been tested at all.
We now handle the sigexc calls as normal calls, with the exception that
it's okay for them to become active while another call was active.
We also set the thread's wait result to THREAD_INTERRUPTED and handle
syscall returns in interrupted continuations by jumping back to the
sigexc_enter code.
It doesn't support memory sharing or copying to a map other than the
current task yet. However, the LKM didn't support the latter case either,
so the only thing we're really missing is the ability to create a shared
region from a previously private one.
When a microthread went to sleep with a continuation, we discarded its
call. This would lead to the call being disposed before we had a chance
to reply to it. Instead, now we keep a reference to it in the thread
until we send a reply for it.
This function works properly now.
Additionally, add some more debug code to Mach port kqchannels,
but remove some debug code from `misc.c` (it causes issues with ASAN).
If we don't tell ASAN about what we're doing with microthreads, it gets
majorly confused about what's going on and generates lots of false
positives.
This is mainly because it poisons the stack, which we re-use when we
start a microthread from a new point (e.g. from a continuation or a new
call). The solution is simple: just tell ASAN that that memory for the
stack is OK when we do this.
Informing ASAN about our microthreads (which it calls "fibers") is just
a neat bonus to have it recognize our microthread stacks as actual stacks
and not just random memory.