[Asterisk-Dev] ForkCDR and hangups

Cees de Groot cg at tric.nl
Thu Dec 30 04:06:57 MST 2004


Hi,

As there's little response on the -users list, I'm taking this here. To  
recap, I had problems when I introduced ForkCDR in my dial plan - now and  
then, Asterisk threads would go bezerk, eat 100% CPU time. DDD quickly  
told me that this was always when doing one of the cdr->next loops in  
cdr.c...

The only place that cdr->next is handled, is in ast_cdr_append where -  
IMHO - some tricky stuff appears with the CDR linked list. As far as my  
setup is concerned, this is called from ForkCDR and the Zap transfer  
function (which I presume is used when doing a Dial - the system at hand  
lets users dial a 0900 (special rate) number and dial out international  
numbers again).

Indeed, the cdr->next->next == cdr in DDD, ergo an endless loop.

I quickly patched it up:

Index: cdr.c
===================================================================
RCS file: /var/lib/cvsroot/breezz/lib/asterisk/cdr.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 cdr.c
--- cdr.c16 Nov 2004 16:57:07 -00001.1.1.1
+++ cdr.c30 Dec 2004 10:55:33 -0000
@@ -532,6 +532,11 @@
  while(cdr->next)
  cdr = cdr->next;
  cdr->next = newcdr;
+/* Stopgap measure to remove circularities
+ * that can occur when ForkCDR() is used...
+ */
+if (newcdr->next == cdr)
+newcdr->next = NULL;
  } else {
  ret = newcdr;
  }

But next day, I had some threads in 100% CPU mode again. DDD showed me  
that now, I had *three* CDR's, where cdr == cdr->next->next->next, a case  
my stopgap hack didn't catch of course. Sifting through the dialplan I  
noticed indeed that it was possible to call ForkCDR multiple times, and  
indeed it would be preferrable to have it that way (one CDR for the  
inbound leg, one CDR for each outbound attempt. If an outbound attempt  
fails, the user is transported back to the IVR main menu). I patched my  
dialplan so it goes through ForkCDR only once (which is sufficient for now  
- we mostly want to catch the outbound leg's billable seconds, but later  
one we might want to register the failed outbound attempts as well, or  
even change the menu that the user stays in the IVR after a
succesful call), and since then Asterisk is running.

I haven't got a clue what all the CDR 'stitching' in  
chan_zap.c:attempt_transfer() should accomplish (to be frank, I haven't  
really really studied that code), but something there is quite  
incompatible with ForkCDR, it seems.

Anyone who can shed some light on this? Wrt code quality, should all the  
loops in cdr.c be rewritten so that they detect endless loops? (probably  
by replacing all the while statements by some industrial quality iteration  
function ;-)). I really want to be able to use ForkCDR multiple times in a  
single call...

TIA,

Cees



More information about the asterisk-dev mailing list