How to get atexit hooks to run in the presence of execv?

R

R. Bernstein

As a hobby I've been (re)writing a debugger. One of the commands,
"restart", works by calling an execv(). You may need to do this when
the program you are debugging is threaded or when one needs to ensure
that all program state is reinitialized.

Recently, I added remote debugging via TCP sockets. (Well, also FIFO's
as well but closing sockets before restarting is what's of concern.)

I noticed that execv in Python 2.5.2 doesn't arrange exit hooks to get
called. Should it? Furthermore, I don't seen any atexit routine that
would let me initiate such finalization. Should there be one?

Or perhaps I'm missing something. Is there a way to arrange atexit
hooks to get run before issuing an execv-like call?

Thanks.
 
M

Mark Wooding

Recently, I added remote debugging via TCP sockets. (Well, also FIFO's
as well but closing sockets before restarting is what's of concern.)

I noticed that execv in Python 2.5.2 doesn't arrange exit hooks to get
called. Should it?

I'd consider that to be highly unusual. Certainly, the C atexit(3)
function is called only in response to a call to exit(3) (possibly
implicitly by returning from main), and not by execve(2) or any of its
little friends.

Your specific problem is to do with file descriptors, so it's probably
best dealt with using the close-on-exec flag:

from fcntl import fcntl, F_GETFD, F_SETFD, F_CLOEXEC

sk = socket(...)
## ...
fcntl(sk.fileno(), F_SETFD,
fcntl(sk.fileno(), F_GETFD) | FD_CLOEXEC)

Now the socket will be magically closed when you exec.. another program.

Finally, can I urge against TCP sockets in an application like this?
Certainly without adequate authentication, it will simply be insecure
even within a single multiuser host (e.g., using localhost only) -- and
assuming that even a home machine has only a single user is becoming
less realistic. Unix-domain sockets live in the filesystem, and access
to them is limited using the standard filesystem mechanisms.

If you're expecting inter-host communications (e.g., remote debugging),
it's a good idea to protect the session using TLS or something (much as
I dislike the TLS certification/public-key- distribution model it's way
better than nothing at all).

-- [mdw]
 
R

R. Bernstein

Mark Wooding said:
I'd consider that to be highly unusual. Certainly, the C atexit(3)
function is called only in response to a call to exit(3) (possibly
implicitly by returning from main), and not by execve(2) or any of its
little friends.

Your specific problem is to do with file descriptors, so it's probably
best dealt with using the close-on-exec flag:

from fcntl import fcntl, F_GETFD, F_SETFD, F_CLOEXEC

sk = socket(...)
## ...
fcntl(sk.fileno(), F_SETFD,
fcntl(sk.fileno(), F_GETFD) | FD_CLOEXEC)

Now the socket will be magically closed when you exec.. another program.

Thanks for the wealth of information. Alas, somehow I think this begs
the question. I *know* how to arrange in the debugger for it to clean
up after itself. But it's the program being debugged which I have no
control over. And I would like to give it an opportunity to clean up
after itself.
Finally, can I urge against TCP sockets in an application like this?

By all means, I hope people will offer thoughts, concerns and ideas.
Certainly without adequate authentication, it will simply be insecure
even within a single multiuser host (e.g., using localhost only) -- and
assuming that even a home machine has only a single user is becoming
less realistic. Unix-domain sockets live in the filesystem, and access
to them is limited using the standard filesystem mechanisms.

If you're expecting inter-host communications (e.g., remote debugging),
it's a good idea to protect the session using TLS or something (much as
I dislike the TLS certification/public-key- distribution model it's way
better than nothing at all).

Well, I also started coding FIFO's as well as TCP sockets, partly
because I could, and partly to try to try to keep the interface
generic. And in the back of my mind, I'd like to add serial devices as
well - I don't see a reason not to.

Initially, I probably won't add authentication or encryption. I'm
having enough of a time trying to get this much working. (cpickling
over sockets seems to still require knowing how many messages were
sent and unpickling each of those, and TCP_NODELAY isn't allowed and
doesn't seem the right thing either.)

However what I really would like to see is authentication and
encription added as an independent plugin layer much as I view whether
one is debugging locally or not. So I don't see this as an issue per
se with TCP sockets.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,008
Latest member
HaroldDark

Latest Threads

Top