Reading process memory

Hello,

I'm trying to read some memory from a stopped process. However, the
read function errors out with "process is running" message even though
SBProcess::GetState tells me that the process is stopped. The process
was stopped because it hit a breakpoint.

SBProcess(0x7fed13981600)::GetState () => stopped
SBProcess(0x7fed13981600)::GetState () => stopped
SBProcess(0x7fed13981600)::ReadMemory (addr=0x7fff5fc34000,
dst=0x112eff900, dst_len=4096, SBError (0x0))...
SBProcess(0x7fed13981600)::ReadMemory() => error: process is running
SBProcess(0x7fed13981600)::ReadMemory (addr=0x7fff5fc34000,
dst=0x112eff900, dst_len=4096, SBError (0x7fed12621ee0): error:
process is running) => 0

I have two questions:
- Is this a bug/known issue? I'm using lldb library that comes with
Xcode 5 version lldb-310.2.37 (though I read somewhere that these
version numbers don't help you much).

- Is there a mechanism to read memory of a running process?

Thanks,
Mike.

It should be easy for you to step through the SBProcess::ReadMemory() call and see what is going wrong. If the process is stopped, it should definitely be returning memory. You are sure you don't have thread race conditions where some other thread is resuming the process?

I only have one thread in operation, so I don't expect there do be any
race conditions unless LLDB has its own threads under the hood. So far
as I can tell, this lock fails for some reason:

        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process_sp->GetRunLock()))
        {
            Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
            bytes_read = process_sp->ReadMemory (addr, dst, dst_len,
sb_error.ref());
        }
        else
        {
            if (log)
                log->Printf ("SBProcess(%p)::ReadMemory() => error:
process is running",
                             static_cast<void*>(process_sp.get()));
            sb_error.SetErrorString("process is running");
        }

At the moment, I don't know why but would be happy to hear your thoughts.

Thanks,
Mike.

When the process resumes it takes a "run lock" to stop anything else that requires a process to stay stopped (like memory read, register read, or anything involving looking at the process). Only one thing can have the run lock at a time. When the process stops, one or more threads can take the "stop lock". It is like a read/write locker where the read lock can be taken by N threads and they will keep anyone from acquiring the write lock, and only one can take the write lock (process needs to run) after all readers have let go of the read lock (stay stopped). So somehow this isn't working on the system you are debugging on. That needs to be fixed.

Greg

As mentioned already on this list, some embedded devices permit reading
of certain memory regions whilst the processor is running.

For such situations it would be nice to engineer lldb to permit that
functionality.

Matt

In Windows you can read any of a process’s memory while the process is running.

I've been doing some more investigation on this bug and have tried a
couple things to isolate it. First I ran this command:

debugger.HandleCommand("memory read --outfile /tmp/mem.txt --count
512 0x####");

It worked as expected. This leads me to believe that the bug is
somewhere in the API layer. Then I tried to disable async via
"debugger.SetAsync(false);" and the ReadMemory command started working
as expected.

So, the run lock doesn't seem to get unlocked properly when a
breakpoint is hit in the async mode. I've not had a chance to narrow
it down any further yet, but I wanted to post this up in case it rings
a bell to someone more familiar with that part of the code.

Thanks,
Mike.