View | Details | Raw Unified | Return to bug 14382
Collapse All | Expand All

(-)a/gdb/linux-nat.c (-4 / +131 lines)
Lines 66-71 Link Here
66
#include "target-descriptions.h"
66
#include "target-descriptions.h"
67
#include "filestuff.h"
67
#include "filestuff.h"
68
#include "objfiles.h"
68
#include "objfiles.h"
69
#include <sys/signalfd.h>
70
#include "gdb_select.h"
69
71
70
#ifndef SPUFS_MAGIC
72
#ifndef SPUFS_MAGIC
71
#define SPUFS_MAGIC 0x23c9b64e
73
#define SPUFS_MAGIC 0x23c9b64e
Lines 219-224 struct simple_pid_list *stopped_pids; Link Here
219
   event loop.  */
221
   event loop.  */
220
static int linux_nat_event_pipe[2] = { -1, -1 };
222
static int linux_nat_event_pipe[2] = { -1, -1 };
221
223
224
/* The signalfd file descriptor.  */
225
static int linux_nat_sfd = -1;
226
222
/* True if we're currently in async mode.  */
227
/* True if we're currently in async mode.  */
223
#define linux_is_async_p() (linux_nat_event_pipe[0] != -1)
228
#define linux_is_async_p() (linux_nat_event_pipe[0] != -1)
224
229
Lines 705-710 static sigset_t suspend_mask; Link Here
705
/* Signals to block to make that sigsuspend work.  */
710
/* Signals to block to make that sigsuspend work.  */
706
static sigset_t blocked_mask;
711
static sigset_t blocked_mask;
707
712
713
#define USE_SIGNALFD 1
714
708
/* SIGCHLD action.  */
715
/* SIGCHLD action.  */
709
struct sigaction sigchld_action;
716
struct sigaction sigchld_action;
710
717
Lines 714-719 struct sigaction sigchld_action; Link Here
714
static void
721
static void
715
block_child_signals (sigset_t *prev_mask)
722
block_child_signals (sigset_t *prev_mask)
716
{
723
{
724
  if (USE_SIGNALFD)
725
    return;
726
717
  /* Make sure SIGCHLD is blocked.  */
727
  /* Make sure SIGCHLD is blocked.  */
718
  if (!sigismember (&blocked_mask, SIGCHLD))
728
  if (!sigismember (&blocked_mask, SIGCHLD))
719
    sigaddset (&blocked_mask, SIGCHLD);
729
    sigaddset (&blocked_mask, SIGCHLD);
Lines 727-732 block_child_signals (sigset_t *prev_mask) Link Here
727
static void
737
static void
728
restore_child_signals_mask (sigset_t *prev_mask)
738
restore_child_signals_mask (sigset_t *prev_mask)
729
{
739
{
740
  if (USE_SIGNALFD)
741
    return;
742
730
  sigprocmask (SIG_SETMASK, prev_mask, NULL);
743
  sigprocmask (SIG_SETMASK, prev_mask, NULL);
731
}
744
}
732
745
Lines 2208-2213 linux_handle_extended_wait (struct lwp_info *lp, int status, Link Here
2208
		  _("unknown ptrace event %d"), event);
2221
		  _("unknown ptrace event %d"), event);
2209
}
2222
}
2210
2223
2224
static void
2225
wait_for_sigchld (void)
2226
{
2227
  if (USE_SIGNALFD)
2228
    {
2229
      for (;;)
2230
	{
2231
	  fd_set rfds;
2232
	  int r;
2233
2234
	  FD_ZERO (&rfds);
2235
	  FD_SET (linux_nat_sfd, &rfds);
2236
2237
	  r = gdb_select (linux_nat_sfd + 1, &rfds, NULL, NULL, NULL);
2238
	  fprintf_unfiltered (gdb_stdlog, "gdb_select returned %d\n", r);
2239
2240
	  if (r != -1 /* && FD_ISSET (linux_nat_sfd, &rfds) */)
2241
	    {
2242
	      struct signalfd_siginfo fdsi;
2243
2244
	      r = read (linux_nat_sfd, &fdsi, sizeof (struct signalfd_siginfo));
2245
	      if (r == -1 && errno == EAGAIN)
2246
		{
2247
		  fprintf_unfiltered (gdb_stdlog, "read returned EAGAIN\n");
2248
		  // return; /* doesn't really help */
2249
		  continue;
2250
		}
2251
2252
	      if (r == -1 && errno == EINTR)
2253
		{
2254
		  fprintf_unfiltered (gdb_stdlog, "read returned EINTR\n");
2255
		  continue;
2256
		}
2257
2258
	      if (r != sizeof (struct signalfd_siginfo))
2259
		perror_with_name ("read");
2260
	      if (fdsi.ssi_signo != SIGCHLD)
2261
		perror_with_name ("read unexpected signal");
2262
2263
	      /* Got SIGCHLD.  */
2264
	      break;
2265
	    }
2266
	}
2267
    }
2268
  else
2269
    {
2270
      sigsuspend (&suspend_mask);
2271
    }
2272
}
2273
2211
/* Wait for LP to stop.  Returns the wait status, or 0 if the LWP has
2274
/* Wait for LP to stop.  Returns the wait status, or 0 if the LWP has
2212
   exited.  */
2275
   exited.  */
2213
2276
Lines 2283-2289 wait_lwp (struct lwp_info *lp) Link Here
2283
2346
2284
      if (debug_linux_nat)
2347
      if (debug_linux_nat)
2285
	fprintf_unfiltered (gdb_stdlog, "WL: about to sigsuspend\n");
2348
	fprintf_unfiltered (gdb_stdlog, "WL: about to sigsuspend\n");
2286
      sigsuspend (&suspend_mask);
2349
      wait_for_sigchld ();
2287
    }
2350
    }
2288
2351
2289
  restore_child_signals_mask (&prev_mask);
2352
  restore_child_signals_mask (&prev_mask);
Lines 3556-3562 linux_nat_wait_1 (struct target_ops *ops, Link Here
3556
      /* Block until we get an event reported with SIGCHLD.  */
3619
      /* Block until we get an event reported with SIGCHLD.  */
3557
      if (debug_linux_nat)
3620
      if (debug_linux_nat)
3558
	fprintf_unfiltered (gdb_stdlog, "LNW: about to sigsuspend\n");
3621
	fprintf_unfiltered (gdb_stdlog, "LNW: about to sigsuspend\n");
3559
      sigsuspend (&suspend_mask);
3622
      wait_for_sigchld ();
3560
    }
3623
    }
3561
3624
3562
  if (!target_is_async_p ())
3625
  if (!target_is_async_p ())
Lines 4674-4680 sigchld_handler (int signo) Link Here
4674
    ui_file_write_async_safe (gdb_stdlog,
4737
    ui_file_write_async_safe (gdb_stdlog,
4675
			      "sigchld\n", sizeof ("sigchld\n") - 1);
4738
			      "sigchld\n", sizeof ("sigchld\n") - 1);
4676
4739
4677
  if (signo == SIGCHLD
4740
  if (!USE_SIGNALFD
4741
      && signo == SIGCHLD
4678
      && linux_nat_event_pipe[0] != -1)
4742
      && linux_nat_event_pipe[0] != -1)
4679
    async_file_mark (); /* Let the event loop know that there are
4743
    async_file_mark (); /* Let the event loop know that there are
4680
			   events to handle.  */
4744
			   events to handle.  */
Lines 4690-4695 handle_target_event (int error, gdb_client_data client_data) Link Here
4690
  inferior_event_handler (INF_REG_EVENT, NULL);
4754
  inferior_event_handler (INF_REG_EVENT, NULL);
4691
}
4755
}
4692
4756
4757
/* Callback registered with the target events file descriptor.  */
4758
4759
static void
4760
handle_target_event_signalfd (int error, gdb_client_data client_data)
4761
{
4762
#if 1
4763
  for (;;)
4764
    {
4765
      struct signalfd_siginfo fdsi;
4766
      int s;
4767
4768
      s = read (linux_nat_sfd, &fdsi, sizeof (struct signalfd_siginfo));
4769
      if (s == -1 && errno == EAGAIN)
4770
	break;
4771
      else if (s == -1 && errno == EINTR)
4772
	continue;
4773
4774
      if (s != sizeof (struct signalfd_siginfo))
4775
	perror_with_name ("read");
4776
      if (fdsi.ssi_signo != SIGCHLD)
4777
	perror_with_name ("read unexpected signal");
4778
4779
      /* Got one SIGCHLD.  */
4780
    }
4781
#endif
4782
4783
  inferior_event_handler (INF_REG_EVENT, NULL);
4784
}
4785
4693
/* Create/destroy the target events pipe.  Returns previous state.  */
4786
/* Create/destroy the target events pipe.  Returns previous state.  */
4694
4787
4695
static int
4788
static int
Lines 4743-4752 linux_nat_async (struct target_ops *ops, int enable) Link Here
4743
	     to poll them.  */
4836
	     to poll them.  */
4744
	  async_file_mark ();
4837
	  async_file_mark ();
4745
	}
4838
	}
4839
4840
      add_file_handler (linux_nat_sfd,
4841
			handle_target_event_signalfd, NULL);
4746
    }
4842
    }
4747
  else
4843
  else
4748
    {
4844
    {
4749
      delete_file_handler (linux_nat_event_pipe[0]);
4845
      delete_file_handler (linux_nat_event_pipe[0]);
4846
      delete_file_handler (linux_nat_sfd);
4750
      linux_async_pipe (0);
4847
      linux_async_pipe (0);
4751
    }
4848
    }
4752
  return;
4849
  return;
Lines 5046-5051 Enables printf debugging output."), Link Here
5046
  /* Make it the default.  */
5143
  /* Make it the default.  */
5047
  sigaction (SIGCHLD, &sigchld_action, NULL);
5144
  sigaction (SIGCHLD, &sigchld_action, NULL);
5048
5145
5146
  if (USE_SIGNALFD)
5147
    {
5148
      sigset_t mask;
5149
      ssize_t s;
5150
5151
      sigemptyset (&mask);
5152
      sigaddset (&mask, SIGCHLD);
5153
5154
#if 0
5155
      /* Hmm, if we don't do this, then gdb hangs in wait_for_sigchld.
5156
	 That seems to mean that if a SIGCHLD signal handler is
5157
	 called, then the signalfd file ends up with nothing to read,
5158
	 and thus 'select' blocks forever.  Test with:
5159
5160
	 "gdb PROGRAM -ex "maint set target-async off" -ex "set debug lin-lwp 1"
5161
5162
	 Which renders this approach worthless to protect against a
5163
	 library GDB links against from stealing out SIGCHLD
5164
	 handler... :-/
5165
      */
5166
5167
      /* Make sure SIGCHLD is blocked.  */
5168
      if (!sigismember (&normal_mask, SIGCHLD))
5169
	sigaddset (&normal_mask, SIGCHLD);
5170
      sigprocmask (SIG_SETMASK, &normal_mask, NULL);
5171
#endif
5172
5173
      linux_nat_sfd = signalfd (-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
5174
      gdb_assert (linux_nat_sfd != -1);
5175
    }
5176
5049
  /* Make sure we don't block SIGCHLD during a sigsuspend.  */
5177
  /* Make sure we don't block SIGCHLD during a sigsuspend.  */
5050
  sigprocmask (SIG_SETMASK, NULL, &suspend_mask);
5178
  sigprocmask (SIG_SETMASK, NULL, &suspend_mask);
5051
  sigdelset (&suspend_mask, SIGCHLD);
5179
  sigdelset (&suspend_mask, SIGCHLD);
5052
- 

Return to bug 14382