Index: aim.c
===================================================================
--- aim.c	(revision c5873bee66a6dca24a9439b1a93ec6112e0cb9be)
+++ aim.c	(revision c6adf1779fe578bd628ad351bc8d99f756ea8e93)
@@ -184,5 +184,5 @@
   owl_function_debugmsg("owl_aim_login: connecting");
 
-  g.aim_nop_timer = owl_select_add_timer(30, 30, owl_aim_send_nop, NULL, NULL);
+  g.aim_nop_timer = owl_select_add_timer("owl_aim_send_nop", 30, 30, owl_aim_send_nop, NULL, NULL);
 
   return(0);
@@ -210,5 +210,6 @@
   /* start the ingorelogin timer */
   owl_global_set_ignore_aimlogin(&g);
-  owl_select_add_timer(owl_global_get_aim_ignorelogin_timer(&g),
+  owl_select_add_timer("owl_aim_unset_ignorelogin",
+                       owl_global_get_aim_ignorelogin_timer(&g),
                        0, owl_aim_unset_ignorelogin, NULL, NULL);
 
Index: commands.c
===================================================================
--- commands.c	(revision 118c9199a27438cd95333d4ef3faa2ccddab6622)
+++ commands.c	(revision c6adf1779fe578bd628ad351bc8d99f756ea8e93)
@@ -654,4 +654,5 @@
 	      "show subscriptions / show subs\n"
 	      "show terminal\n"
+	      "show timers\n"
 	      "show variables\n"
 	      "show variable <variable>\n"
@@ -2243,4 +2244,6 @@
   } else if (!strcmp(argv[1], "styles")) {
     owl_function_show_styles();
+  } else if (!strcmp(argv[1], "timers")) {
+    owl_function_show_timers();
   } else if (!strcmp(argv[1], "subs") || !strcmp(argv[1], "subscriptions")) {
     owl_function_getsubs();
Index: functions.c
===================================================================
--- functions.c	(revision 118c9199a27438cd95333d4ef3faa2ccddab6622)
+++ functions.c	(revision c6adf1779fe578bd628ad351bc8d99f756ea8e93)
@@ -90,4 +90,34 @@
   owl_function_popless_fmtext(&fm);
   owl_list_cleanup(&l, owl_free);
+  owl_fmtext_cleanup(&fm);
+}
+
+static void _owl_function_timer_append_fmtext(gpointer data, gpointer user_data) {
+  owl_fmtext *fm = user_data;
+  owl_timer *timer = data;
+  char *str = owl_sprintf("- %s: in %d seconds",
+                          timer->name ? timer->name : "(unnamed)",
+                          timer->time - time(NULL));
+  owl_fmtext_append_normal(fm, str);
+  owl_free(str);
+  if (timer->interval) {
+    str = owl_sprintf(", repeat every %d seconds", timer->interval);
+    owl_fmtext_append_normal(fm, str);
+    owl_free(str);
+  }
+  owl_fmtext_append_normal(fm, "\n");
+}
+
+void owl_function_show_timers(void) {
+  owl_fmtext fm;
+  GList **timers;
+
+  owl_fmtext_init_null(&fm);
+  owl_fmtext_append_bold(&fm, "Active timers:\n");
+
+  timers = owl_global_get_timerlist(&g);
+  g_list_foreach(*timers, _owl_function_timer_append_fmtext, &fm);
+
+  owl_function_popless_fmtext(&fm);
   owl_fmtext_cleanup(&fm);
 }
Index: owl.h
===================================================================
--- owl.h	(revision 118c9199a27438cd95333d4ef3faa2ccddab6622)
+++ owl.h	(revision c6adf1779fe578bd628ad351bc8d99f756ea8e93)
@@ -532,4 +532,5 @@
   void (*destroy)(struct _owl_timer *);
   void *data;
+  char *name;
 } owl_timer;
 
Index: perl/lib/BarnOwl/Complete/Client.pm
===================================================================
--- perl/lib/BarnOwl/Complete/Client.pm	(revision dc8f6e0953e232434c4d8f6fa01a608ed7bdb1da)
+++ perl/lib/BarnOwl/Complete/Client.pm	(revision c6adf1779fe578bd628ad351bc8d99f756ea8e93)
@@ -37,4 +37,5 @@
     subs        => undef,
     terminal    => undef,
+    timers      => undef,
     variables   => undef,
     variable    => \&complete_variable,
Index: perl/lib/BarnOwl/MainLoopCompatHook.pm
===================================================================
--- perl/lib/BarnOwl/MainLoopCompatHook.pm	(revision 385cce28938323d92a6fd45eba287049a36cee33)
+++ perl/lib/BarnOwl/MainLoopCompatHook.pm	(revision c6adf1779fe578bd628ad351bc8d99f756ea8e93)
@@ -44,4 +44,5 @@
   unless ($self->{timer}) {
     $self->{timer} = BarnOwl::Timer->new( {
+        name => "BarnOwl::MainLoopCompatHook",
         after => 0,
         interval => 1,
Index: perl/lib/BarnOwl/Timer.pm
===================================================================
--- perl/lib/BarnOwl/Timer.pm	(revision 8d16e58dfb7d32aaae1378039fbbde334d5ab660)
+++ perl/lib/BarnOwl/Timer.pm	(revision c6adf1779fe578bd628ad351bc8d99f756ea8e93)
@@ -13,9 +13,13 @@
     my $self = {cb => $cb};
 
+    my $name = $args->{name};
+    $name = "(unnamed)" unless defined $name;
+
     bless($self, $class);
 
     $self->{timer} = BarnOwl::Internal::add_timer($args->{after} || 0,
                                                   $args->{interval} || 0,
-                                                  $self);
+                                                  $self,
+                                                  $name);
     return $self;
 }
Index: perl/modules/IRC/lib/BarnOwl/Module/IRC/Connection.pm
===================================================================
--- perl/modules/IRC/lib/BarnOwl/Module/IRC/Connection.pm	(revision c8d9f84473286a0cc8096539ea7153ff6793b35d)
+++ perl/modules/IRC/lib/BarnOwl/Module/IRC/Connection.pm	(revision c6adf1779fe578bd628ad351bc8d99f756ea8e93)
@@ -324,4 +324,5 @@
     $self->{reconnect_timer} = 
         BarnOwl::Timer->new( {
+            name  => 'IRC (' . $self->alias . ') reconnect_timer',
             after => $interval,
             cb    => sub {
Index: perl/modules/Jabber/lib/BarnOwl/Module/Jabber/Connection.pm
===================================================================
--- perl/modules/Jabber/lib/BarnOwl/Module/Jabber/Connection.pm	(revision 0dbb7d2f35f2a47f67378d74e79b3d2d6da229af)
+++ perl/modules/Jabber/lib/BarnOwl/Module/Jabber/Connection.pm	(revision c6adf1779fe578bd628ad351bc8d99f756ea8e93)
@@ -198,4 +198,5 @@
         $BarnOwl::Module::Jabber::vars{keepAliveTimer} =
             BarnOwl::Timer->new({
+                'name' => "Jabber ($fullJid) keepAliveTimer",
                 'after' => 5,
                 'interval' => 5,
Index: perl/modules/Twitter/lib/BarnOwl/Module/Twitter/Handle.pm
===================================================================
--- perl/modules/Twitter/lib/BarnOwl/Module/Twitter/Handle.pm	(revision c8d9f84473286a0cc8096539ea7153ff6793b35d)
+++ perl/modules/Twitter/lib/BarnOwl/Module/Twitter/Handle.pm	(revision c6adf1779fe578bd628ad351bc8d99f756ea8e93)
@@ -160,6 +160,8 @@
     }
 
+    my $nickname = $self->{cfg}->{account_nickname};
     if($self->{cfg}->{poll_for_tweets}) {
         $self->{timer} = BarnOwl::Timer->new({
+            name     => "Twitter ($nickname) poll_for_tweets",
             after    => $delay,
             interval => 90,
@@ -170,4 +172,5 @@
     if($self->{cfg}->{poll_for_dms}) {
         $self->{direct_timer} = BarnOwl::Timer->new({
+            name     => "Twitter ($nickname) poll_for_dms",
             after    => $delay,
             interval => 180,
Index: perlglue.xs
===================================================================
--- perlglue.xs	(revision 818f19c647de5c3fdf58e43b27b2809ea5ea5607)
+++ perlglue.xs	(revision c6adf1779fe578bd628ad351bc8d99f756ea8e93)
@@ -516,8 +516,9 @@
 
 IV
-add_timer(after, interval, cb)
+add_timer(after, interval, cb, name = NULL)
 	int after
 	int interval
 	SV *cb
+	const char *name
 	PREINIT:
 		SV *ref;
@@ -525,10 +526,11 @@
 	CODE:
 		ref = sv_rvweaken(newSVsv(cb));
-		t = owl_select_add_timer(after,
+		t = owl_select_add_timer(name,
+					 after,
 					 interval,
 					 owl_perlconfig_perl_timer,
 					 owl_perlconfig_perl_timer_destroy,
 					 ref);
-	owl_function_debugmsg("Created timer %p", t);
+		owl_function_debugmsg("Created timer %s: %p", t->name ? t->name : "(unnamed)", t);
 	RETVAL = (IV)t;
 	OUTPUT:
@@ -542,6 +544,6 @@
 	CODE:
 		t = (owl_timer*)timer;
-		owl_function_debugmsg("Freeing timer %p", t);
-				owl_select_remove_timer(t);
+		owl_function_debugmsg("Freeing timer %s: %p", t->name ? t->name : "(unnamed)", t);
+		owl_select_remove_timer(t);
 
 MODULE = BarnOwl		PACKAGE = BarnOwl::Editwin
Index: select.c
===================================================================
--- select.c	(revision 3ecd78ba8fdedc0077ed849163b6415a5969327a)
+++ select.c	(revision c6adf1779fe578bd628ad351bc8d99f756ea8e93)
@@ -13,5 +13,5 @@
 }
 
-owl_timer *owl_select_add_timer(int after, int interval, void (*cb)(owl_timer *, void *), void (*destroy)(owl_timer*), void *data)
+owl_timer *owl_select_add_timer(const char* name, int after, int interval, void (*cb)(owl_timer *, void *), void (*destroy)(owl_timer*), void *data)
 {
   owl_timer *t = owl_malloc(sizeof(owl_timer));
@@ -23,4 +23,5 @@
   t->destroy = destroy;
   t->data = data;
+  t->name = name ? owl_strdup(name) : NULL;
 
   *timers = g_list_insert_sorted(*timers, t,
@@ -37,4 +38,5 @@
       t->destroy(t);
     }
+    owl_free(t->name);
     owl_free(t);
   }
Index: variable.c
===================================================================
--- variable.c	(revision b120bd3c1bd6d9da691c8e4f11a3a1ba56d34c83)
+++ variable.c	(revision c6adf1779fe578bd628ad351bc8d99f756ea8e93)
@@ -435,5 +435,6 @@
       owl_function_zephyr_buddy_check(0);
       if (timer == NULL) {
-        timer = owl_select_add_timer(180, 180, owl_zephyr_buddycheck_timer, NULL, NULL);
+        timer = owl_select_add_timer("owl_zephyr_buddycheck_timer",
+                                     180, 180, owl_zephyr_buddycheck_timer, NULL, NULL);
       }
     } else {
