[asterisk-bugs] [JIRA] (ASTERISK-25525) A call EndWhile can cause the dial plan to jump to another context.

Richard Mudgett (JIRA) noreply at issues.asterisk.org
Thu Nov 5 17:53:33 CST 2015


    [ https://issues.asterisk.org/jira/browse/ASTERISK-25525?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=228165#comment-228165 ] 

Richard Mudgett commented on ASTERISK-25525:
--------------------------------------------

Your dialplan is incorrect.  You never exited the inner while loop.  That is why it returns to the inner while loop's location.  You need to use ExitWhile to terminate the loop early before you can return from the subroutine.  Also you have to be careful about the use of ExitWhile because the loop has to have seen the loop's EndWhile for ExitWhile to know where execution needs to jump to the end of the loop.

Usage rules:
# {{While}} marks the start of a while loop in the dialplan as well as the condition to keep executing the loop.  For the {{While}} to terminate the loop, the loop's {{EndWhile}} must have been executed before.  This implies that the while condition must have been true at least once.
# {{EndWhile}} marks the end of the while loop.
# {{ExitWhile}} breaks out of the while loop and jumps to the loop's {{EndWhile}} location.  For {{ExitWhile}} to know where to go, the loop's {{EndWhile}} must have been executed before.
# {{ContinueWhile}} jumps to the current while loop's {{While}} location.

[~rnewton] This information needs to be added to the {{While}} application's documentation as it is currently lacking much usage detail.

> A call EndWhile can cause the dial plan to jump to another context.
> -------------------------------------------------------------------
>
>                 Key: ASTERISK-25525
>                 URL: https://issues.asterisk.org/jira/browse/ASTERISK-25525
>             Project: Asterisk
>          Issue Type: Bug
>      Security Level: None
>          Components: Applications/app_while
>    Affects Versions: 11.6.0
>            Reporter: Steven T. Wheeler
>            Severity: Minor
>
> I would expect that a While/EndWhile loop would be restricted to a single context. However, in some cases a call EndWhile can cause the dial plan to jump to another context. We have noticed this with Gosub and Goto.
> Here is a simple example:
> {code:title=extensions.conf|borderStyle=solid}
> [test-while-out]
> exten => s,1,Set(i=0)
>  same => n,While($[${INC(i)} <= 5])
>   same => n,Log(NOTICE,i is ${i})
>   same => n,Gosub(test-while-inner,s,1)
>  same => n,EndWhile
> [test-while-inner]
> exten => s,1,Set(j=0)
>  same => n,While($[${INC(j)} <= 5])
>   same => n,Log(NOTICE,j is ${j})
>   same => n,Return
>  same => n,EndWhile
>  same => n,Return
> {code}
> And in the Asterisk console execute:
> {code:title=Console|borderStyle=solid}
> *CLI> originate Local/s at test-while-out application wait 10
>     -- Executing [s at test-while-out:1] Set("Local/s at test-while-out-00000008;2", "i=0") in new stack
>     -- Executing [s at test-while-out:2] While("Local/s at test-while-out-00000008;2", "1") in new stack
>     -- Executing [s at test-while-out:3] Log("Local/s at test-while-out-00000008;2", "NOTICE,i is 1") in new stack
> [2015-11-05 16:28:59] NOTICE[27770][C-00000013]: Ext. s:3 @ test-while-out: i is 1
>     -- Executing [s at test-while-out:4] Gosub("Local/s at test-while-out-00000008;2", "test-while-inner,s,1") in new stack
>     -- Executing [s at test-while-inner:1] Set("Local/s at test-while-out-00000008;2", "j=0") in new stack
>     -- Executing [s at test-while-inner:2] While("Local/s at test-while-out-00000008;2", "1") in new stack
>     -- Executing [s at test-while-inner:3] Log("Local/s at test-while-out-00000008;2", "NOTICE,j is 1") in new stack
> [2015-11-05 16:28:59] NOTICE[27770][C-00000013]: Ext. s:3 @ test-while-inner: j is 1
>     -- Executing [s at test-while-inner:4] Return("Local/s at test-while-out-00000008;2", "") in new stack
>     -- Executing [s at test-while-out:5] EndWhile("Local/s at test-while-out-00000008;2", "") in new stack
>     -- Executing [s at test-while-inner:2] While("Local/s at test-while-out-00000008;2", "1") in new stack
>     -- Executing [s at test-while-inner:3] Log("Local/s at test-while-out-00000008;2", "NOTICE,j is 2") in new stack
> [2015-11-05 16:28:59] NOTICE[27770][C-00000013]: Ext. s:3 @ test-while-inner: j is 2
>     -- Executing [s at test-while-inner:4] Return("Local/s at test-while-out-00000008;2", "") in new stack
> [2015-11-05 16:28:59] ERROR[27770][C-00000013]: app_stack.c:378 return_exec: Return without Gosub: stack is empty
>   == Spawn extension (test-while-inner, s, 4) exited non-zero on 'Local/s at test-while-out-00000008;2'
> {code}
> The call starts at test-while-out which contains a While/EndWhile loop. Inside that loop it logs the value of {{i}} and the Gosubs to test-while-inner. The inner context also contains a While/EndWhile loop but we return from inside the loop. In the real world this would be due to some conditional statement. After returning to the outer loop we call EndWhile. I would expect this to bring us back to the beginning of the outer loop. But it actually brings us back to the beginning of the inner loop.



--
This message was sent by Atlassian JIRA
(v6.2#6252)



More information about the asterisk-bugs mailing list