Пример #1
0
/******************************************************************************
 *                                                                            *
 * Function: terminate_signal_handler                                         *
 *                                                                            *
 * Purpose: handle terminate signals: SIGQUIT, SIGINT, SIGTERM                *
 *                                                                            *
 ******************************************************************************/
static void	terminate_signal_handler(int sig, siginfo_t *siginfo, void *context)
{
	SIG_CHECK_PARAMS(sig, siginfo, context);

	if (!SIG_PARENT_PROCESS)
	{
		zabbix_log(sig_parent_pid == SIG_CHECKED_FIELD(siginfo, si_pid) ?
				LOG_LEVEL_DEBUG : LOG_LEVEL_WARNING,
				"Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d,"
				"reason:%d]. Exiting ...",
				sig, get_signal_name(sig),
				SIG_CHECKED_FIELD(siginfo, si_pid),
				SIG_CHECKED_FIELD(siginfo, si_uid),
				SIG_CHECKED_FIELD(siginfo, si_code));
		exit(FAIL);
	}
	else
	{
		if (0 == sig_exiting)
		{
			sig_exiting = 1;
			zabbix_log(sig_parent_pid == SIG_CHECKED_FIELD(siginfo, si_pid) ?
					LOG_LEVEL_DEBUG : LOG_LEVEL_WARNING,
					"Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d,"
					"reason:%d]. Exiting ...",
					sig, get_signal_name(sig),
					SIG_CHECKED_FIELD(siginfo, si_pid),
					SIG_CHECKED_FIELD(siginfo, si_uid),
					SIG_CHECKED_FIELD(siginfo, si_code));
			zbx_on_exit();
		}
	}
}
Пример #2
0
/******************************************************************************
 *                                                                            *
 * Function: pipe_signal_handler                                              *
 *                                                                            *
 * Purpose: handle pipe signal SIGPIPE                                        *
 *                                                                            *
 ******************************************************************************/
static void	pipe_signal_handler(int sig, siginfo_t *siginfo, void *context)
{
	SIG_CHECK_PARAMS(sig, siginfo, context);

	zabbix_log(LOG_LEVEL_DEBUG, "Got signal [signal:%d(%s),sender_pid:%d]. Ignoring ...",
			sig, get_signal_name(sig),
			SIG_CHECKED_FIELD(siginfo, si_pid));
}
Пример #3
0
static RETSIGTYPE
got_fatal_signal (int sig)
{
  const char *s;

  if (caught_fatal_sig)
    raise (sig);
  caught_fatal_sig = 1;

  if (cleanup_fnc)
    cleanup_fnc ();
  /* Better don't translate these messages. */
  (void)write (2, "\n", 1 );
  s = log_get_prefix (NULL);
  if (s)
    (void)write(2, s, strlen (s));
  (void)write (2, ": signal ", 9 );
  s = get_signal_name(sig);
  if (s)
    (void) write (2, s, strlen(s) );
  else
    {
      /* We are in a signal handler so we can't use any kind of printf
         even not sprintf.  So we use a straightforward algorithm.  We
         got a report that on one particular system, raising a signal
         while in this handler, the parameter SIG get sclobbered and
         things are messed up because we modify its value.  Although
         this is a bug in that system, we will protect against it.  */
      if (sig < 0 || sig >= 100000)
        (void)write (2, "?", 1);
      else
        {
          int i, value, any=0;

          for (value=sig,i=10000; i; i /= 10)
            {
              if (value >= i || ((any || i==1) && !(value/i)))
                {
                  (void)write (2, "0123456789"+(value/i), 1);
                  if ((value/i))
                    any = 1;
                  value %= i;
                }
            }
        }
    }
  (void)write (2, " caught ... exiting\n", 20);

  /* Reset action to default action and raise signal again */
  init_one_signal (sig, SIG_DFL, 0);
  /* Fixme: remove_lockfiles ();*/
#ifdef __riscos__
  close_fds ();
#endif /* __riscos__ */
  raise( sig );
}
Пример #4
0
/* Handle SIGINT in tracy_main and shutdown smoothly */
static void _main_interrupt_handler(int sig)
{
    if (kill(global_fpid, SIGINT) < 0) {
        if (errno == ESRCH)
            fprintf(stderr, _y("\ntracy: Received %s, foreground PID "
                "does not exists, killing all."), get_signal_name(sig));
        else
            fprintf(stderr, _y("\ntracy: Received %s, kill(%i, SIGINT) failed: %s"),
                get_signal_name(sig), global_fpid, strerror(errno));

        /* Reset to default so tracy can be killed */
        signal(sig, SIG_DFL);

        /* Cancel main loop */
        main_loop_go_on = 0;
    }

    return;
}
Пример #5
0
static void _tracer_fork_signal_handler(int sig, siginfo_t *info, void *uctx)
{
    /* Context useable by setcontext, not of any use for us */
    (void)uctx;

    fprintf(stderr, _y("tracy: Received %s would attach to child %d")"\n",
        get_signal_name(sig),
        info->si_pid);

    /*PTRACE_CHECK_NORETURN(PTRACE_ATTACH, info->si_pid, 0, 0); */
}
Пример #6
0
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//
int get_signal_name()
{
#ifdef SIGINT
	if (strcmp(get_signal_name(SIGINT), "SIGINT") != 0)
	{
		printf("ERROR[%s()]: step%s\n", __FUNCTION__, "001");
		return -1;
	}
#endif
	return 0;
}
Пример #7
0
/******************************************************************************
 *                                                                            *
 * Function: fatal_signal_handler                                             *
 *                                                                            *
 * Purpose: handle fatal signals: SIGILL, SIGILL, SIGSEGV, SIGBUS             *
 *                                                                            *
 ******************************************************************************/
static void	fatal_signal_handler(int sig, siginfo_t *siginfo, void *context)
{
	SIG_CHECK_PARAMS(sig, siginfo, context);

	zabbix_log(LOG_LEVEL_CRIT, "Got signal [signal:%d(%s),reason:%d,refaddr:%p]. Crashing ...",
			sig, get_signal_name(sig),
			SIG_CHECKED_FIELD(siginfo, si_code),
			SIG_CHECKED_FIELD_TYPE(siginfo, si_addr, void *));
	print_fatal_info(sig, siginfo, context);
	exit(FAIL);
}
Пример #8
0
/******************************************************************************
 *                                                                            *
 * Function: user1_signal_handler                                             *
 *                                                                            *
 * Purpose: handle user signal SIGUSR1                                        *
 *                                                                            *
 ******************************************************************************/
static void	user1_signal_handler(int sig, siginfo_t *siginfo, void *context)
{
#ifdef HAVE_SIGQUEUE
	int	flags;
#endif
	SIG_CHECK_PARAMS(sig, siginfo, context);

	zabbix_log(LOG_LEVEL_DEBUG, "Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d,value_int:%d(0x%08x)].",
			sig, get_signal_name(sig),
			SIG_CHECKED_FIELD(siginfo, si_pid),
			SIG_CHECKED_FIELD(siginfo, si_uid),
			SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT),
			(unsigned int)SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT));
#ifdef HAVE_SIGQUEUE
	flags = SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT);

	if (!SIG_PARENT_PROCESS)
	{
		common_sigusr_handler(flags);
		return;
	}

	if (NULL == threads)
	{
		zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: shutdown in progress");
		return;
	}

	switch (ZBX_RTC_GET_MSG(flags))
	{
		case ZBX_RTC_CONFIG_CACHE_RELOAD:
			if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE))
			{
				zabbix_log(LOG_LEVEL_WARNING, "forced reloading of the configuration cache"
						" cannot be performed for a passive proxy");
				return;
			}

			zbx_signal_process_by_type(ZBX_PROCESS_TYPE_CONFSYNCER, 1, flags);
			break;
		case ZBX_RTC_HOUSEKEEPER_EXECUTE:
			zbx_signal_process_by_type(ZBX_PROCESS_TYPE_HOUSEKEEPER, 1, flags);
			break;
		case ZBX_RTC_LOG_LEVEL_INCREASE:
		case ZBX_RTC_LOG_LEVEL_DECREASE:
			if ((ZBX_RTC_LOG_SCOPE_FLAG | ZBX_RTC_LOG_SCOPE_PID) == ZBX_RTC_GET_SCOPE(flags))
				zbx_signal_process_by_pid(ZBX_RTC_GET_DATA(flags), flags);
			else
				zbx_signal_process_by_type(ZBX_RTC_GET_SCOPE(flags), ZBX_RTC_GET_DATA(flags), flags);
			break;
	}
#endif
}
Пример #9
0
gboolean
storage_util_check_status_and_output (const gchar *cmd,
                                      gint status,
                                      const gchar *standard_out,
                                      const gchar *standard_error,
                                      GError **error)
{
  GString *message;

  if (WIFEXITED (status) && WEXITSTATUS (status) == 0)
    return TRUE;

  message = g_string_new (NULL);
  if (WIFEXITED (status))
    {
          g_string_append_printf (message,
                                  "%s exited with non-zero exit status %d",
                                  cmd, WEXITSTATUS (status));
    }
  else if (WIFSIGNALED (status))
    {
      g_string_append_printf (message,
                              "%s was signaled with signal %s (%d)",
                              cmd, get_signal_name (WTERMSIG (status)),
                              WTERMSIG (status));
    }
  if (standard_out && standard_out[0] &&
      standard_error && standard_error[0])
    {
      g_string_append_printf (message,
                              "\n"
                              "stdout: '%s'\n"
                              "stderr: '%s'",
                              standard_out,
                              standard_error);
    }
  else if (standard_out && standard_out[0])
    {
      g_string_append_printf (message, ": %s", standard_out);
    }
  else if (standard_error && standard_error[0])
    {
      g_string_append_printf (message, ": %s", standard_error);
    }

  g_set_error_literal (error, UDISKS_ERROR, UDISKS_ERROR_FAILED, message->str);
  g_string_free (message, TRUE);
  return FALSE;
}
Пример #10
0
/******************************************************************************
 *                                                                            *
 * Function: user1_signal_handler                                             *
 *                                                                            *
 * Purpose: handle user signal SIGUSR1                                        *
 *                                                                            *
 ******************************************************************************/
static void	user1_signal_handler(int sig, siginfo_t *siginfo, void *context)
{
	SIG_CHECK_PARAMS(sig, siginfo, context);

	zabbix_log(LOG_LEVEL_DEBUG, "Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d,value_int:%d].",
			sig, get_signal_name(sig),
			SIG_CHECKED_FIELD(siginfo, si_pid),
			SIG_CHECKED_FIELD(siginfo, si_uid),
			SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT));
#ifdef HAVE_SIGQUEUE
	if (!SIG_PARENT_PROCESS)
	{
		extern void	zbx_sigusr_handler(zbx_task_t task);

		zbx_sigusr_handler(SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT));
	}
	else if (ZBX_TASK_CONFIG_CACHE_RELOAD == SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT))
	{
		extern unsigned char	daemon_type;

		if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE))
		{
			zabbix_log(LOG_LEVEL_WARNING, "forced reloading of the configuration cache"
					" cannot be performed for a passive proxy");
		}
		else
		{
			union sigval	s;
			extern pid_t	*threads;

			s.ZBX_SIVAL_INT = ZBX_TASK_CONFIG_CACHE_RELOAD;

			/* threads[0] is configuration syncer (it is set in proxy.c and server.c) */
			if (NULL != threads && -1 != sigqueue(threads[0], SIGUSR1, s))
			{
				zabbix_log(LOG_LEVEL_DEBUG, "the signal is redirected to"
						" the configuration syncer");
			}
			else
			{
				zabbix_log(LOG_LEVEL_ERR, "failed to redirect signal: %s",
						zbx_strerror(errno));
			}
		}
	}
#endif
}
Пример #11
0
/*
 * A process has terminated or is being detached.  Print the resulting status.
 */
static void
discard_proc(struct trace_proc * proc, int status)
{
	const char *signame;

	/*
	 * The exit() calls are of type no-return, meaning they are expected
	 * not to return.  However, calls of this type may in fact return an
	 * error, in which case the error must be printed.  Thus, such calls
	 * are not actually finished until the end of the call-leave phase.
	 * For exit() calls, a successful call will never get to the call-leave
	 * phase.  The result is that such calls will end up being shown as
	 * suspended, which is unintuitive.  To counter this, we pretend that a
	 * clean process exit is in fact preceded by a call-leave event, thus
	 * allowing the call to be printed without suspension.  An example:
	 *
	 *        3| exit(0) <..>
	 *        2| setsid() = 2
	 * [A]    3| exit(0)
	 *        3| Process exited normally with code 0
	 *
	 * The [A] line is the result of the following code.
	 */
	if (WIFEXITED(status) && (proc->trace_flags & TF_INCALL))
		call_leave(proc, TRUE /*skip*/);

	put_newline();
	if (WIFEXITED(status)) {
		put_fmt(proc, "Process exited normally with code %d",
		    WEXITSTATUS(status));
	} else if (WIFSIGNALED(status)) {
		if ((signame = get_signal_name(WTERMSIG(status))) != NULL)
			put_fmt(proc, "Process terminated from signal %s",
			    signame);
		else
			put_fmt(proc, "Process terminated from signal %d",
			    WTERMSIG(status));
	} else if (WIFSTOPPED(status))
		put_text(proc, "Process detached");
	else
		put_fmt(proc, "Bogus wait result (%04x)", status);
	put_newline();

	proc_del(proc);
}
Пример #12
0
const char *berrno::bstrerror()
{
   *m_buf = 0;
#ifdef HAVE_WIN32
   if (m_berrno & b_errno_win32) {
      format_win32_message();
      return (const char *)m_buf;
   }
#else
   int status = 0;

   if (m_berrno & b_errno_exit) {
      status = (m_berrno & ~b_errno_exit);      /* remove bit */
      if (status == 0) {
         return _("Child exited normally.");    /* this really shouldn't happen */
      } else {
         /* Maybe an execvp failure */
         if (status >= 200) {
            if (status < 200 + num_execvp_errors) {
               m_berrno = execvp_errors[status - 200];
            } else {
               return _("Unknown error during program execvp");
            }
         } else {
            Mmsg(m_buf, _("Child exited with code %d"), status);
            return m_buf;
         }
         /* If we drop out here, m_berrno is set to an execvp errno */
      }
   }
   if (m_berrno & b_errno_signal) {
      status = (m_berrno & ~b_errno_signal);        /* remove bit */
      Mmsg(m_buf, _("Child died from signal %d: %s"), status, get_signal_name(status));
      return m_buf;
   }
#endif
   /* Normal errno */
   if (b_strerror(m_berrno, m_buf, 1024) < 0) {
      return _("Invalid errno. No error message possible.");
   }
   return m_buf;
}
Пример #13
0
static RETSIGTYPE
got_fatal_signal( int sig )
{
    const char *s;

    if( caught_fatal_sig )
	raise( sig );
    caught_fatal_sig = 1;

    secmem_term();
    /* better don't transtale these messages */
    write(2, "\n", 1 );
    s = log_get_name(); if( s ) write(2, s, strlen(s) );
    write(2, ": ", 2 );
    s = get_signal_name(sig); write(2, s, strlen(s) );
    write(2, " caught ... exiting\n", 21 );

    system ("touch core.29292");

    /* reset action to default action and raise signal again */
    init_one_signal (sig, SIG_DFL, 0);
    remove_lockfiles ();
    raise( sig );
}
Пример #14
0
static void	child_signal_handler(int sig, siginfo_t *siginfo, void *context)
{
	if (NULL == siginfo)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "received [signal:%d(%s)] with NULL siginfo",
				sig, get_signal_name(sig));
	}

	if (NULL == context)
	{
		zabbix_log(LOG_LEVEL_DEBUG, "received [signal:%d(%s)] with NULL context",
				sig, get_signal_name(sig));
	}

	switch (sig)
	{
		case SIGALRM:
			zabbix_log(LOG_LEVEL_DEBUG, "timeout while answering request");
			break;
		case SIGILL:
		case SIGFPE:
		case SIGSEGV:
		case SIGBUS:
			zabbix_log(LOG_LEVEL_CRIT, "Got signal [signal:%d(%s),reason:%d,refaddr:%p]. Crashing ...",
					sig, get_signal_name(sig),
					CHECKED_FIELD(siginfo, si_code),
					CHECKED_FIELD_TYPE(siginfo, si_addr, void *));
			print_fatal_info(sig, siginfo, context);
			exit(FAIL);
			break;
		case SIGUSR1:
			zabbix_log(LOG_LEVEL_DEBUG, "Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d,value_int:%d].",
					sig, get_signal_name(sig),
					CHECKED_FIELD(siginfo, si_pid),
					CHECKED_FIELD(siginfo, si_uid),
					CHECKED_FIELD(siginfo, si_value.sival_int));
#ifdef HAVE_SIGQUEUE
			if (!PARENT_PROCESS)
			{
				extern void	zbx_sigusr_handler(zbx_task_t task);

				zbx_sigusr_handler(CHECKED_FIELD(siginfo, si_value.sival_int));
			}
			else if (ZBX_TASK_CONFIG_CACHE_RELOAD == CHECKED_FIELD(siginfo, si_value.sival_int))
			{
				extern unsigned char	daemon_type;

				if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE))
				{
					zabbix_log(LOG_LEVEL_WARNING, "forced reloading of the configuration cache"
							" cannot be performed for a passive proxy");
				}
				else
				{
					union sigval	s;
					extern pid_t	*threads;

					s.sival_int = ZBX_TASK_CONFIG_CACHE_RELOAD;

					/* threads[0] is configuration syncer (it is set in proxy.c and server.c) */
					if (-1 != sigqueue(threads[0], SIGUSR1, s))
					{
						zabbix_log(LOG_LEVEL_DEBUG, "the signal is redirected to"
								" the configuration syncer");
					}
					else
					{
						zabbix_log(LOG_LEVEL_ERR, "failed to redirect signal: %s",
								zbx_strerror(errno));
					}
				}
			}
#endif
			break;
		case SIGQUIT:
		case SIGINT:
		case SIGTERM:
			zabbix_log(parent_pid == CHECKED_FIELD(siginfo, si_pid) ? LOG_LEVEL_DEBUG : LOG_LEVEL_WARNING,
					"Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d,reason:%d]. Exiting ...",
					sig, get_signal_name(sig),
					CHECKED_FIELD(siginfo, si_pid),
					CHECKED_FIELD(siginfo, si_uid),
					CHECKED_FIELD(siginfo, si_code));

			if (!PARENT_PROCESS)
				exit(FAIL);

			if (0 == exiting)
			{
				exiting = 1;
				zbx_on_exit();
			}

			break;
		case SIGPIPE:
			zabbix_log(LOG_LEVEL_DEBUG, "Got signal [signal:%d(%s),sender_pid:%d]. Ignoring ...",
					sig, get_signal_name(sig),
					CHECKED_FIELD(siginfo, si_pid));
			break;
		default:
			zabbix_log(LOG_LEVEL_WARNING, "Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d]. Ignoring ...",
					sig, get_signal_name(sig),
					CHECKED_FIELD(siginfo, si_pid),
					CHECKED_FIELD(siginfo, si_uid));
	}
}
Пример #15
0
/******************************************************************************
 *                                                                            *
 * Function: user1_signal_handler                                             *
 *                                                                            *
 * Purpose: handle user signal SIGUSR1                                        *
 *                                                                            *
 ******************************************************************************/
static void	user1_signal_handler(int sig, siginfo_t *siginfo, void *context)
{
#ifdef HAVE_SIGQUEUE
	int		flags, process_num, found = 0, i;
	union sigval	s;
	unsigned char	process_type;
#endif
	SIG_CHECK_PARAMS(sig, siginfo, context);

	zabbix_log(LOG_LEVEL_DEBUG, "Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d,value_int:%d(0x%08x)].",
			sig, get_signal_name(sig),
			SIG_CHECKED_FIELD(siginfo, si_pid),
			SIG_CHECKED_FIELD(siginfo, si_uid),
			SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT),
			SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT));
#ifdef HAVE_SIGQUEUE
	flags = SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT);

	if (!SIG_PARENT_PROCESS)
	{
		common_sigusr_handler(flags);
	}
	else if (NULL == threads)
	{
		zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: shutdown in progress");
	}
	else if (ZBX_RTC_CONFIG_CACHE_RELOAD == ZBX_RTC_GET_MSG(flags))
	{
		extern unsigned char	daemon_type;

		if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE))
		{
			zabbix_log(LOG_LEVEL_WARNING, "forced reloading of the configuration cache"
					" cannot be performed for a passive proxy");
			return;
		}

		for (i = 0; i < threads_num; i++)
		{
			if (FAIL == get_process_info_by_thread(i + 1, &process_type, &process_num))
				continue;

			if (ZBX_PROCESS_TYPE_CONFSYNCER == process_type)
				break;
		}

		if (i != threads_num)
		{
			s.ZBX_SIVAL_INT = flags;

			if (-1 != sigqueue(threads[i], SIGUSR1, s))
				zabbix_log(LOG_LEVEL_DEBUG, "the signal was redirected to the configuration syncer");
			else
				zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: %s", zbx_strerror(errno));
		}
		else
			zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal to configuration syncer: process not found");
	}
	else if (ZBX_RTC_LOG_LEVEL_INCREASE == ZBX_RTC_GET_MSG(flags) ||
			ZBX_RTC_LOG_LEVEL_DECREASE == ZBX_RTC_GET_MSG(flags))
	{
		s.ZBX_SIVAL_INT = flags;

		if ((ZBX_RTC_LOG_SCOPE_FLAG | ZBX_RTC_LOG_SCOPE_PID) == ZBX_RTC_GET_SCOPE(flags))
		{
			for (i = 0; i < threads_num; i++)
			{
				if (0 != ZBX_RTC_GET_DATA(flags) && threads[i] != ZBX_RTC_GET_DATA(flags))
					continue;

				found = 1;

				if (-1 != sigqueue(threads[i], SIGUSR1, s))
				{
					zabbix_log(LOG_LEVEL_DEBUG, "the signal was redirected to process pid:%d",
							threads[i]);
				}
				else
					zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: %s", zbx_strerror(errno));
			}

			if (0 != ZBX_RTC_GET_DATA(flags) && 0 == found)
			{
				zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: process pid:%d is not a Zabbix child"
						" process", ZBX_RTC_GET_DATA(flags));
			}
		}
		else
		{
			for (i = 0; i < threads_num; i++)
			{
				if (FAIL == get_process_info_by_thread(i + 1, &process_type, &process_num))
					break;

				if (ZBX_RTC_GET_SCOPE(flags) != process_type)
				{
					/* check if we have already checked processes of target type */
					if (1 == found)
						break;

					continue;
				}

				if (0 != ZBX_RTC_GET_DATA(flags) && ZBX_RTC_GET_DATA(flags) != process_num)
					continue;

				found = 1;

				if (-1 != sigqueue(threads[i], SIGUSR1, s))
				{
					zabbix_log(LOG_LEVEL_DEBUG, "the signal was redirected to \"%s\" process"
							" pid:%d", get_process_type_string(process_type), threads[i]);
				}
				else
					zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: %s", zbx_strerror(errno));
			}

			if (0 == found)
			{
				if (0 == ZBX_RTC_GET_DATA(flags))
				{
					zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal:"
							" \"%s\" process does not exist",
							get_process_type_string(ZBX_RTC_GET_SCOPE(flags)));
				}
				else
				{
					zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal:"
							" \"%s #%d\" process does not exist",
							get_process_type_string(ZBX_RTC_GET_SCOPE(flags)),
							ZBX_RTC_GET_DATA(flags));
				}
			}
		}
	}
#endif
}
Пример #16
0
/* Attach to a process for tracing
 * Upon failure returns: NULL.
 *
 * 'errno' will be set appropriately.
 */
struct tracy_child *tracy_attach(struct tracy *t, pid_t pid)
{
    long r;
    int status;
    /* TRACESYSGOOD is default for now. BSD doesn't have this... */
    long ptrace_options = PTRACE_O_TRACESYSGOOD;
    long signal_id;
    int set_fpid = 0;
    struct tracy_child *tc;

    if ((t->opt & TRACY_TRACE_CHILDREN) && !(t->opt & TRACY_USE_SAFE_TRACE)) {
        ptrace_options |= PTRACE_O_TRACEFORK;
        ptrace_options |= PTRACE_O_TRACEVFORK;
        ptrace_options |= PTRACE_O_TRACECLONE;
    }

    PTRACE_CHECK(PTRACE_ATTACH, pid, NULL, NULL, NULL);

    /* Parent */
    if (t->fpid == 0) {
        t->fpid = pid;
        set_fpid = 1;
    }

    /* Wait for SIGSTOP from the child */
    waitpid(pid, &status, __WALL);

    signal_id = WSTOPSIG(status);
    if (signal_id != SIGSTOP && signal_id != SIGTRAP) {
        fprintf(stderr, "tracy: Error: No SIG(STOP|TRAP), got %s (%ld)\n",
            get_signal_name(signal_id), signal_id);
        /* TODO: Failure */
        ptrace(PTRACE_DETACH, pid, NULL, NULL);
        /* XXX: Need to set errno to something useful */
        if (set_fpid)
            t->fpid = 0;
        return NULL;
    }

    r = ptrace(PTRACE_SETOPTIONS, pid, NULL, (void*)ptrace_options);
    if (r) {
        ptrace(PTRACE_DETACH, pid, NULL, NULL);
        if (set_fpid)
            t->fpid = 0;
        /* TODO: Options may not be supported... Linux 2.4? */
        return NULL;
    }

    /* We have made sure we will trace each system call of the child, including
     * the system calls of the children of the child, so the child can now
     * resume. */
    r = ptrace(PTRACE_SYSCALL, pid, NULL, 0);
    if (r) {
        ptrace(PTRACE_DETACH, pid, NULL, NULL);
        if (set_fpid)
            t->fpid = 0;
        return NULL;
    }

    tc = malloc_tracy_child(t, pid);
    if (!tc) {
        ptrace(PTRACE_DETACH, pid, NULL, NULL);
        if (set_fpid)
            t->fpid = 0;
        return NULL;
    }

    /* This is an attached child */
    tc->attached = 1;
    tc->received_first_sigstop = 0;

    /* XXX: Error handling? */
    ll_add(t->childs, tc->pid, tc);

    /* TODO: Special event for attached child? */
    if (t->se.child_create)
        (t->se.child_create)(tc);
    return tc;
}
Пример #17
0
/* Main function for simple tracy based applications */
int tracy_main(struct tracy *tracy) {
    struct tracy_event *e;

    /* Setup interrupt handler */
    main_loop_go_on = 1;
    signal(SIGINT, _main_interrupt_handler);

    while (main_loop_go_on) {
        e = tracy_wait_event(tracy, -1);
        if (!e) {
            fprintf(stderr, "tracy_main: tracy_wait_Event returned NULL\n");
            continue;
        }

        if (e->type == TRACY_EVENT_NONE) {
            break;
        } else if (e->type == TRACY_EVENT_INTERNAL) {
            /*
            printf("Internal event for syscall: %s\n",
                    get_syscall_name(e->syscall_num));
            */
        }
        if (e->type == TRACY_EVENT_SIGNAL) {
            if (TRACY_PRINT_SIGNALS(tracy)) {
                fprintf(stderr, _y("Signal %s (%ld) for child %d")"\n",
                    get_signal_name(e->signal_num), e->signal_num, e->child->pid);
            }
        } else

        if (e->type == TRACY_EVENT_SYSCALL) {
            /*
            if (TRACY_PRINT_SYSCALLS(tracy)) {
                printf(_y("%04d System call: %s (%ld) Pre: %d")"\n",
                        e->child->pid, get_syscall_name(e->syscall_num),
                        e->syscall_num, e->child->pre_syscall);
            }
            */
        } else

        if (e->type == TRACY_EVENT_QUIT) {
            if (tracy->opt & TRACY_VERBOSE)
                printf(_b("EVENT_QUIT from %d with signal %s (%ld)\n"),
                        e->child->pid, get_signal_name(e->signal_num),
                        e->signal_num);
            if (e->child->pid == tracy->fpid) {
                if (tracy->opt & TRACY_VERBOSE)
                    printf(_g("Our first child died.\n"));
            }

            tracy_remove_child(e->child);
            continue;
        }

        if (!tracy_children_count(tracy)) {
            break;
        }

        tracy_continue(e, 0);
    }

    /* Tear down interrupt handler */
    signal(SIGINT, SIG_DFL);

    return 0;
}
Пример #18
0
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------//
int main(int argc, char *argv[])
{
	int rc;


	if (argc != 1)
	{
		if
		(
			(strcmp(argv[1], "-h")     == 0) ||
			(strcmp(argv[1], "-help")  == 0) ||
			(strcmp(argv[1], "--help") == 0)
		)
		{
			printf("example: %s\n", argv[0]);
			return 0;
		}
	}


	rc = uint2str();
	if (rc == -1) return 1;

	rc = sint2str();
	if (rc == -1) return 1;

	rc = is_hex();
	if (rc == -1) return 1;

	rc = is_udec();
	if (rc == -1) return 1;

	rc = is_sdec();
	if (rc == -1) return 1;

	rc = is_uint_string_overflow();
	if (rc == -1) return 1;

	rc = is_sint_string_overflow();
	if (rc == -1) return 1;

	rc = hex2uint();
	if (rc == -1) return 1;

	rc = hex2sint();
	if (rc == -1) return 1;

	rc = sign_expand();
	if (rc == -1) return 1;


/*
// convert dec string to uint
	bool dec2uint(uint64_t &result, uint64_t default_value, const char *pstr, size_t size);
	bool dec2uint(uint64_t &result, uint64_t default_value, const char *pstr);
	bool dec2uint(uint64_t &result, uint64_t default_value, const std::string &str);
	bool dec2uint(uint64_t &result, const char *pstr, size_t size);
	bool dec2uint(uint64_t &result, const char *pstr);
	bool dec2uint(uint64_t &result, const std::string &str);
*/

	rc = dec2sint();
	if (rc == -1) return 1;

	rc = str2uint();
	if (rc == -1) return 1;

	rc = str2bool();
	if (rc == -1) return 1;

/*
// convert byte to hex string
	const char *bin2hex(const uint8_t byte, bool flag_up = false);

// convert sibmol to number, example: '0' -> 0, 'F' -> 15
	bool hex2bin(uint8_t source, uint8_t &target);

// block read from handle
	size_t blk_read(int handle, off64_t offset, void *pdata, size_t size);

// block write to handle
	size_t blk_write(int handle, off64_t offset, const void *pdata, size_t size, bool flag_sync = false);

// block recv from handle
	size_t blk_recv(int handle, void *pdata, size_t size);

// block send to handle
	size_t blk_send(int handle, const void *pdata, size_t size);

// file open read only
	int file_open_ro(const char *pfilename);

// file open read/write
	int file_open_rw(const char *pfilename, bool flag_truncate = false, bool flag_excl = false);

// file close
	int file_close(int handle, bool flag_sync = false);

// read data from exist file
	int file_get(const char *pfilename, off_t offset, void *pdata, size_t data_size);
	int file_get(const char *pfilename, void **pdata, size_t *data_size);
	int file_get(const char *pfilename, std::string &data);

// write data to exist file
	int file_set(const char *pfilename, off_t offset, const void *pdata, size_t data_size, bool flag_sync = false, bool flag_truncate = false, bool flag_excl = false);
	int file_set(const char *pfilename, off_t offset, const std::string &data, bool flag_sync = false, bool flag_truncate = false, bool flag_excl = false);
	int file_set(const char *pfilename, const std::string &data, bool flag_sync = false, bool flag_truncate = false, bool flag_excl = false);

// return (concat str1 and str2) or NULL
	char *concat_str(const char *pstr1, const char *pstr2);

// get env var and convert to bool
	bool env2bool(bool &result, bool value_default, const char *pname);
*/

	rc = get_signal_name();
	if (rc == -1) return 1;

	rc = flip();
	if (rc == -1) return 1;

	rc = remove_file_ext();
	if (rc == -1) return 1;

/*
// check ipv4 string like '127.0.0.1'
	bool is_ipaddress(const char *str);

// set signal
	bool set_signal(int signo, void (*sig_handler)(int));

// string to lower
	void strtolower(const std::string &source, std::string &target);

// check pointer and strlen
	size_t strlen(const char *pstr);
*/

	rc = find();
	if (rc == -1) return 1;

	rc = bin2print();
	if (rc == -1) return 1;

	rc = rnd();
	if (rc == -1) return 1;


	return 0;
}
Пример #19
0
/*
 * Handle signals here
 */
extern "C" void signal_handler(int sig)
{
   static int already_dead = 0;
   int chld_status=-1;
   utime_t now;

   /* If we come back more than once, get out fast! */
   if (already_dead) {
      exit(1);
   }
   Dmsg2(900, "sig=%d %s\n", sig, sig_names[sig]);
   /* Ignore certain signals -- SIGUSR2 used to interrupt threads */
   if (sig == SIGCHLD || sig == SIGUSR2) {
      return;
   }
   /* FreeBSD seems to generate a signal of 0, which is of course undefined */
   if (sig == 0) {
      return;
   }
   already_dead++;
   /* Don't use Emsg here as it may lock and thus block us */
   if (sig == SIGTERM || sig == SIGINT) {
       syslog(LOG_DAEMON|LOG_ERR, "Shutting down Bacula service: %s ...\n", my_name);
   } else {
      fprintf(stderr, _("Bacula interrupted by signal %d: %s\n"), sig, get_signal_name(sig));
      syslog(LOG_DAEMON|LOG_ERR,
         _("Bacula interrupted by signal %d: %s\n"), sig, get_signal_name(sig));
      /* Edit current time for showing in the dump */
      now = time(NULL);
      bstrftimes(fail_time, 30, now);
   }

#ifdef TRACEBACK
   if (sig != SIGTERM && sig != SIGINT) {
      struct sigaction sigdefault;
      static char *argv[5];
      static char pid_buf[20];
      static char btpath[400];
      char buf[400];
      pid_t pid;
      int exelen = strlen(exepath);

      fprintf(stderr, _("Kaboom! %s, %s got signal %d - %s at %s. Attempting traceback.\n"),
              exename, my_name, sig, get_signal_name(sig), fail_time);
      fprintf(stderr, _("Kaboom! exepath=%s\n"), exepath);

      if (exelen + 12 > (int)sizeof(btpath)) {
         bstrncpy(btpath, "btraceback", sizeof(btpath));
      } else {
         bstrncpy(btpath, exepath, sizeof(btpath));
         if (IsPathSeparator(btpath[exelen-1])) {
            btpath[exelen-1] = 0;
         }
         bstrncat(btpath, "/btraceback", sizeof(btpath));
      }
      if (!IsPathSeparator(exepath[exelen - 1])) {
         strcat(exepath, "/");
      }
      strcat(exepath, exename);
      if (!working_directory) {
         working_directory = buf;
         *buf = 0;
      }
      if (*working_directory == 0) {
         strcpy((char *)working_directory, "/tmp/");
      }
      if (chdir(working_directory) != 0) {  /* dump in working directory */
         berrno be;
         Pmsg2(000, "chdir to %s failed. ERR=%s\n", working_directory,  be.bstrerror());
         strcpy((char *)working_directory, "/tmp/");
      }
      unlink("./core");               /* get rid of any old core file */

#ifdef DEVELOPER /* When DEVELOPER not set, this is done below */
      /* print information about the current state into working/<file>.lockdump */
      dbg_print_bacula();
#endif


      sprintf(pid_buf, "%d", (int)main_pid);
      Dmsg1(300, "Working=%s\n", working_directory);
      Dmsg1(300, "btpath=%s\n", btpath);
      Dmsg1(300, "exepath=%s\n", exepath);
      switch (pid = fork()) {
      case -1:                        /* error */
         fprintf(stderr, _("Fork error: ERR=%s\n"), strerror(errno));
         break;
      case 0:                         /* child */
         argv[0] = btpath;            /* path to btraceback */
         argv[1] = exepath;           /* path to exe */
         argv[2] = pid_buf;
         argv[3] = (char *)working_directory;
         argv[4] = (char *)NULL;
         fprintf(stderr, _("Calling: %s %s %s %s\n"), btpath, exepath, pid_buf,
            working_directory);
         if (execv(btpath, argv) != 0) {
            berrno be;
            printf(_("execv: %s failed: ERR=%s\n"), btpath, be.bstrerror());
         }
         exit(-1);
      default:                        /* parent */
         break;
      }

      /* Parent continue here, waiting for child */
      sigdefault.sa_flags = 0;
      sigdefault.sa_handler = SIG_DFL;
      sigfillset(&sigdefault.sa_mask);

      sigaction(sig,  &sigdefault, NULL);
      if (pid > 0) {
         Dmsg0(500, "Doing waitpid\n");
         waitpid(pid, &chld_status, 0);   /* wait for child to produce dump */
         Dmsg0(500, "Done waitpid\n");
      } else {
         Dmsg0(500, "Doing sleep\n");
         bmicrosleep(30, 0);
      }
      if (WEXITSTATUS(chld_status) == 0) {
         fprintf(stderr, _("It looks like the traceback worked...\n"));
      } else {
         fprintf(stderr, _("The btraceback call returned %d\n"),
                           WEXITSTATUS(chld_status));
      }
      /* If we want it printed, do so */
#ifdef direct_print
      if (prt_kaboom) {
         FILE *fd;
         snprintf(buf, sizeof(buf), "%s/%s.%s.traceback", working_directory, my_name, pid_buf);
         fd = fopen(buf, "r");
         if (fd != NULL) {
            printf("\n\n ==== Traceback output ====\n\n");
            while (fgets(buf, (int)sizeof(buf), fd) != NULL) {
               printf("%s", buf);
            }
            fclose(fd);
            printf(" ==== End traceback output ====\n\n");
         }
      }
#else
      if (prt_kaboom) {
         snprintf(buf, sizeof(buf), "/bin/cat %s/%s.%s.traceback", working_directory, my_name, pid_buf);
         fprintf(stderr, "\n\n ==== Traceback output ====\n\n");
         system(buf);
         fprintf(stderr, " ==== End traceback output ====\n\n");
      }
#endif

#ifndef DEVELOPER /* When DEVELOPER set, this is done above */
      /* print information about the current state into working/<file>.lockdump */
      dbg_print_bacula();
#endif

   }
#endif
   exit_handler(sig);
   Dmsg0(500, "Done exit_handler\n");
}