From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24288 invoked by alias); 26 Mar 2009 00:05:23 -0000 Received: (qmail 23731 invoked by uid 22791); 26 Mar 2009 00:05:09 -0000 X-SWARE-Spam-Status: No, hits=-0.5 required=5.0 tests=BAYES_05,SARE_MSGID_LONG40,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mail-gx0-f179.google.com (HELO mail-gx0-f179.google.com) (209.85.217.179) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 26 Mar 2009 00:05:05 +0000 Received: by gxk27 with SMTP id 27so748397gxk.0 for ; Wed, 25 Mar 2009 17:05:02 -0700 (PDT) MIME-Version: 1.0 Received: by 10.231.16.134 with SMTP id o6mr39801iba.53.1238025902457; Wed, 25 Mar 2009 17:05:02 -0700 (PDT) Date: Thu, 26 Mar 2009 00:05:00 -0000 Message-ID: Subject: How does gdb handle syscall restarting on Linux? From: Scott Long To: gdb@sourceware.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2009-03/txt/msg00161.txt.bz2 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