Mercurial > dovecot > original-hg > dovecot-1.2
changeset 3864:6124ca416a6c HEAD
Added gdbhelper binary.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 14 Jan 2006 14:46:33 +0200 |
parents | 55df57c028d4 |
children | 749d42902341 |
files | dovecot-example.conf src/util/Makefile.am src/util/gdbhelper.c |
diffstat | 3 files changed, 79 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/dovecot-example.conf Fri Jan 13 22:25:57 2006 +0200 +++ b/dovecot-example.conf Sat Jan 14 14:46:33 2006 +0200 @@ -413,10 +413,17 @@ # Login executable location. #login_executable = /usr/libexec/dovecot/imap-login - # IMAP executable location + # IMAP executable location. Changing this allows you to execute other + # binaries before the imap process is executed. + # + # This would write rawlogs into ~/dovecot.rawlog/ directory: + # mail_executable = /usr/libexec/dovecot/rawlog /usr/libexec/dovecot/imap + # + # This would attach gdb into the imap process and write backtraces into + # /tmp/gdbhelper.* files: + # mail_executable = /usr/libexec/dovecot/gdbhelper /usr/libexec/dovecot/imap + # #mail_executable = /usr/libexec/dovecot/imap - # This would write rawlogs into ~/dovecot.rawlog/ directory: - #mail_executable = /usr/libexec/dovecot/rawlog /usr/libexec/dovecot/imap # Maximum IMAP command line length in bytes. Some clients generate very long # command lines with huge mailboxes, so you may need to raise this if you get
--- a/src/util/Makefile.am Fri Jan 13 22:25:57 2006 +0200 +++ b/src/util/Makefile.am Sat Jan 14 14:46:33 2006 +0200 @@ -1,6 +1,6 @@ pkglibexecdir = $(libexecdir)/dovecot -pkglibexec_PROGRAMS = rawlog +pkglibexec_PROGRAMS = rawlog gdbhelper sbin_PROGRAMS = dovecotpw AM_CPPFLAGS = \ @@ -13,6 +13,12 @@ rawlog_SOURCES = \ rawlog.c +gdbhelper_LDADD = \ + ../lib/liblib.a + +gdbhelper_SOURCES = \ + gdbhelper.c + dovecotpw_LDADD = \ ../auth/libpassword.a \ ../lib-ntlm/libntlm.a \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/util/gdbhelper.c Sat Jan 14 14:46:33 2006 +0200 @@ -0,0 +1,62 @@ +/* Copyright (C) 2006 Timo Sirainen */ + +#include "lib.h" + +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <time.h> +#include <sys/wait.h> + +int main(int argc, char *argv[]) +{ + pid_t pid = fork(); + const char *path, *cmd; + int fd_in[2], fd_log, status; + + if (argc < 2) + i_fatal("Usage: gdbhelper <program> [<args>]"); + + switch (pid) { + case 1: + i_fatal("fork() failed: %m"); + case 0: + /* child */ + (void)execvp(argv[1], argv+1); + i_fatal("execvp(%s) failed: %m", argv[1]); + default: + path = t_strdup_printf("/tmp/gdbhelper.%s.%s", + dec2str(time(NULL)), dec2str(pid)); + fd_log = open(path, O_CREAT | O_WRONLY, 0600); + if (fd_log < 0) + i_fatal("open(%s) failed: %m", path); + + if (pipe(fd_in) < 0) + i_fatal("pipe() failed: %m"); + cmd = "handle SIGPIPE nostop\n" + "handle SIGALRM nostop\n" + "cont\n" + "where\n" + "quit\n"; + if (write(fd_in[1], cmd, strlen(cmd)) < 0) + i_fatal("write() failed: %m"); + + if (dup2(fd_in[0], 0) < 0 || + dup2(fd_log, 1) < 0 || + dup2(fd_log, 2) < 0) + i_fatal("dup2() failed: %m"); + + cmd = t_strdup_printf("gdb %s %s", argv[1], dec2str(pid)); + if (system(cmd) < 0) + i_fatal("system() failed: %m"); + + if (wait(&status) < 0) + i_fatal("wait() failed: %m"); + if (status == 0) { + if (unlink(path) < 0 && errno != ENOENT) + i_error("unlink(%s) failed: %m", path); + } + } + return 0; +}