Hi Jim, just pinging this again to see if you've had a chance to take a
quick look at the ModulesDidLoad patch, let me know if you'd prefer I
submit this as a general patch for someone else to review. Thanks!


On Fri, Mar 7, 2014 at 10:41 AM, Andrew MacPherson <andrew.m...@gmail.com>wrote:

> Hi Jim,
>
> I've attached a patch here that does what you suggest, I created a
> ModulesDidLoad() on both the Process and the JITLoader and use this now to
> only search the new modules for necessary JIT symbols. This works great and
> startup time does seem faster on programs with large shared libraries.
>
> I didn't make ModulesDidLoad() on the Process virtual for now as there was
> no need for it in this particular case but if you'd prefer I do it anyway
> just let me know. I also left out SymbolsDidLoad() as I'd prefer to have a
> use case that I can test with it and I don't right now, I will certainly
> keep it in mind for later though.
>
> This new patch also does away with the need for the patch I sent yesterday
> as that code (and the crashing code you hit) has been replaced with this
> new method. I'm not sure what the status of building the JITLoaderGDB on
> OSX is right now, I haven't made any commits since the initial patch commit.
>
> Thanks for the help!
>
> Andrew
>
>
>
> On Thu, Mar 6, 2014 at 7:10 PM, <jing...@apple.com> wrote:
>
>> Andrew,
>>
>> I'll have to check out this patch when I get back home.  You very nicely
>> turned off the JITLoaderGDB for MacOS X, but now that I've updated, that
>> means I can't tell whether your patch fixes the crash :-(  I'm in the
>> middle of something else so I don't want to have to mess with this right
>> now, but my checkout at home is still in the state it was last night, so
>> I'll check it out there.
>>
>> We don't currently have a pluggable mechanism for watching shared library
>> loads, but there is a place where code belonging to Target & Process can
>> observe these changes synchronously.  That place is Target::ModulesDidLoad.
>>  Currently it handles the breakpoint resetting, and some work that Jason
>> needed to do for the "SystemRuntime plugin".  Since your JITLoader is also
>> internal to the process, it would be fine for you to hook in there and look
>> for your symbol.  I don't thing we need to come up with some generic
>> mechanism for this yet.
>>
>> However, when we had only one process thing doing a job in
>> Target::ModulesDidLoad it was kinda okay to check for m_process_sp and do
>> what is arguably process related work there:
>>
>> void
>> Target::ModulesDidLoad (ModuleList &module_list)
>> {
>>     if (module_list.GetSize())
>>     {
>>         m_breakpoint_list.UpdateBreakpoints (module_list, true, false);
>>         if (m_process_sp)
>>         {
>>             SystemRuntime *sys_runtime = m_process_sp->GetSystemRuntime();
>>             if (sys_runtime)
>>             {
>>                 sys_runtime->ModulesDidLoad (module_list);
>>             }
>>         }
>>         // TODO: make event data that packages up the module_list
>>         BroadcastEvent (eBroadcastBitModulesLoaded, NULL);
>>     }
>> }
>>
>> but now that there are two process related jobs, we should break this out
>> and make a Process::ModulesDidLoad and do the process related stuff there.
>>  If you don't mind splitting this off, then feel free to do so and put your
>> symbol search there rather than in the stop hook.
>>
>> If the work you have to do is applicable to generic processes there's no
>> reason to make Process::ModulesDidLoad virtual, but that might arguably be
>> useful.  Since there is Process generic work that is done here as well (the
>> SystemRuntime call) you'll have to deal with how partition the generic &
>> overridable behaviors.
>>
>> We have two patterns for structuring a task that requires some generic
>> work and some subclass, related work in lldb.  In some places we just
>> document in the base class method that you have to call the base class
>> method in your derived method.  Generally that's in code that aren't going
>> to have a lot of folks touching it, so you can trust that whoever changes
>> it will read the headers first.  In other places we have a non-virtual Task
>> method, and a virtual DoTask method, then the Task method does the generic
>> stuff and calls DoTask for the virtual part of the task.  The latter is
>> cleaner though it adds another method to the internal API.  Anyway, if it
>> makes sense to have this Process::ModulesDidLoad be virtual, feel free to
>> do this either way...
>>
>> You might also want to hook into SymbolsDidLoad, which gets called when a
>> symbol file gets added to a binary already loaded in the process.  That
>> would catch the case where your symbol was stripped from the binary, but
>> somebody added a symbol file that contained the symbol mid-way through the
>> debug run.
>>
>> Jim
>>
>> On Mar 6, 2014, at 1:52 AM, Andrew MacPherson <andrew.m...@gmail.com>
>> wrote:
>>
>> > Hi Jim,
>> >
>> > I agree that this part of the patch isn't pretty but I wasn't able to
>> find a way to be notified when a shared library is loaded (exactly as you
>> suggest). We need to check on launch or attach and then whenever a new
>> library is loaded, if there's a better way to do that it would be great to
>> clean this up.
>> >
>> > I can't reproduce the crash on Linux but it looks like we need to
>> unregister the notification callback that's set, that's the only reason I
>> can think of that you would end up in the ProcessStateChangedCallback with
>> an invalid baton pointer. I've attached a patch that I'm hoping will
>> resolve the issue here, it's definitely a bug that it wasn't being
>> unregistered.
>> >
>> > I hadn't intended for the JITLoaderGDB to be enabled on OSX as I wasn't
>> able to test it there, sorry about that. It's likely not useful there right
>> now as it would need modifications to the ObjectFileMachO to do some
>> relocations, and additionally MCJIT in LLVM would need to be modified to
>> call the GDB hook on OSX (though other JIT hosts may work). That said it
>> shouldn't be causing crashes if enabled.
>> >
>> > Thanks for looking into this.
>> >
>> > Cheers,
>> > Andrew
>> >
>> >
>> >
>> > On Thu, Mar 6, 2014 at 4:28 AM, Jim Ingham <jing...@apple.com> wrote:
>> > This part of the patch worries me.  If I am debugging a process that
>> doesn't have this JIT loader symbol, this bit means every time that the
>> process stops for any reason you will search the whole world for some
>> symbol that won't be found.  That's something we really avoid doing if we
>> can, programs get pretty big and this is not the sort of thing you want to
>> do.
>> >
>> > I don't know how this symbol comes about, is there no event (shared
>> library load or something) that you can hook into to find this symbol?
>> >
>> > This patch is also causing a crash on Mac OS X just running a program.
>>  The crash looks like:
>> >
>> > (lldb) bt
>> > * thread #8: tid = 0xf68e5, name =
>> <lldb.process.internal-state(pid=40372)>, function:
>> lldb_private::Process::GetTarget() , stop reason = EXC_BAD_ACCESS (code=1,
>> address=0x100)
>> >     frame #0: 0x0000000106f8072c
>> LLDB`lldb_private::Process::GetTarget() at Process.h:2516
>> >     frame #1: 0x0000000108e7aa5a
>> LLDB`JITLoaderGDB::GetSymbolAddress(lldb_private::ConstString const&,
>> lldb::SymbolType) const at JITLoaderGDB.cpp:368
>> >     frame #2: 0x0000000108e7a8bf LLDB`JITLoaderGDB::SetJITBreakpoint()
>> at JITLoaderGDB.cpp:99
>> >     frame #3: 0x0000000108e7a6d8
>> LLDB`JITLoaderGDB::ProcessStateChangedCallback(void*,
>> lldb_private::Process*, lldb::StateType) at JITLoaderGDB.cpp:354
>> >     frame #4: 0x0000000108b7b29b
>> LLDB`lldb_private::Process::SynchronouslyNotifyStateChanged(lldb::StateType)
>> at Process.cpp:1223
>> >     frame #5: 0x0000000108b89762
>> LLDB`lldb_private::Process::ShouldBroadcastEvent(lldb_private::Event*) at
>> Process.cpp:3846
>> >     frame #6: 0x0000000108b8454d
>> LLDB`lldb_private::Process::HandlePrivateEvent(std::__1::shared_ptr<lldb_private::Event>&)
>> at Process.cpp:4141
>> >     frame #7: 0x0000000108b8a755
>> LLDB`lldb_private::Process::RunPrivateStateThread() at Process.cpp:4290
>> >     frame #8: 0x0000000108b89bfd
>> LLDB`lldb_private::Process::PrivateStateThread(void*) at Process.cpp:4221
>> >     frame #9: 0x00000001087d811a LLDB`ThreadCreateTrampoline(void*) at
>> Host.cpp:629
>> >     frame #10: 0x00007fff815df899 libsystem_pthread.dylib`_pthread_body
>> >     frame #11: 0x00007fff815df72a libsystem_pthread.dylib`_pthread_start
>> >     frame #12: 0x00007fff815e3fc9 libsystem_pthread.dylib`thread_start
>> > (lldb) f 2
>> > frame #2: 0x0000000108e7a8bf LLDB`JITLoaderGDB::SetJITBreakpoint() at
>> JITLoaderGDB.cpp:99
>> >    96                 log->Printf("JITLoaderGDB::%s looking for JIT
>> register hook",
>> >    97                             __FUNCTION__);
>> >    98
>> > -> 99             addr_t jit_addr =
>> GetSymbolAddress(ConstString("__jit_debug_register_code"),
>> >    100                                               eSymbolTypeAny);
>> >    101            if (jit_addr == LLDB_INVALID_ADDRESS)
>> >    102                return;
>> > (lldb) expr *this
>> > (JITLoaderGDB) $13 = {
>> >   lldb_private::JITLoader = {
>> >     m_process = 0x0000000000000000 Public:
>> lldb_private::ThreadSafeValue<lldb::StateType> @  Private:
>> lldb_private::ThreadSafeValue<lldb::StateType> @
>> >   }
>> >   m_jit_objects = size=160215376 {
>> >     [0] = {
>> >       first = <parent is NULL>
>> >       second = <parent is NULL>
>> >     }
>> >     ...
>> >   }
>> >   m_jit_break_id = 0
>> >   m_notification_callbacks = {
>> >     baton = 0x0000000000000001
>> >     initialize = 0x00007fc54b00f3b0
>> >     process_state_changed = 0x00000001098cb150 (vtable for
>> std::__1::__shared_ptr_pointer<lldb_private::Section*,
>> std::__1::default_delete<lldb_private::Section>,
>> std::__1::allocator<lldb_private::Section> > + 16)
>> >   }
>> > }
>> >
>> > Looks like the JIT instance that is getting passed in is not good for
>> some reason.
>> >
>> > Jim
>> >
>> >
>> > On Mar 5, 2014, at 2:12 AM, Andrew MacPherson <andrew.m...@gmail.com>
>> wrote:
>> >
>> >> +void
>> >> +JITLoaderGDB::ProcessStateChangedCallback(void *baton,
>> >> +                                          lldb_private::Process
>> *process,
>> >> +                                          lldb::StateType state)
>> >> +{
>> >> +    JITLoaderGDB* instance = static_cast<JITLoaderGDB*>(baton);
>> >> +
>> >> +    switch (state)
>> >> +    {
>> >> +    case eStateConnected:
>> >> +    case eStateAttaching:
>> >> +    case eStateLaunching:
>> >> +    case eStateInvalid:
>> >> +    case eStateUnloaded:
>> >> +    case eStateExited:
>> >> +    case eStateDetached:
>> >> +        // instance->Clear(false);
>> >> +        break;
>> >> +
>> >> +    case eStateRunning:
>> >> +    case eStateStopped:
>> >> +        // Keep trying to set our JIT breakpoint each time we stop
>> until we
>> >> +        // succeed
>> >> +        if (!instance->DidSetJITBreakpoint() && process->IsAlive())
>> >> +            instance->SetJITBreakpoint();
>> >> +        break;
>> >> +
>> >> +    case eStateStepping:
>> >> +    case eStateCrashed:
>> >> +    case eStateSuspended:
>> >> +        break;
>> >> +    }
>> >> +}
>> >> +
>> >
>> >
>> > <jit-unregister-notification.patch>
>>
>>
>
_______________________________________________
lldb-commits mailing list
lldb-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to