Commit a8001bb2 a8001bb2e4684d7144e9a2217704e8f6635c5603 by Sergey Poznyakoff

Add useful debugging hooks.

* libmailutils/diag/bt.c: New file.
* libmailutils/diag/wd.c: New file.
* libmailutils/diag/Makefile.am (libdiag_la_SOURCES): Add bt.c and wd.c

* include/mailutils/debug.h (mu_gdb_bt, mu_wd): New protos.
* include/mailutils/util.h (mu_getmaxfd): New protos.
* libmailutils/base/getmaxfd.c: New file.
* libmailutils/base/Makefile.am (libbase_la_SOURCES): Add getmaxfd.c

* libmailutils/server/acl.c: Use mu_getmaxfd.
* libmailutils/stream/prog_stream.c: Likewise.
* mh/mh_whatnow.c: Likewise.

* libmu_scm/mu_body.c (mu-body?): Bugfix.
1 parent ec0d5f94
......@@ -83,7 +83,6 @@ void mu_debug_log_begin (const char *fmt, ...) MU_PRINTFLIKE(1,2);
void mu_debug_log_cont (const char *fmt, ...) MU_PRINTFLIKE(1,2);
void mu_debug_log_end (const char *fmt, ...) MU_PRINTFLIKE(1,2);
void mu_debug_log_nl (void);
#define MU_ASSERT(expr) \
......@@ -115,7 +114,13 @@ void mu_debug_log_nl (void);
mu_debug_log s; \
} \
while (0)
/* Debugging hooks. */
/* Dump a stack trace and terminate the program. */
void mu_gdb_bt (void);
/* Sleep till attached to by gdb. */
void mu_wd (unsigned to);
#ifdef __cplusplus
}
#endif
......
......@@ -177,6 +177,7 @@ int mu_getpass (mu_stream_t in, mu_stream_t out, const char *prompt,
/* ----------------------- */
/* Assorted functions. */
/* ----------------------- */
int mu_getmaxfd (void);
/* Get the host name, doing a gethostbyname() if possible. */
int mu_get_host_name (char **host);
int mu_spawnvp (const char *prog, char *av[], int *stat);
......
......@@ -31,6 +31,7 @@ libbase_la_SOURCES = \
filename.c\
freeitem.c\
getcwd.c\
getmaxfd.c\
getpass.c\
hostname.c\
iterator.c\
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library. If not, see
<http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <unistd.h>
#include <limits.h>
#if defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX)
# define __getmaxfd() sysconf (_SC_OPEN_MAX)
#elif defined (HAVE_GETDTABLESIZE)
# define __getmaxfd() getdtablesize ()
#elif defined OPEN_MAX
# define __getmaxfd() OPEN_MAX
#else
# define __getmaxfd() 256
#endif
int
mu_getmaxfd ()
{
return __getmaxfd ();
}
......@@ -18,11 +18,13 @@
noinst_LTLIBRARIES = libdiag.la
libdiag_la_SOURCES = \
bt.c\
debug.c\
diag.c\
muerror.c\
muerrno.c\
syslog.c
syslog.c\
wd.c
INCLUDES = @MU_LIB_COMMON_INCLUDES@ -I/libmailutils
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library. If not, see
<http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <argp.h>
#include <mailutils/util.h>
/* Dump a stack trace and terminate current program.
The trace is written to file /tmp/mailutils.PROG.PID, where PROG
is the file name of the program, and PID its PID. */
void
mu_gdb_bt ()
{
int i;
pid_t master_pid = getpid ();
pid_t pid;
static char buf[1024];
static char fname[1024];
char *p;
int fd;
char *argv[8];
p = strrchr (program_invocation_name, '/');
if (p)
p++;
else
p = program_invocation_name;
sprintf (fname, "/tmp/mailutils.%s.%lu", p, (unsigned long) master_pid);
pid = fork ();
if (pid == (pid_t)-1)
abort ();
if (pid)
{
sleep (10);
abort ();
}
for (i = mu_getmaxfd (); i >= 0; i--)
close (i);
fd = open (fname, O_WRONLY|O_CREAT, 0600);
if (fd == -1)
abort ();
dup2 (fd, 1);
dup2 (fd, 2);
close (fd);
argv[0] = "/usr/bin/gdb";
argv[1] = program_invocation_name;
sprintf (buf, "%lu", (unsigned long) master_pid);
argv[2] = buf;
argv[3] = "-ex";
argv[4] = "bt";
argv[5] = "-ex";
argv[6] = "kill";
argv[7] = NULL;
execvp (argv[0], argv);
abort ();
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library. If not, see
<http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <unistd.h>
#include <argp.h>
#include <mailutils/diag.h>
/* A debugging hook.
Suspend execution to let the developer to attach to the current process
using gdb.
Wait at most TO seconds. If TO is 0, wait forever. */
void
mu_wd (unsigned to)
{
unsigned volatile _count_down;
pid_t pid = getpid ();
if (to)
mu_diag_output (MU_DIAG_CRIT,
"process %lu is waiting for debug (%u seconds left)",
(unsigned long) pid, to);
else
mu_diag_output (MU_DIAG_CRIT,
"process %lu is waiting for debug",
(unsigned long) pid);
mu_diag_output (MU_DIAG_CRIT,
"to attach: gdb -ex 'set variable mu_wd::_count_down=0' %s %lu",
program_invocation_name, (unsigned long) pid);
if (to)
{
_count_down = to;
while (_count_down)
{
sleep (1);
_count_down--;
}
}
else
{
_count_down = 1;
while (_count_down)
{
sleep (1);
}
}
mu_diag_output (MU_DIAG_CRIT, "process %lu finished waiting",
(unsigned long) pid);
}
......@@ -39,6 +39,7 @@
#include <mailutils/errno.h>
#include <mailutils/kwd.h>
#include <mailutils/io.h>
#include <mailutils/util.h>
struct _mu_acl_entry
{
......@@ -473,14 +474,6 @@ struct run_closure
mu_acl_result_t *result;
};
#if defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX)
# define getmaxfd() sysconf (_SC_OPEN_MAX)
#elif defined (HAVE_GETDTABLESIZE)
# define getmaxfd() getdtablesize ()
#else
# define getmaxfd() 64
#endif
#define SEQ(s, n, l) \
(((l) == (sizeof(s) - 1)) && memcmp (s, n, l) == 0)
......@@ -604,7 +597,7 @@ spawn_prog (const char *cmdline, int *pstatus, struct run_closure *rp)
_exit (127);
}
for (i = getmaxfd (); i > 2; i--)
for (i = mu_getmaxfd (); i > 2; i--)
close (i);
execvp (ws.ws_wordv[0], ws.ws_wordv);
_exit (127);
......
......@@ -60,14 +60,6 @@ _prog_stream_unregister (struct _mu_prog_stream *stream)
#if defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX)
# define getmaxfd() sysconf (_SC_OPEN_MAX)
#elif defined (HAVE_GETDTABLESIZE)
# define getmaxfd() getdtablesize ()
#else
# define getmaxfd() 64
#endif
#define REDIRECT_STDIN_P(f) ((f) & MU_STREAM_WRITE)
#define REDIRECT_STDOUT_P(f) ((f) & MU_STREAM_READ)
......@@ -260,7 +252,7 @@ start_program_filter (int *p, struct _mu_prog_stream *fs, int flags)
}
/* Close unneded descripitors */
for (i = getmaxfd (); i > 2; i--)
for (i = mu_getmaxfd (); i > 2; i--)
close (i);
/*FIXME: Switch to other uid/gid if desired */
......
......@@ -100,7 +100,7 @@ SCM_DEFINE_PUBLIC (scm_mu_body_p, "mu-body?", 1, 0, 0,
"Return @code{true} if @var{scm} is a Mailutils message body object.\n")
#define FUNC_NAME s_scm_mu_body_p
{
return mu_scm_is_body (scm);
return scm_from_bool (mu_scm_is_body (scm));
}
#undef FUNC_NAME
......
......@@ -17,14 +17,6 @@
#include <mh.h>
#if defined (HAVE_SYSCONF) && defined (_SC_OPEN_MAX)
# define getmaxfd() sysconf (_SC_OPEN_MAX)
#elif defined (HAVE_GETDTABLESIZE)
# define getmaxfd() getdtablesize ()
#else
# define getmaxfd() 64
#endif
typedef int (*handler_fp) (struct mh_whatnow_env *wh,
int argc, char **argv,
int *status);
......@@ -620,7 +612,7 @@ mh_whatnowproc (struct mh_whatnow_env *wh, int initial_edit, const char *prog)
set_default_editor (wh);
mh_whatnow_env_to_environ (wh);
for (i = getmaxfd (); i > 2; i--)
for (i = mu_getmaxfd (); i > 2; i--)
close (i);
execvp (ws.ws_wordv[0], ws.ws_wordv);
mu_diag_funcall (MU_DIAG_ERROR, "execvp", prog, errno);
......