Mirror of the gdb mailing list
 help / color / mirror / Atom feed
From: Scott Long <smxlong@gmail.com>
To: gdb@sourceware.org
Subject: How does gdb handle syscall restarting on Linux?
Date: Thu, 26 Mar 2009 00:05:00 -0000	[thread overview]
Message-ID: <a348a4b0903251705k463f7810pcea9cee736dbb526@mail.gmail.com> (raw)

I'm developing a lightweight process control library for Linux,
essentially a wrapper around ptrace() but with the ability to inject
code into processes for instrumentation ("attach and profile"
functionality). I've hit an issue which I'm sure gdb must also
encounter, and was wondering how gdb deals with it.

I've already perused the gdb source, but can't find the relevant code.

What I am observing is that I attach to a process, wait for it to
stop, poke some code into memory as well as a stack frame, twiddle ESP
and EIP, then restart the process.

The symptom is that the process attempts to execute from an EIP value
which is 2 less than the value I set it to. In this case, this EIP
value points to an invalid address, and the inferior process crashes
when I attempt to restart it.

What I believe has happened is that the SIGSTOP which was delivered
when I attached, interrupted a system call in the inferior process.
The kernel is now trying to restart this system call by adjusting EIP
by -2 (the size of an "int 0x80" instruction).

How can I detect this situation, and more importantly, how do I handle
it? A few thoughts have occurred to me.

1. I could check if the current EIP is somewhere in the vDSO region,
and if so, assume that I've interrupted a system call. Restart the
process and try again, until I'm not in the vDSO any more.

2. Similar to 1, but "keep on trucking" by adding 2 to my EIP value to
account for the -2 the kernel will set -- then adjust the original EIP
by -2 as if the kernel had done it.

3. Ignore the issue, and place a pad page full of NOP instructions
immediately prior to the injected code. Now it doesn't matter than EIP
is off, it will just follow the NOPs until it hits the real code.

My concern is that I don't want to damage process semantics by doing
something invalid, like causing a system call or a signal to silently
get lost.

It seems like gdb MUST be able to deal with this. If there is code in
gdb which does this, I'd love to have a pointer to it, to avoid
wasting anybody's time here.

Thanks,
Scott Long


             reply	other threads:[~2009-03-26  0:05 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-26  0:05 Scott Long [this message]
2009-03-26  0:20 ` Pedro Alves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a348a4b0903251705k463f7810pcea9cee736dbb526@mail.gmail.com \
    --to=smxlong@gmail.com \
    --cc=gdb@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox