[lldb-dev] Further Linux adventures

Greg Clayton gclayton at apple.com
Sun Oct 30 13:40:47 PDT 2011


If the LinuxPlugin is always debugging  a native local process, the GetByteOrder() should look like:

ByteOrder
ProcessLinux::GetByteOrder() const
{
	lldb::endian::InlHostByteOrder();
}

I don't think, someone correct me if I am wrong, that the ProcessLinux plug-in can be used for remote debugging? If so, the above fix will work. Else, checking with the object file is ok as long as you always have the correct file selected prior to running. 

For the ptrace logging instead of using sprintf, I would suggest using the StringStream:

#include "lldb/Core/StreamString.h"

StringStream strm;

Then your display_bytes() function would take a "lldb_private::Stream &" instead of a "char *" and your code would look like:


void 
display_bytes (lldb_private::StreamString &strm, void *bytes, uint32_t count)
{
    uint8_t *ptr = (uint8_t *)bytes;
    const uint32_t loop_count = std::min<uint32_t>(DEBUG_PTRACE_MAXBYTES, count);
    for(uint32_t i=0; i<loop_count; i++)
    {
		strm.Printf ("[%x]", *ptr);
        ptr++;
    }
}

Also, don't worry about #ifdef'ing out the ptrace logging, there is already a "ptrace" logging channel that you are using, If you only want to see the logging when "verbose" is enabled which can be done via:

    LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_PTRACE));
    LogSP verbose_log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_PTRACE | LINUX_LOG_VERBOSE));

Then just check for the "verbose_log" when you want to dump the bits. So instead of:


#ifdef DEBUG_PTRACE
    if (log)
    {


You would have:

    if (verbose_log)
    {


So I would switch over to using the StreamString and don't use the #ifdef DEBUG_PTRACE. One goal in LLDB is to always be able to log the things that are going wrong, and the ptrace calls and the data fall into those categories.

Greg Clayton

On Oct 30, 2011, at 1:07 PM, Joel Dillon wrote:

> There was another stray plain int I'd missed in the code that reads registers, truncating the PC.
> The attached patch makes lldb compile (modulo some link ordering dependency problems that
> I don't have enough cmake-fu to fix properly) and work on Linux (and as a bonus prevents a 
> segfault when attempting to attach to a running process, though that functionality appears
> to be unimplemented as yet). I also added some extra logging for ptrace that helped me catch
> some of the problems.
> 
> On Thu, Oct 27, 2011 at 12:54 PM, Greg Clayton <gclayton at apple.com> wrote:
> 
> The darwin ptrace call looks from <sys/ptrace.h> looks like:
> 
> int ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);
> 
> I never try to use "int" "long" as types when programming in LLDB and we would try to exclusively use "uint*_t" and "int*_t" where the type is explicit. The only exception to the rule is if you are wrapping an API (like say "ptrace") where it returns a specific type in the header file ("int" in our header file). If the return types differ from system to system, we should templatize the code the uses it.
> 
> So overall we should try to use the explicitly sized integer typedefs from stdint.h (uint8_t, uint16_t, uint32_t, etc) to avoid any such issues. It sounds like there are some issues in the Linux plug-in. The function is:
> 
> void
> LinuxThread::BreakNotify(const ProcessMessage &message)
> {
>    bool status;
>    LogSP log (ProcessLinuxLog::GetLogIfAllCategoriesSet (LINUX_LOG_THREAD));
> 
>    assert(GetRegisterContextLinux());
>    status = GetRegisterContextLinux()->UpdateAfterBreakpoint();
>    assert(status && "Breakpoint update failed!");
> 
>    // With our register state restored, resolve the breakpoint object
>    // corresponding to our current PC.
>    assert(GetRegisterContext());
>    lldb::addr_t pc = GetRegisterContext()->GetPC();
>    if (log)
>        log->Printf ("LinuxThread::%s () PC=0x%8.8llx", __FUNCTION__, pc);
>    lldb::BreakpointSiteSP bp_site(GetProcess().GetBreakpointSiteList().FindByAddress(pc));
>    assert(bp_site);
>    lldb::break_id_t bp_id = bp_site->GetID();
>    assert(bp_site && bp_site->ValidForThisThread(this));
> 
> 
>    m_breakpoint = bp_site;
>    m_stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id);
> }
> 
> 
> 
> Liiks like the PC is read from the register context and there doesn't seem to be a breakpoint site. Enable the logging before you run:
> 
> (lldb) log enable plugin.process.linux thread
> (lldb) run
> 
> This should cause the PC to be logged. Then you should check that a software breakpoint was indeed set at this location. You might also want to verify that no one removed the breakpoint site after stopping?
> 
> 
> 
> <linux.diff>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20111030/d25dbbcd/attachment.html>


More information about the lldb-dev mailing list