Re: JIT debugging (Attach and speed)

Pedro Alves
2016-03-23T18:24:54Z

On 03/23/2016 04:51 AM, Yichao Yu wrote:
>>>>> Yeah, there's no full fix available, only some ideas thrown out.
>>>>> The last discussed one wouldn't cause a regression -- the
>>>>> "longjmp"-caching idea. We may still need to defer breakpoint re-set
>>>>> to at most once per jit load event, something like Paul's original
>>>>> patch, but with a breakpoint_re_set call somewhere.
>
> I've just run the profile myself and got some quite different result
> from the 2011 thread[1].
> With no breakpoint in gdb and simply jitting O(2000) functions: [2]
> With one (un-triggered) breakpoint in gdb and jitting O(1500) functions: [3]
>
> It seems that there's other slowness when there are breakpoint created
> but in terms of scaling, the fastest growing one is the sorting in
> `update_section_map`
>
> [1] https://sourceware.org/ml/gdb/2011-01/msg00009.html
> [2] http://i.imgur.com/6Ca6Yal.jpg
> [3] http://i.imgur.com/aHKGACX.jpg

Ouch. Not sure what to do here.

Maybe we could cache something above find_pc_section ->
update_section_map, to avoid the section look ups.
From [2], we see that this is in the inline frame sniffer.
Maybe we can add a shortcut here, based on assuming that if
we're stopped at the jit event breakpoint address, then we're
not stopped at an inlining site. That is, a trick similar to
the pc_at_non_inline_function check in infrun.c.

So, as a quick hack, if you make inline_frame_sniffer bail out early
with 0, does it improve things?

>
>>>>> It'd even be better to somehow restrict breakpoint re-setting
>>>>> to the jit modules that were added/removed/changed, but
>>>>> that's harder.
>
> I've re-read the 2011 thread and I think I have a slightly better
> understanding now. IIUC we need to check if the newly registered file
> contains any pending breakpoints. Is the problem that this is done by
> checking it over all the registered object files? Is it possible to
> avoid O(n^2) scaling without only re-setting on the jit object file
> currently being modified?

Batch loading the object files comes to mind. From reading
the code, it seems like gdb only reads on object file per
JIT_REGISTER event. The descriptor->relevant_entry one.
Is that correct? Is there a reason the loader couldn't batch
compile all functions, only call the JIT_REGISTER once, and
then have GDB follow descriptor->relevant_entry->next_entry, etc.?

If we could batch load, then we could also defer breakpoint re-set
until all is loaded, as well as inhibit section map updates,
as done in svr4_handle_solib_event for normal DSO loading.

Thanks,
Pedro Alves