[lldb-dev] starting a process in stop-at-entry-point mode on Linux

Greg Clayton gclayton at apple.com
Thu Jul 24 14:22:23 PDT 2014


We moved away from launching debugserver with args to setup and launch the process we can properly setup all things (environment, disable ASLR, set arch, set stdin/out/err files, set working dir, much more) and then launch. It also allows the host layer to do all the launching instead of sending hundreds of slow packets to set all this up.


> On Jul 24, 2014, at 2:12 PM, jingham at apple.com wrote:
> 
> When you connect to debugserver from lldb, and it doesn't have a process running, you can already just tell it to "run" and it will start up the target process.  That was actually the default in lldb for quite some time.  I don't remember now why we switched to having lldb launch things and then attach debugserver to them, do you Greg?
> 
> Jim
> 
>> On Jul 24, 2014, at 2:00 PM, Todd Fiala <tfiala at google.com> wrote:
>> 
>> Ah I see. Yeah that would work around the issues we have on Linux where different kernel versions differ on the handling of detaching from ptrace during a group stop (which is where I was originally going to start - have lldb fork/exec/ptrace, then detach, leaving process stopped, and hand off to llgs).
>> 
>> So in that case:
>> 
>> lldb can do the fork/exec, pass the inferior pid to llgs, wait for that to attach, lldb does the write to the pipe and close after this point, and then everything can move along merrily.
>> 
>> All that said, this does sound way more complicated than just modifying the flow to have llgs just launch the exe in the first place like it already can.
>> 
>> Greg - is there any reason it would be trouble for you guys if we modified the local debugging flow to have debugserver/llgs launch the inferior?  Then this would just work in both places without having to jump through implementing the stop-on-launch bits on Linux and anywhere else that didn't have that startup mode?
>> 
>> -Todd 
>> 
>> 
>> On Thu, Jul 24, 2014 at 1:40 PM, Greg Clayton <gclayton at apple.com> wrote:
>> Richard is suggesting you:
>> 
>> - open a pipe
>> - fork()
>> - child: close the write file descriptor and read from the read end (which blocks waiting for the parent)
>> - parent: close the read file descriptor
>> - parent: ptrace(PT_ATTACH, child_pid, ...)
>> - parent: write a byte to write end of the pipe and close write end
>> - child: read a byte from the read end and close the read end of pipe
>> 
>> 
>>> On Jul 24, 2014, at 1:28 PM, Todd Fiala <tfiala at google.com> wrote:
>>> 
>>> Hi Richard,
>>> 
>>> Can you say more about this part:
>>>> is to simply use a pipe between the parent and child to indicate when they're both ready.
>>> 
>>> I think I assumed too much context with Greg -
>>> 
>>> The exact scenario we're talking about is:
>>> 
>>> 1. Start up a process, going to be debugged, needs to be stopped at very-very start point (i.e. c/c++ library entry point).  Debugger will pick it up from here.
>>> 
>>> 2. Apple's flow for this when debugging over debugserver on a local process is to start the exe up from lldb, in a mode that starts the process but keeps it in (essentially) a group-stop state at that first entry point.  Then they have debugserver attach to that process.
>>> 
>>> I could try to rewire that scenario for Linux/* (which I had originally considered and may eventually get back to that point) to have llgs configured and then have llgs launch the process, which would work right now.  However, at the moment I'd like to see if I can not monkey around too much with the flow of starting a local llgs-debugged exe and just follow MacOSX's flow here.
>>> 
>>> Does your idea still fit into that context?
>>> 
>>> -Todd
>>> 
>>> 
>>> 
>>> On Thu, Jul 24, 2014 at 12:46 PM, Richard Mitton <richard at codersnotes.com> wrote:
>>> A better way, rather than messing with signals, is to simply use a pipe between the parent and child to indicate when they're both ready.
>>> 
>>> Richard Mitton
>>> richard at codersnotes.com
>>> 
>>> 
>>> On 07/24/2014 11:28 AM, Greg Clayton wrote:
>>> On Jul 23, 2014, at 4:44 PM, Todd R. Fiala <todd.fiala at gmail.com> wrote:
>>> 
>>> Hey Greg,
>>> 
>>> I’m looking into implementing process start-up so I can just follow your flow of launching the exe, then connecting via llgs with reverse connect.  I’d like to take a shot at getting Linux processes to start up in a “stopped at initial entry point” behavior rather than doing something different than MacOSX at this point.
>>> 
>>> Linux PTRACE doesn’t provide this out of the box.  There is an alternative that could work but is not reliable across Linux kernel versions: detaching from a PTRACE’d exe during a group-stop will leave it stopped.  I think the initial startup signal I get with PTRACE may yield a group stop.  If it’s not, I can immediately turn around and issue a stop, deliver that and get the real group stop.  (Not 100% sure I could do that last part with guaranteed no-execution semantics at the entry point location).  Unfortunately, the detach is not reliable everywhere I need this to run to keep the process in a stopped state at that point for handoff to llgs.
>>> What I could do instead, is fork, and have the child process self-send a SIGSTOP before doing the exec.  And, on Linux (and maybe FreeBSD), when llgs attaches, it just needs to know that it has to wait for one exec signal before the process really starts. (I’m not sure if there is a shell mode for debugging with Linux - if there is, then we need to exec through the shell script too, I think — I don’t remember seeing that on the linux code path so it likely is buggy and/or unsupported at the moment).  In any event, if I do this, I’m pretty sure I can guarantee that I can start a process in debug-ready mode with the caveat that there is an exec that has to be silently ignored when llgs attaches.
>>> 
>>> How does that sound?  Thoughts?
>>> The idea sounds good, as you can just do:
>>> 
>>> kill(getpid(), SIGSTOP)
>>> 
>>> but you can run into problems with the foreground app in a terminal not being able to SIGSTOP itself and you might get some SIGTTOU or SIGTTIN signals.
>>> 
>>> But do try it out. The ProcessLaunchInfo have:
>>> 
>>>         uint32_t
>>>         GetResumeCount () const
>>>         {
>>>             return m_resume_count;
>>>         }
>>> 
>>>         void
>>>         SetResumeCount (uint32_t c)
>>>         {
>>>             m_resume_count = c;
>>>         }
>>> 
>>> 
>>> So you just need to set this to 1 and it will continue past 1 exec without trying to read the dyld info for any execs before m_resume_count gets to zero.
>>> 
>>> Greg
>>> 
>>> 
>>> _______________________________________________
>>> lldb-dev mailing list
>>> lldb-dev at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>>> 
>>> 
>>> _______________________________________________
>>> lldb-dev mailing list
>>> lldb-dev at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>>> 
>>> 
>>> 
>>> --
>>> Todd Fiala |   Software Engineer |     tfiala at google.com |     650-943-3180
>>> 
>>> _______________________________________________
>>> lldb-dev mailing list
>>> lldb-dev at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
>> 
>> 
>> 
>> 
>> -- 
>> Todd Fiala |	 Software Engineer |	 tfiala at google.com |	 650-943-3180
>> 
>> _______________________________________________
>> lldb-dev mailing list
>> lldb-dev at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
> 





More information about the lldb-dev mailing list