From: Kevin Buettner <kevinb@cygnus.com>
To: Michael Snyder <msnyder@cygnus.com>
Cc: Kick Damien-DKICK1 <DKICK1@motorola.com>, gdb-patches@sources.redhat.com
Subject: [PATCH RFA #2] Retry open()s in procfs.c
Date: Fri, 13 Apr 2001 18:55:00 -0000 [thread overview]
Message-ID: <1010414015521.ZM21085@ocotillo.lan> (raw)
I request approval for committing the patch below.
This patch supercedes the patch I submitted in:
http://sources.redhat.com/ml/gdb-patches/2001-04/msg00133.html
In addition to handling the original problem that I was seeing on AIX5
(which involved a race between GDB and the kernel in opening/creating
/proc/PID/ctl), this patch handles other conditions in which it may be
desirable to retry an open() in procfs.c. In particular, I hope that
it will also fix the problem reported by Damien Kick in:
http://sources.redhat.com/ml/gdb/2001-04/msg00078.html
(Damien, I would appreciate it if you'd give this patch a try and
let me know if it fixes the problem that you reported.)
I've tested these changes on AIX5 and it does gracefully handle the
race condition noted above. (I added a temporary printf() just before
the sleep() to verify that the ``else'' clause does indeed get hit and
operates as expected.) I've also run the GDB testsuite on both
i586-sco-sysv5uw7.1.1 and i386-pc-solaris2.8 and see no regressions.
Okay to commit?
* procfs.c (open_with_retry): New function.
(open_procinfo_files, load_syscalls, proc_iterate_over_mappings)
(proc_get_LDT_entry): Call open_with_retry() instead of open().
Index: procfs.c
===================================================================
RCS file: /cvs/src/src/gdb/procfs.c,v
retrieving revision 1.26
diff -u -p -r1.26 procfs.c
--- procfs.c 2001/03/27 02:01:11 1.26
+++ procfs.c 2001/04/14 01:37:56
@@ -458,6 +458,40 @@ find_procinfo_or_die (int pid, int tid)
return pi;
}
+/* open_with_retry() is a wrapper for open(). The appropriate
+ open() call is attempted; if unsuccessful, it will be retried as
+ many times as needed for the EAGAIN and EINTR conditions.
+
+ For other conditions, open_with_retry() will retry the open() a
+ limited number of times. In addition, a short sleep is imposed
+ prior to retrying the open(). The reason for this sleep is to give
+ the kernel a chance to catch up and create the file in question in
+ the event that GDB "wins" the race to open a file before the kernel
+ has created it. */
+
+static int
+open_with_retry (const char *pathname, int flags)
+{
+ int retries_remaining, status;
+
+ retries_remaining = 2;
+
+ while (1)
+ {
+ status = open (pathname, flags);
+
+ if (status >= 0 || retries_remaining == 0)
+ break;
+ else if (errno != EINTR && errno != EAGAIN)
+ {
+ retries_remaining--;
+ sleep (1);
+ }
+ }
+
+ return status;
+}
+
/*
* Function: open_procinfo_files
*
@@ -543,7 +577,7 @@ open_procinfo_files (procinfo *pi, int w
strcat (tmp, "/lwpctl");
else
strcat (tmp, "/ctl");
- fd = open (tmp, O_WRONLY);
+ fd = open_with_retry (tmp, O_WRONLY);
if (fd <= 0)
return 0; /* fail */
pi->ctl_fd = fd;
@@ -552,7 +586,7 @@ open_procinfo_files (procinfo *pi, int w
if (pi->tid)
return 0; /* there is no 'as' file descriptor for an lwp */
strcat (tmp, "/as");
- fd = open (tmp, O_RDWR);
+ fd = open_with_retry (tmp, O_RDWR);
if (fd <= 0)
return 0; /* fail */
pi->as_fd = fd;
@@ -562,7 +596,7 @@ open_procinfo_files (procinfo *pi, int w
strcat (tmp, "/lwpstatus");
else
strcat (tmp, "/status");
- fd = open (tmp, O_RDONLY);
+ fd = open_with_retry (tmp, O_RDONLY);
if (fd <= 0)
return 0; /* fail */
pi->status_fd = fd;
@@ -586,12 +620,13 @@ open_procinfo_files (procinfo *pi, int w
#ifdef PIOCTSTATUS /* OSF */
- if ((fd = open (pi->pathname, O_RDWR)) == 0) /* Only one FD; just open it. */
+ /* Only one FD; just open it. */
+ if ((fd = open_with_retry (pi->pathname, O_RDWR)) == 0)
return 0;
#else /* Sol 2.5, Irix, other? */
if (pi->tid == 0) /* Master procinfo for the process */
{
- fd = open (pi->pathname, O_RDWR);
+ fd = open_with_retry (pi->pathname, O_RDWR);
if (fd <= 0)
return 0; /* fail */
}
@@ -843,7 +878,7 @@ load_syscalls (procinfo *pi)
/* Open the file descriptor for the sysent file */
sprintf (pathname, "/proc/%d/sysent", pi->pid);
- sysent_fd = open (pathname, O_RDONLY);
+ sysent_fd = open_with_retry (pathname, O_RDONLY);
if (sysent_fd < 0)
{
error ("load_syscalls: Can't open /proc/%d/sysent", pi->pid);
@@ -2874,7 +2909,7 @@ proc_iterate_over_mappings (int (*func)
#ifdef NEW_PROC_API
/* Open map fd. */
sprintf (pathname, "/proc/%d/map", pi->pid);
- if ((map_fd = open (pathname, O_RDONLY)) < 0)
+ if ((map_fd = open_with_retry (pathname, O_RDONLY)) < 0)
proc_error (pi, "proc_iterate_over_mappings (open)", __LINE__);
/* Make sure it gets closed again. */
@@ -2903,7 +2938,7 @@ proc_iterate_over_mappings (int (*func)
{
sprintf (name, "/proc/%d/object/%s", pi->pid, map->pr_mapname);
/* Note: caller's responsibility to close this fd! */
- fd = open (name, O_RDONLY);
+ fd = open_with_retry (name, O_RDONLY);
/* Note: we don't test the above call for failure;
we just pass the FD on as given. Sometimes there is
no file, so the ioctl may return failure, but that's
@@ -2982,7 +3017,7 @@ proc_get_LDT_entry (procinfo *pi, int ke
/* Open the file descriptor for the LDT table. */
sprintf (pathname, "/proc/%d/ldt", pi->pid);
- if ((fd = open (pathname, O_RDONLY)) < 0)
+ if ((fd = open_with_retry (pathname, O_RDONLY)) < 0)
{
proc_warn (pi, "proc_get_LDT_entry (open)", __LINE__);
return NULL;
next reply other threads:[~2001-04-13 18:55 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-04-13 18:55 Kevin Buettner [this message]
2001-04-16 15:20 ` Michael Snyder
2001-04-16 18:30 ` Kevin Buettner
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=1010414015521.ZM21085@ocotillo.lan \
--to=kevinb@cygnus.com \
--cc=DKICK1@motorola.com \
--cc=gdb-patches@sources.redhat.com \
--cc=msnyder@cygnus.com \
/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