I really didn't like much the current way to attach a debugger to cyrus,
so I cooked up something that might be of interest to you guys.

Basically, one should set "debug_command" in imapd.conf to a format string.
There are three parameters: the first is the name of the executable (sans
path). The second is the pid (integer) and the third is the service ID.

I use (paths for the Debian package, which are different from stock Cyrus):
debug_command: /usr/sbin/ddd /usr/lib/cyrus/bin/%s %d

To enable, give a "-D" option to the cyrus service.

This is clearly a bit too rough still;  I didn't even attempt to write the
hook for the service-threads.c variation.  Also, maybe it would be better to
use environment variables instead of a config directive to specify the
debugging command?

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
Index: imap/fud.c
===================================================================
RCS file: /home/cvs/debian/cyrus21-imapd/imap/fud.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 fud.c
--- imap/fud.c  22 Feb 2002 17:25:26 -0000      1.1.1.4
+++ imap/fud.c  13 May 2002 17:35:32 -0000
@@ -164,9 +164,11 @@
 
     setproctitle_init(argc, argv, envp);
 
-    while ((opt = getopt(argc, argv, "C:")) != EOF) {
+    while ((opt = getopt(argc, argv, "C:D")) != EOF) {
        switch (opt) {
        case 'C': /* alt config file - handled by service::main() */
+           break;
+       case 'D': /* external debugger - handled by service::main() */
            break;
        default:
            break;
Index: imap/imapd.c
===================================================================
RCS file: /home/cvs/debian/cyrus21-imapd/imap/imapd.c,v
retrieving revision 1.11
diff -u -r1.11 imapd.c
--- imap/imapd.c        29 Apr 2002 12:17:51 -0000      1.11
+++ imap/imapd.c        13 May 2002 17:36:09 -0000
@@ -533,9 +533,11 @@
     snmp_connect(); /* ignore return code */
     snmp_set_str(SERVER_NAME_VERSION,CYRUS_VERSION);
 
-    while ((opt = getopt(argc, argv, "C:sp:")) != EOF) {
+    while ((opt = getopt(argc, argv, "C:Dsp:")) != EOF) {
        switch (opt) {
        case 'C': /* alt config file - handled by service::main() */
+           break;
+       case 'D': /* external debugger - handled by service::main() */
            break;
        case 's': /* imaps (do starttls right away) */
            imaps = 1;
Index: imap/lmtpd.c
===================================================================
RCS file: /home/cvs/debian/cyrus21-imapd/imap/lmtpd.c,v
retrieving revision 1.10
diff -u -r1.10 lmtpd.c
--- imap/lmtpd.c        16 Apr 2002 20:12:42 -0000      1.10
+++ imap/lmtpd.c        13 May 2002 17:39:40 -0000
@@ -313,9 +313,11 @@
     prot_setflushonread(deliver_in, deliver_out);
     prot_settimeout(deliver_in, 360);
 
-    while ((opt = getopt(argc, argv, "C:a")) != EOF) {
+    while ((opt = getopt(argc, argv, "C:Da")) != EOF) {
        switch(opt) {
        case 'C': /* alt config file - handled by service::main() */
+           break;
+       case 'D': /* ext. debugger - handled by service::main() */
            break;
 
        case 'a':
Index: imap/lmtpproxyd.c
===================================================================
RCS file: /home/cvs/debian/cyrus21-imapd/imap/lmtpproxyd.c,v
retrieving revision 1.9
diff -u -r1.9 lmtpproxyd.c
--- imap/lmtpproxyd.c   30 Apr 2002 19:14:39 -0000      1.9
+++ imap/lmtpproxyd.c   13 May 2002 17:40:08 -0000
@@ -279,9 +279,11 @@
     prot_setflushonread(deliver_in, deliver_out);
     prot_settimeout(deliver_in, 300);
 
-    while ((opt = getopt(argc, argv, "C:q")) != EOF) {
+    while ((opt = getopt(argc, argv, "C:Dq")) != EOF) {
        switch(opt) {
        case 'C': /* alt config file - handled by service::main() */
+           break;
+       case 'D': /* ext debugger - handled by service::main() */
            break;
 
        case 'q':
Index: imap/mupdate.c
===================================================================
RCS file: /home/cvs/debian/cyrus21-imapd/imap/mupdate.c,v
retrieving revision 1.1.1.10
diff -u -r1.1.1.10 mupdate.c
--- imap/mupdate.c      11 Apr 2002 16:05:00 -0000      1.1.1.10
+++ imap/mupdate.c      13 May 2002 17:40:47 -0000
@@ -352,9 +352,11 @@
     }
 
     /* see if we're the master or a slave */
-    while ((opt = getopt(argc, argv, "C:m")) != EOF) {
+    while ((opt = getopt(argc, argv, "C:Dm")) != EOF) {
        switch (opt) {
        case 'C':
+           break;
+       case 'D': /* ext debugger */
            break;
        case 'm':
            masterp = 1;
Index: imap/pop3d.c
===================================================================
RCS file: /home/cvs/debian/cyrus21-imapd/imap/pop3d.c,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 pop3d.c
--- imap/pop3d.c        10 Apr 2002 18:02:42 -0000      1.1.1.7
+++ imap/pop3d.c        13 May 2002 17:37:48 -0000
@@ -337,9 +337,11 @@
        fatal(error_message(r), EC_CONFIG);
     }
 
-    while ((opt = getopt(argc, argv, "C:sk")) != EOF) {
+    while ((opt = getopt(argc, argv, "C:Dsk")) != EOF) {
        switch(opt) {
        case 'C': /* alt config file - handled by service::main() */
+           break;
+       case 'D': /* external debugger - handled by service::main() */
            break;
 
        case 's': /* pop3s (do starttls right away) */
Index: imap/pop3proxyd.c
===================================================================
RCS file: /home/cvs/debian/cyrus21-imapd/imap/pop3proxyd.c,v
retrieving revision 1.1.1.8
diff -u -r1.1.1.8 pop3proxyd.c
--- imap/pop3proxyd.c   23 Apr 2002 18:41:33 -0000      1.1.1.8
+++ imap/pop3proxyd.c   13 May 2002 17:39:00 -0000
@@ -221,9 +221,11 @@
     popd_in = prot_new(0, 0);
     popd_out = prot_new(1, 1);
 
-    while ((opt = getopt(argc, argv, "C:sk")) != EOF) {
+    while ((opt = getopt(argc, argv, "C:Dsk")) != EOF) {
        switch(opt) {
        case 'C': /* alt config file - handled by service::main() */
+           break;
+       case 'D': /* ext. debugger - handled by service::main() */
            break;
 
        case 's': /* pop3s (do starttls right away) */
Index: imap/proxyd.c
===================================================================
RCS file: /home/cvs/debian/cyrus21-imapd/imap/proxyd.c,v
retrieving revision 1.1.1.15
diff -u -r1.1.1.15 proxyd.c
--- imap/proxyd.c       28 Apr 2002 18:12:50 -0000      1.1.1.15
+++ imap/proxyd.c       13 May 2002 17:38:15 -0000
@@ -927,9 +927,11 @@
     mboxlist_init(0);
     mboxlist_open(NULL);
 
-    while ((opt = getopt(argc, argv, "C:sp:")) != EOF) {
+    while ((opt = getopt(argc, argv, "C:Dsp:")) != EOF) {
        switch (opt) {
        case 'C': /* alt config file - handled by service::main() */
+           break;
+       case 'D': /* ext. debugger - handled by service::main() */
            break;
        case 's': /* imaps (do starttls right away) */
            imaps = 1;
Index: master/service.c
===================================================================
RCS file: /home/cvs/debian/cyrus21-imapd/master/service.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 service.c
--- master/service.c    8 Mar 2002 19:26:17 -0000       1.1.1.5
+++ master/service.c    13 May 2002 18:21:35 -0000
@@ -138,6 +138,7 @@
 #endif
 
 extern void config_init(const char *, const char *);
+extern const char *config_getstring(const char *key, const char *def);
 extern const char *config_dir;
 
 static int getlockfd(char *service)
@@ -257,14 +258,18 @@
     struct request_info request;
     int opt;
     char *alt_config = NULL;
+    int call_debugger = 0;
     int soctype;
     int typelen = sizeof(soctype);
 
-    while ((opt = getopt(argc, argv, "C:")) != EOF) {
+    while ((opt = getopt(argc, argv, "C:D")) != EOF) {
        switch (opt) {
        case 'C': /* alt config file */
            alt_config = optarg;
            break;
+       case 'D': /* activate external debugger */
+           call_debugger = 1;
+           break;
        default:
            break;
        }
@@ -291,6 +296,18 @@
     }
     config_init(alt_config, service);
 
+    if (call_debugger) {
+       char debugbuf[1024];
+       int ret;
+       const char *debugger = config_getstring("debug_command", (char *) 0);
+       if (debugger) {
+           snprintf(debugbuf, sizeof(debugbuf), debugger, 
+                    argv[0], getpid(), service);
+           syslog(LOG_DEBUG, "running external debugger: %s", debugbuf);
+           ret = system(debugbuf); /* run debugger */
+           syslog(LOG_DEBUG, "debugger returned exit status: %d", ret);
+       }
+    }
     syslog(LOG_DEBUG, "executed");
 
     /* set close on exec */

Reply via email to