Coder Social home page Coder Social logo

reptyr's Introduction

reptyr - A tool for "re-ptying" programs.

reptyr is a utility for taking an existing running program and attaching it to a new terminal. Started a long-running process over ssh, but have to leave and don't want to interrupt it? Just start a screen, use reptyr to grab it, and then kill the ssh session and head on home.

USAGE

reptyr PID

"reptyr PID" will grab the process with id PID and attach it to your current terminal.

After attaching, the process will take input from and write output to the new terminal, including ^C and ^Z. (Unfortunately, if you background it, you will still have to run "bg" or "fg" in the old terminal. This is likely impossible to fix in a reasonable way without patching your shell.)

Typical usage pattern

  • Start a long running process, e.g. top
  • Background the process with CTRL-Z
  • Resume the process in the background: bg
  • Display your running background jobs with jobs -l, this should look like this:
    • [1]+ 4711 Stopped (signal) top
    • (The -l in jobs -l makes sure you'll get the PID)
  • Disown the jobs from the current parent with disown top. After that, jobs will not show the job any more, but ps -a will.
  • Start your terminal multiplexer of choice, e.g. tmux
  • Reattach to the backgrounded process: reptyr 4711
  • Detach your terminal multiplexer (e.g. CTRL-A D) and close ssh
  • Reconnect ssh, attach to your multiplexer (e.g. tmux attach), rejoice!

"But wait, isn't this just screenify?"

There's a shell script called "screenify" that's been going around the internet for nigh on 10 years now that uses gdb to (supposedly) accomplish the same thing. The difference is that reptyr works much, much, better.

If you attach a "less" using screenify, it will still take input from the old terminal. If you attach an ncurses program using screenify, and resize the window, your program won't notice. If you attach a process with screenify, ^C in the new terminal won't work.

reptyr fixes all of these problems, and is the only such tool I know of that does so. See below for some more details on how it accomplishes this.

PORTABILITY

reptyr supports Linux and FreeBSD. Not all functionality is currently available on FreeBSD. (Notably, FreeBSD doesn't support reptyr -T at this time.

reptyr uses ptrace to attach to the target and control it at the syscall level, so it is highly dependent on details of the syscall API, available syscalls, and terminal ioctl()s. A port to other operating systems may be technically feasible, but requires significant low-level knowledge of the relevant platform, and may entail significant refactors.

reptyr works on i386, x86_64, and ARM. Ports to other architectures should be straightforward, and should in most cases be as simple as adding an arch/ARCH.h file and adding a clause to the ifdef ladder in ptrace.c.

ptrace_scope on Ubuntu Maverick and up

reptyr depends on the ptrace system call to attach to the remote program. On Ubuntu Maverick and higher, this ability is disabled by default for security reasons. You can enable it temporarily by doing

# echo 0 > /proc/sys/kernel/yama/ptrace_scope

as root, or permanently by editing the file /etc/sysctl.d/10-ptrace.conf, which also contains more information about exactly what this setting accomplishes.

reptyr -l

As a bonus feature, if you run "reptyr -l", reptyr will create a new pseudo-terminal pair with nothing attached to the slave end, and print its name out.

If you are debugging a program in gdb, you can pass that name to "set inferior-pty". Because there is no existing program listening to that tty, this will work much better than passing an existing shell's terminal.

How does it work?

The main thing that reptyr does that no one else does is that it actually changes the controlling terminal of the process you are attaching. I wrote a blog post explaining just what the shenanigans involved are.

PRONUNCIATION

I pronounce it like "repeater", but since that's easily ambiguous, "re-P-T-Y-er" is also acceptable.

CREDITS

reptyr was written by Nelson Elhage [email protected]. Contact him with any questions or bug reports.

URL

http://github.com/nelhage/reptyr

reptyr's People

Contributors

a1346054 avatar andoriyu avatar bkpepe avatar dependabot[bot] avatar divinity76 avatar ebroder avatar et7f3 avatar fawaf avatar graingert avatar heckendorfc avatar hypereye avatar ingramj avatar jwilk avatar kevans91 avatar lgautrot avatar nelhage avatar ony avatar pozdnychev avatar rakuco avatar ralph avatar reaperhulk avatar robryk avatar rwmacleod avatar sairon avatar scop avatar shachaf avatar theosotr avatar torwulf avatar vi avatar worr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reptyr's Issues

Hangup when running child processes

I am running a gedit instance from a terminal:

$ ps auf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
jeremie  14619  0.4  0.0  32032  7596 pts/1    Ss   00:37   0:00 bash
jeremie  14680 14.0  0.2 892612 48616 pts/1    Sl+  00:37   0:00  \_ gedit README.md

I then try to grab the underlying bash process:

./reptyr 14619

which works, but in the process it kills the running gedit instance:

$ ./reptyr 14860
[-] Timed out waiting for child stop.
Hangup

Not all commands react to the hangup in the same way though. E.g. sleep keeps on running in the previous terminal. Is the hangup intended?

Build fails on CentOS 5

Build fails on CentOS 5 (gcc-4.1.2, glibc-2.5):

$ make
cc -Wall -Werror -D_GNU_SOURCE -g   -c -o reptyr.o reptyr.c
In file included from platform/linux/linux.h:36,
                 from platform/platform.h:26,
                 from reptyr.c:37:
/usr/include/sys/wait.h:104: error: expected identifier before numeric constant

$ sed -ne '100,108p' /usr/include/sys/wait.h
/* The following values are used by the `waitid' function.  */
#if defined __USE_SVID || defined __USE_XOPEN
typedef enum
{
  P_ALL,        /* Wait for any child.  */
  P_PID,        /* Wait for specified process.  */
  P_PGID        /* Wait for members of process group.  */
} idtype_t;
#endif

It refuses to compile on Mac OS X

Is this LINUX only?

cc -Wall -Werror -D_GNU_SOURCE -g   -c -o reptyr.o reptyr.c
cc -Wall -Werror -D_GNU_SOURCE -g   -c -o ptrace.o ptrace.c
In file included from ptrace.c:1:
/usr/include/sys/ptrace.h:94: Error: error: expected declaration specifiers or ‘...’ before ‘pid_t’
/usr/include/sys/ptrace.h:94: Error: error: expected declaration specifiers or ‘...’ before ‘caddr_t’
cc1: warnings being treated as errors
ptrace.c:25: warning: ‘enum __ptrace_request’ declared inside parameter list
ptrace.c:25: warning: its scope is only this definition or declaration, which is probably not what you want
ptrace.c: In function ‘ptrace_attach_child’:
ptrace.c:35: Error: error: ‘PTRACE_ATTACH’ undeclared (first use in this function)
ptrace.c:35: Error: error: (Each undeclared identifier is reported only once
ptrace.c:35: Error: error: for each function it appears in.)
ptrace.c:35: Error: error: type of formal parameter 2 is incomplete
ptrace.c: In function ‘ptrace_finish_attach’:
ptrace.c:48: Error: error: ‘PTRACE_SETOPTIONS’ undeclared (first use in this function)
ptrace.c:48: Error: error: ‘PTRACE_O_TRACESYSGOOD’ undeclared (first use in this function)
ptrace.c:48: Error: error: ‘PTRACE_O_TRACEFORK’ undeclared (first use in this function)
ptrace.c:48: Error: error: type of formal parameter 2 is incomplete
ptrace.c:56: Error: error: ‘PTRACE_DETACH’ undeclared (first use in this function)
ptrace.c:56: Error: error: too many arguments to function ‘ptrace’
ptrace.c: In function ‘ptrace_detach_child’:
ptrace.c:61: Error: error: ‘PTRACE_DETACH’ undeclared (first use in this function)
ptrace.c:61: Error: error: type of formal parameter 2 is incomplete
ptrace.c: In function ‘ptrace_wait’:
ptrace.c:80: Error: error: ‘PTRACE_EVENT_FORK’ undeclared (first use in this function)
ptrace.c:81: Error: error: ‘PTRACE_GETEVENTMSG’ undeclared (first use in this function)
ptrace.c:81: Error: error: type of formal parameter 2 is incomplete
ptrace.c: In function ‘ptrace_advance_to_state’:
ptrace.c:103: Error: error: ‘PTRACE_SYSCALL’ undeclared (first use in this function)
ptrace.c:103: Error: error: type of formal parameter 2 is incomplete
ptrace.c:106: Error: error: ‘PTRACE_CONT’ undeclared (first use in this function)
ptrace.c:106: Error: error: type of formal parameter 2 is incomplete
ptrace.c:108: warning: implicit declaration of function ‘kill’
ptrace.c: In function ‘reset_user_struct’:
ptrace.c:126: Error: error: ‘struct user’ has no member named ‘regs’
ptrace.c:127: Error: error: ‘struct user’ has no member named ‘regs’
ptrace.c:127: Error: error: ‘struct user’ has no member named ‘regs’
ptrace.c: In function ‘ptrace_save_regs’:
ptrace.c:133: Error: error: ‘PTRACE_GETREGS’ undeclared (first use in this function)
ptrace.c:133: Error: error: type of formal parameter 2 is incomplete
ptrace.c: In function ‘ptrace_restore_regs’:
ptrace.c:140: Error: error: ‘PTRACE_SETREGS’ undeclared (first use in this function)
ptrace.c:140: Error: error: type of formal parameter 2 is incomplete
ptrace.c: In function ‘ptrace_remote_syscall’:
ptrace.c:159: Error: error: ‘PTRACE_POKEUSER’ undeclared (first use in this function)
ptrace.c:159: Error: error: ‘struct user’ has no member named ‘regs’
ptrace.c:159: Error: error: type of formal parameter 2 is incomplete
ptrace.c:160: Error: error: ‘struct user’ has no member named ‘regs’
ptrace.c:160: Error: error: type of formal parameter 2 is incomplete
ptrace.c:161: Error: error: ‘struct user’ has no member named ‘regs’
ptrace.c:161: Error: error: type of formal parameter 2 is incomplete
ptrace.c:162: Error: error: ‘struct user’ has no member named ‘regs’
ptrace.c:162: Error: error: type of formal parameter 2 is incomplete
ptrace.c:163: Error: error: ‘struct user’ has no member named ‘regs’
ptrace.c:163: Error: error: type of formal parameter 2 is incomplete
ptrace.c:164: Error: error: ‘struct user’ has no member named ‘regs’
ptrace.c:164: Error: error: type of formal parameter 2 is incomplete
ptrace.c:165: Error: error: ‘struct user’ has no member named ‘regs’
ptrace.c:165: Error: error: type of formal parameter 2 is incomplete
ptrace.c:170: Error: error: ‘PTRACE_PEEKUSER’ undeclared (first use in this function)
ptrace.c:170: Error: error: ‘struct user’ has no member named ‘regs’
ptrace.c:170: Error: error: type of formal parameter 2 is incomplete
ptrace.c:174: Error: error: ‘struct user’ has no member named ‘regs’
ptrace.c:174: Error: error: ‘struct user’ has no member named ‘regs’
ptrace.c:174: Error: error: type of formal parameter 2 is incomplete
ptrace.c:175: Error: error: ‘struct user’ has no member named ‘regs’
ptrace.c:175: Error: error: ‘struct user’ has no member named ‘regs’
ptrace.c:175: Error: error: type of formal parameter 2 is incomplete
ptrace.c: In function ‘ptrace_memcpy_to_child’:
ptrace.c:186: Error: error: ‘PTRACE_POKEDATA’ undeclared (first use in this function)
ptrace.c:186: Error: error: type of formal parameter 2 is incomplete
ptrace.c:194: Error: error: ‘PTRACE_PEEKDATA’ undeclared (first use in this function)
ptrace.c:194: Error: error: type of formal parameter 2 is incomplete
ptrace.c:198: Error: error: type of formal parameter 2 is incomplete
ptrace.c: In function ‘ptrace_memcpy_from_child’:
ptrace.c:209: Error: error: ‘PTRACE_PEEKDATA’ undeclared (first use in this function)
ptrace.c:209: Error: error: type of formal parameter 2 is incomplete
ptrace.c: At top level:
ptrace.c:224: warning: ‘enum __ptrace_request’ declared inside parameter list
ptrace.c:223: Error: error: parameter 2 (‘req’) has incomplete type
ptrace.c: In function ‘__ptrace_command’:
ptrace.c:227: Error: error: too many arguments to function ‘ptrace’
make: *** [ptrace.o] Error 1

Use case: attach to a bash shell

to execute a few commands there.

And then unattach from it again (restoring the state
before reptyr was used at all).

The idea is to get information from the bash shell (last command(s) run, env variables, current directory, and so forth), or even to run arbitrary commands there,
but then to restore it to a usable state, as if reptyr had never done anything to it (and it works in all terminals correctly again).

Is this sort of use case possible with reptyr?

Can you give a short instructions?

Test build fails with kernel < 3.4?

On CentOS 6 (kernel-headers-2.6.32):

$ make test
cc -Wall -Werror -D_GNU_SOURCE -g   -c -o test/victim.o test/victim.c
test/victim.c: In function ‘main’:
test/victim.c:8: error: ‘PR_SET_PTRACER’ undeclared (first use in this function)
test/victim.c:8: error: (Each undeclared identifier is reported only once
test/victim.c:8: error: for each function it appears in.)
test/victim.c:8: error: ‘PR_SET_PTRACER_ANY’ undeclared (first use in this function)
make: *** [test/victim.o] Error 1

I suppose PR_SET_PTRACER was added in kernel 3.4. Not sure what can be done about this, but if nothing else, document it?

make a new release :)

Hey.

There have been quite some interesting commits since the last release a year ago... when will we see a new release, which is more likely to be packaged by distros?

Cheers,
Chris.

Return value of attached command

Hi,

I looks to me, as if the return value of the process which reptyr attaches to cannot be retrieved.
Is there some technical limitation, is it not implemented or am I not using it correctly?

Greets! Jonathan

old terminal can still fg

Hi.

Not sure whether this is actually intended, not possible otherwise, or just a bug.

If I reptyr something to a new terminal, I can still say "fg" in the old terminal.
The application "stays" in the new one, but the old one is now also blocked, and even ^C or ^Z don't work there.

Cheers,
Chris.

Unable to attach to pid

Commands I tried to far:
a) echo "hi" ; sleep 200; echo "hi"
b) ping "foo.com"
c) irssi

Version: 0.5 on x64.
Tested on zsh + bash.

Steps to reproduce

$ ctrl+z                     # Suspend the current process
(I also tried to use bg here)
(optional: $ jobs -l      # get the PID )
$ disown "%1"           # Detach irssi from the shell

start a new terminal:

$ reptyr  <PID>  # Get back the process

Unfortunately I get the following error:

[+] Checking for problematic process group members...
[+] Allocated scratch page: 7f011f20d000
[+] Looking up fds for tty in child.
[+] Resolved child tty: 880a
[+] Found an alias for the tty: 0
[+] Found an alias for the tty: 1
[+] Found an alias for the tty: 2
[-] Unable to open the tty in the child.
Unable to attach to pid 15021: Permission denied

tty's echo setting not propagated

In my first test of this, I started up gdb in a terminal, then grabbed it in another terminal with reptyr. The two things I immediately noticed not working were that ^Z didn't suspend (but there's already an issue filed for that), and the receiving terminal did not echo my characters.

I was running gdb, so I entered !stty echo and it fixed it, but perhaps some of the settings should be propagated automatically? (Or something; terminals baffle me.)

Reliability

I need to reptyr badblocks in non-destructive read-write mode after the X server locked up. However I feel this is especially representative of any critical I/O based applications.

I am probably being paranoid, and I've already tested reptyr/badblocks in a virtual machine, and everything appeared fine. But I would probably never notice a single scrambled bad block.

So my question is this: Theoretically, is it possible/plausible for reptyr to scramble the FDs, accidentally write junk to a bad sector, or any other nightmare, that would compromise the reliability of critical applications.

Doesn't it work if the parent has child processes?

~/reptyr-master$ ./reptyr 946227
[-] Process 946489 (gmake) shares 946227's process group. Unable to attach.
(This most commonly means that 946227 has sub-processes).
Unable to attach to pid 946227: Invalid argument

Regards,
Manju

Failing with rtorrent.

Hi there.

If I run rtorrent as-is, then reptyr can move it however my old terminall still display rtorrent until i kill it (rtorrent that is).

if I have rtorrent running under screen, it can't move it., error log:

slashbeast@tomoyo reptyr % ./reptyr 30321
[+] Allocated scratch page: 7ffb4cd19000
[+] Looking up fds for tty in child.
[+] Resolved child tty: /dev/pts/5
[+] Found an alias for the tty: 0
[+] Found an alias for the tty: 1
[+] Found an alias for the tty: 2
[+] Opened the new tty in the child: 5
[+] TCGETS(0): 0
[+] TCSETS: 0
[+] Copied terminal settings
[+] Forked a child: 30641
[+] Change pgid for pid 30321
[-]  failed: Operation not permitted
[-] Failed to setsid: Operation not permitted
[+] Change pgid for pid 30641
Unable to attach to pid 30321: Operation not permitted

Funtoo 64bit, gcc 4.4.5.

allowing to attach from a non-interactive processes

Hello, first, thanks for repytr. It helped me:

http://tpo.sourcepole.ch/#writing-into-stdin-of-an-already-running-process

Now as you can see in that blog entry above, where I had to feed "yes" into a fsck, I had to find a work around for the fact that repytr won't attach from inside of a non-interactive tty.

It would be useful however if reptyr would allow that out of the box, without needing to work around the problem with script or similar.

So that's what I would like to propose as a feature. Some switch to tell reptyr to work from a --non_interactive_shell aka --don_t_read_terminal_attributes.

Best greets!

Build fails on CentOS 6

OS: CentOS release 6.10 (Final)

bash-4.1$ uname -a
Linux ru.ru 2.6.32-754.14.2.el6.x86_64 #1 SMP Tue May 14 19:35:42 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

Error:

bash-4.1$ make
cc -Wall -Werror -D_GNU_SOURCE -g    -c -o reptyr.o reptyr.c
cc -Wall -Werror -D_GNU_SOURCE -g    -c -o reallocarray.o reallocarray.c
cc -Wall -Werror -D_GNU_SOURCE -g    -c -o attach.o attach.c
cc -Wall -Werror -D_GNU_SOURCE -g    -c -o platform/linux/linux_ptrace.o platform/linux/linux_ptrace.c
platform/linux/linux_ptrace.c: In function ‘ptrace_save_regs’:
platform/linux/linux_ptrace.c:214: error: ‘PTRACE_GETREGSET’ undeclared (first use in this function)
platform/linux/linux_ptrace.c:214: error: (Each undeclared identifier is reported only once
platform/linux/linux_ptrace.c:214: error: for each function it appears in.)
platform/linux/linux_ptrace.c: In function ‘ptrace_restore_regs’:
platform/linux/linux_ptrace.c:228: error: ‘PTRACE_SETREGSET’ undeclared (first use in this function)
platform/linux/linux_ptrace.c: In function ‘ptrace_remote_syscall’:
platform/linux/linux_ptrace.c:255: error: ‘PTRACE_GETREGSET’ undeclared (first use in this function)
platform/linux/linux_ptrace.c:265: error: ‘PTRACE_SETREGSET’ undeclared (first use in this function)
make: *** [platform/linux/linux_ptrace.o] Error 1

how can I get the ouput of reptyr -l into tmux

I'm writing a script using tmux and gdb to automatically generate a productive debugger. Currently I use sleep infinity to set up an inferior tty. I'd like to switched to reptyr -l. However, i cannot get the output of reptyr -l in order to make the whole setting up process automatic.

The script looks like this ,

#!/usr/bin/env bash

tmux neww -n Debug
tmux splitw -h -p 50
tmux select-pane -t 1
tty1=$(tmux display -p "#{pane_tty}")
tmux splitw -v -p 40
tty3=$(tmux display -p "#{pane_tty}")
tmux select-pane -t 1
tmux splitw -v -p 40
tty2=$(tmux display -p "#{pane_tty}")
# tmux send-keys "reptyr -l" C-m
tmux send-keys "sleep infinity" C-m
tmux select-pane -t 4
tmux send-keys "cgdb -- $1 -tty $tty2 -ex \"dashboard -output $tty1\" -ex \"dashboard expression -output $tty3\"" C-m

X11 stealing?

unix sockets are unix sockets, so it should be possible to steal an X11 program from normal X11 and into X11-over-ssh, right?

it would be a really useful feature.

Mac

Hi,
This tool looks awesome. I'm excited to salvage a certain important process that I have disowned a while ago and have left running.
I'm on a mac and when I try to run make I get

/usr/local/bin/gcc-6 -Wall -Werror -D_GNU_SOURCE -g    -c -o reptyr.o reptyr.c
In file included from reptyr.c:37:0:
platform/platform.h:60:25: error: field 'addr' has incomplete type
         struct sockaddr addr;
                         ^~~~
platform/platform.h:61:28: error: field 'addr_un' has incomplete type
         struct sockaddr_un addr_un;
                            ^~~~~~~
make: *** [reptyr.o] Error 1

Any ideas?

reptyr group of processes?

Using FreeBSD. I started make buildkernel KERNCONF=MYKERNEL, then all like in Typical usage pattern section. ps -aj now shows:

USER       PID  PPID  PGID SID JOBC STAT TT     TIME COMMAND
...
root      1101   914  1101 914    1 T     1  0:00,01 sudo make buildkernel KERNCONF=GATEWAY
root      1102  1101  1101 914    1 T     1  0:00,00 make buildkernel KERNCONF=GATEWAY
root      1107  1102  1101 914    1 T     1  0:00,01 make -m /usr/src/share/mk -f Makefile.inc1 ...
root     39714  1107  1101 914    1 T     1  0:00,36 make -m /usr/src/share/mk KERNEL=kernel ...
root     41545 39714  1101 914    1 T     1  0:00,00 cc -c -O2 -pipe -fno-strict-aliasing -std=c99 ...
root     41546 41545  1101 914    1 T     1  0:00,42 /usr/bin/cc -cc1 -triple x86_64-unknown-freebsd10.3 ...
...

Trying to reptyr 1101 or any other results in:

[-] Process 1101 shares a process group with 5 other processes. Unable to attach.

Unable to attach to pid 1101: Invalid argument

Is it possible to resume all processes at once?

Test suite failure on ix86

Test suite fails on ix86 on Fedora 20 and development, succeeds on x86_64 and armv7hl:

https://kojipkgs.fedoraproject.org//work/tasks/615/8690615/build.log

python test/tty-steal.py
Traceback (most recent call last):
  File "test/tty-steal.py", line 16, in <module>
    reptyr.expect("ECHO: world")
  File "/usr/lib/python2.7/site-packages/pexpect/__init__.py", line 1418, in expect
    timeout, searchwindowsize)
  File "/usr/lib/python2.7/site-packages/pexpect/__init__.py", line 1433, in expect_list
    timeout, searchwindowsize)
  File "/usr/lib/python2.7/site-packages/pexpect/__init__.py", line 1521, in expect_loop
    raise EOF(str(err) + '\n' + str(self))
pexpect.EOF: End Of File (EOF). Exception style platform.
<pexpect.spawn object at 0xf725cb0c>
version: 3.1
command: ./reptyr
args: ['./reptyr', '-T', '8302']
searcher: <pexpect.searcher_re object at 0xf725cb4c>
buffer (last 100 chars): ''
before (last 100 chars): 'Unable to attach to pid 8302: Bad address\r\nworld\r\n'
after: <class 'pexpect.EOF'>
match: None
match_index: None
exitstatus: 1
flag_eof: True
pid: 8303
child_fd: 4
closed: False
timeout: 30
delimiter: <class 'pexpect.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1

PowerPC support?

I tried to compile. Didn't work. I tried to read the source, like amd64.h. Where do these magic numbers come from?

Won't build

Cloned db4fa12 hit make and reptyr wont' compile.

cc -Wall -Werror -D_GNU_SOURCE -g   -c -o reptyr.o reptyr.c
cc -Wall -Werror -D_GNU_SOURCE -g   -c -o ptrace.o ptrace.c
In file included from ptrace.h:23:0,
                 from ptrace.c:37:
/usr/include/linux/ptrace.h:58:8: error: redefinition of ‘struct ptrace_peeksiginfo_args’
 struct ptrace_peeksiginfo_args {
        ^
In file included from ptrace.c:22:0:
/usr/include/sys/ptrace.h:191:8: note: originally defined here
 struct ptrace_peeksiginfo_args
        ^
make: *** [ptrace.o] Error 1

Error on chown() function in attach.c

I am getting this error when trying to package it on arch, and I have no idea how to fix it.

cc -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -Wall -Werror -D_GNU_SOURCE -g -D_FORTIFY_SOURCE=2 -c -o reptyr.o reptyr.c
cc -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -Wall -Werror -D_GNU_SOURCE -g -D_FORTIFY_SOURCE=2 -c -o reallocarray.o reallocarray.c
cc -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -Wall -Werror -D_GNU_SOURCE -g -D_FORTIFY_SOURCE=2 -c -o attach.o attach.c
attach.c: In function ‘setup_steal_socket’:
attach.c:387:5: error: ignoring return value of ‘chown’, declared with attribute warn_unused_result [-Werror=unused-result]
chown(steal->addr_un.sun_path, steal->target_stat.uid, steal->target_stat.gid);
^
attach.c:388:5: error: ignoring return value of ‘chown’, declared with attribute warn_unused_result [-Werror=unused-result]
chown(steal->tmpdir, steal->target_stat.uid, steal->target_stat.gid);
^
cc1: all warnings being treated as errors
: recipe for target 'attach.o' failed
make: *** [attach.o] Error 1

Old terminal not freed

When grabbing a process, the old terminal is not freed. Ctrl-\ will free it but kill the original process. Ideally you'd want the terminal to be freed and a message saying it was grabbed by another terminal.

Build fails on CentOS 6 with CFLAGS=-O2

Build fails on CentOS 6 (at least x86_64) with CFLAGS=-O2 (gcc-4.4.7, glibc-2.12):

$ CFLAGS="-O2" make
cc -O2 -Wall -Werror -D_GNU_SOURCE -g   -c -o attach.o attach.c
cc1: warnings being treated as errors
attach.c: In function ‘steal_child_pty’:
attach.c:443: error: dereferencing pointer ‘cm’ does break strict-aliasing rules
attach.c:447: error: dereferencing pointer ‘cm’ does break strict-aliasing rules
attach.c:445: error: dereferencing pointer ‘cm’ does break strict-aliasing rules
attach.c:444: error: dereferencing pointer ‘cm’ does break strict-aliasing rules
attach.c:442: note: initialized from here
make: *** [attach.o] Error 1

commandline key to send SIGCONT to attached process

I think, it will be useful to have a commandline key to send SIGCONT to the attached process, which can be used in such pattern:

  1. process runs in, say, tmux or screen
  2. user presses ^Z
    2.5) user does not type bg to avoid process to write to stolen fds and freezes/crashes because of that
  3. user types disown
  4. user exits (not detach) tmux/screen (for example, to restart "server" instance for tmux)
  5. user enters new tmux/screen instance
  6. reptyr -<key> $PID

Yama: check ahead of trying ptrace attach would be more desirable

Since (a bit controversial) introduction of YAMA with default ptrace_scope set to 1 in Fedora 22, I had an unpleasant experience with reptyr attaching to vim process. Reptyr failed providing a good enough diagnostics about the problem, however when I fg'd the vim at the original terminal, I couldn't see the expected screen nor C^L was working (in retrospect, I've found out that blindly typing <Esc> followed with :redraw<Enter> would have actually helped me in that case).

Hence I would like to ask if either check_ptrace_scope detect-only-equivalent, or at least a dumb forked-child-tries-to-attach-to-parent test (or a mix of these two) could be carried out before actually trying the effective attach to prevent such distorted experience. Or would you consider this a vim's fault in not anticipating such scenario and in turn not redrawing when desired?

fail with android repo

The steps are:
repo forall -c 'git checkout -b XXX'
Ctrl+z
disown
screen
reptyr PID_OF_repo

The error log is:
[+] Allocated scratch page: 7f18b6fee000
[+] Looking up fds for tty in child.
[+] Resolved child tty: 8800
[+] Found an alias for the tty: 0
[+] Found an alias for the tty: 1
[+] Found an alias for the tty: 2
[+] Opened the new tty in the child: 4
[+] Target is not a session leader, attempting to setsid.
[+] Forked a child: 5115
[+] Change pgid for pid 4598
[+] Change pgid for pid 4617
[-] failed: Permission denied
[-] Failed to setsid: Operation not permitted
[+] Change pgid for pid 4598
[+] Change pgid for pid 5115
Unable to attach to pid 4598: Operation not permitted

BTW, i have changed /proc/sys/kernel/yama/ptrace_scope
cat /proc/sys/kernel/yama/ptrace_scope
0

When running as daemon, CPU usage is constantly at 100%

One of my use case with reptyr is with -L, to start an Emacs server process with an allocated PTY. Running reptyr -L emacs --fg-daemon=<server-name> works as expected. Unfortunately, when integrating the command with Runit[^1], the CPU usage caused by reptyr was constantly at 100%:

#!/usr/bin/env sh

exec 2>&1
exec reptyr -L emacs --fg-daemon=<server-name>

At first I thought was Emacs being mischievous. However, this happened even with simple shell scripts such as the following:

#!/usr/bin/env bash

while true; do
    echo $(date -R)
    sleep 1
done

The CPU usage came back to normal when running without reptyr -L. Any idea what might be the cause?

[^1] http://smarden.org/runit/

gcc believes that "scratch" might be uninitialized after grab_pid

gcc-4.9.2 and gcc-5.2.0 issue an error during build:

<builtin>: recipe for target 'attach.o' failed
ionice -c 3 nice -n 19 make -j12 --load-average=8
In file included from attach.c:46:0:
attach.c: In function 'steal_block_hup':
platform/platform.h:38:5: error: 'scratch' may be used uninitialized in this function [-Werror=maybe-uninitialized]
     ptrace_remote_syscall((child), ptrace_syscall_numbers((child))->nr_##name, \
     ^
attach.c:487:18: note: 'scratch' was declared here
     child_addr_t scratch;
                  ^
cc1: all warnings being treated as errors
make: *** [attach.o] Error 1

Though according to code of steal_block_hup:

    if ((err = grab_pid(steal->target_stat.sid, &leader, &scratch)))
        return err;

And in grab_pid:

    if ((err = mmap_scratch(child, scratch)))
        goto out_restore_regs; 

Which means that error propagated correctly.

Maybe code of mmap_scratch confuses compiler:

    if (scratch_page > (unsigned long) - 1000) {
        return -(signed long)scratch_page;
    }

    *addr = scratch_page;

Though it is clear that there no way to get 0 before assigning scratch_page to *addr.

Note that clang 3.7.0 able to build this code.

daemonize (feature)

One thing often happens. I start some long-running process - maybe in emacs shell. Now I want to go home, but unfortunately, I did not use emacs --daemon. Too late now.

I can use reptyr (start new emacs --daemon + emacsclient, shell, reptry). But what I'd like is to daemonize the process. That is, redirect the stdout/stderr to a logfile (with configurable logfile behaviour), and then daemonize the process.

Seems like reptyr could be a useful tool for this. Any thoughts? Maybe make a daemonize.py python script, and invoke it from reptry from it after deamonize redirects it's stdout/stderr?

Works in any Linux terminal?

Or does it have to be used in screen?

I get this when trying:

>>> reptyr 8274
Unable to attach to pid 8274: Operation not permitted
The kernel denied permission while attaching. If your uid matches
the target's, check the value of /proc/sys/kernel/yama/ptrace_scope.
For more information, see /etc/sysctl.d/10-ptrace.conf

>>> sudo reptyr 8274
[sudo] password for root:
[-] Unable to open the tty in the child.
Unable to attach to pid 8274: Permission denied

ptrace definition error when compiling

I'm getting a ptrace constant definition error when I compile. I'm not terribly familiar with ptrace; I'm guess that this error indicates that my kernel version is too old or that the system call is disabled, but if it's fixable that would be awesome. Unfortunately, I do not have root access on this box.

$ make

cc -Wall -Werror -D_GNU_SOURCE -g   -c -o reptyr.o reptyr.c
cc -Wall -Werror -D_GNU_SOURCE -g   -c -o ptrace.o ptrace.c
ptrace.c: In function ‘ptrace_finish_attach’:
ptrace.c:47: error: ‘PTRACE_O_TRACESYSGOOD’ undeclared (first use in this function)
ptrace.c:47: error: (Each undeclared identifier is reported only once
ptrace.c:47: error: for each function it appears in.)
ptrace.c:47: error: ‘PTRACE_O_TRACEFORK’ undeclared (first use in this function)
ptrace.c: In function ‘ptrace_wait’:
ptrace.c:79: error: ‘PTRACE_EVENT_FORK’ undeclared (first use in this function)
make: *** [ptrace.o] Error 1

System details:

$ uname -a

Linux [omitted] 2.6.18-238.1.1.el5 #1 SMP Tue Jan 4 13:32:19 EST 2011 x86_64 x86_64 x86_64 GNU/Linux

$ cat /etc/redhat-release

Red Hat Enterprise Linux Server release 5.6 (Tikanga)

$ ll /usr/include/sys/ptrace.h

-rw-r--r-- 1 root root 4778 Dec 14 12:08 /usr/include/sys/ptrace.h

reptyr -T fails with "Unable to attach [...] Permission Denied"

Hello, I'm running a version of Debian Jessie on armhf.

pi@raspberrypi ~/Downloads/reptyr $ sudo ./reptyr -T 31637 
Unable to attach to pid 31637: Permission denied

31637 has been disowned from it's parent terminal (but for the record, it does the exact same thing if the process is not disowned).

Screen not refreshed

I tried grabbing an HTOP process, the screen was not fully drawn so it showed just the changed cells on each update interval.

Permissive ptrace settings required

It seems that you need to have permissive ptrace settings for this to work. This is not the default on ubuntu, and can be changed temporarily by running (as root):
echo 0 > /proc/sys/kernel/yama/ptrace_scope
It can be changed permanently by editing the following file:
/etc/sysctl.d/10-ptrace.conf
I think a documentation update to this effect is in order.

Temporary child is left as zombie process

The child of the process to reptyr that was used in the setsid trickery stays as a zombie while the reptyr'ed process is running.
This is more like an 'uglyness' than a real problem. It could probably be solved by wait()ing to collect the child's status.

build on older glibc

i have old glibc 2.3 system where PTRACE_SETOPTIONS and PTRACE_GETEVENTMSG are not available. but the defines are present in newer version of linux-libc-headers

when compiling with manually defining the values or including linux/ptrace.h resulting binary seems working fine.

fix variant 1:

#ifndef PTRACE_SETOPTIONS
#define PTRACE_SETOPTIONS   0x4200
#endif
#define PTRACE_GETEVENTMSG  0x4201
#ifndef PTRACE_GETEVENTMSG
#endif

fix variant 2:

#include <linux/ptrace.h>

in that system:

linux-libc-headers-2.6.33.20-1.amd64
glibc-devel-2.3.6-18.amd64

tested resultng binary on 2.6.27.45-1 kernel with bc program.

Build failure with gcc 7.0.1

Build fails with current Fedora rawhide, gcc 7.0.1:

attach.c: In function ‘setup_steal_socket’:
attach.c:393:15: error: ‘%s’ directive output may be truncated writing up to 4095 bytes into a region of size 108 [-Werror=format-truncation=]
              "%s/reptyr.sock", steal->tmpdir);
               ^~
attach.c:392:5: note: ‘snprintf’ output between 13 and 4108 bytes into a destination of size 108
     snprintf(steal->addr_un.sun_path, sizeof(steal->addr_un.sun_path),
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              "%s/reptyr.sock", steal->tmpdir);
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors

Reptyr works for binaries but not for scripts

I'm using nelhage-reptyr-61cc5f8 on Ubuntu 10.04.3 LTS). On a terminal I created a script like this:

!/bin/bash

while true
do
sleep 5
date
done

Once I started it I open another terminal and tried to reptyr the bash process, or the parent bash process. The original one was stopped (as if ^Z had been typed) but the output was still coming out on the original terminal. Maybe that's normal behaviour for scripts but just in case I report it.

macOS support

Since #83 (just titled "Mac") was closed via fe7a276, it's apparent that that issue was about failing with a better error message. Since it looks like there's no other issue tracking Mac support, I figured I'd create this one.

Thanks for releasing reptyr!

Can't build current master on x86

In file included from ptrace.c:97:0:
arch/default-syscalls.h:30:1: error: '__NR_socket' undeclared here (not in a function)
arch/default-syscalls.h:31:1: error: '__NR_connect' undeclared here (not in a function)
arch/default-syscalls.h:32:1: error: '__NR_sendmsg' undeclared here (not in a function)

I don't expect i386 to have all these syscalls, there is socketcall instead.

Building for amd64 works fine.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.