Bug? Select Case doesn't work in Debug. In release is ok

Mike1970

Well-Known Member
Licensed User
Longtime User
Hi everyone, i'm getting annoyed becuase when i'm running the app in debug, and there is a select case function it is always skipped, even if the condition is true. I attach a gif.
Sorry for the quality but i can't upload a better file because there is the size limit for attachment :(

ezgif.com-optimize(6).gif


This is the code. In the example the Result variable is 1 (0x1)
B4X:
Wait For (RegistrazioneCompletata) Complete (Result As Int)
Select Result
    Case 1
        ...
    
    Case 2
        ...
    
    Case 3
        ...
    
    Case 4
        ...
    
End Select
 

Mike1970

Well-Known Member
Licensed User
Longtime User
The video doesn't help.

I guess that the code is executed and only the breakpoint is skipped. Add some log messages to verify it.

Obviusly in the "Case 1" there is a bunch of code:


B4X:
Case 1
    Try
        Main.FileManager1.SQL1.ExecNonQuery2("INSERT INTO operazioni VALUES (?, ?, ?, ?)", Array As Object(Null, DateTime.Time(DateTime.Now) & " " & DateTime.Date(DateTime.Now), Home.codiceCisterna, Litri.valoreLitri))
        Main.FileManager1.Dump("operazioni")
    Catch
        Msgbox("",LastException)
    End Try


    Msgbox2("Msg", "Operazione registrata con successo", "Completato", Array ("Ok"))
    Wait For Msg_Click (ButtonText As String)
        If ButtonText = "Ok" Then
        'elimino il file di sessione
            If File.Exists(File.DirLibrary & $"/${Main.FileManager1.NomeCartella}"$, "tmpSession.txt") Then
                Log(File.Delete(File.DirLibrary & $"/${Main.FileManager1.NomeCartella}"$, "tmpSession.txt"))
            End If

            btnDelete_Click 'cancello la foto dalla preview

            Main.NavControl.ShowPage(Home.HomePg)
        End If

None of this line is executed on the iPhone, the msgbox2 doesn't appear infact.
 

Mike1970

Well-Known Member
Licensed User
Longtime User
Try to reproduce it in a small project.

In a clean project it works correctly.. but i simpy made a function that return a number.

Maybe the bug is related to a combination of elements that i don't know ...

The fact are that the Result variable is 1, and the code written in the "Case 1" is not exectued BUT in release it works, infact meanwhile i'm doing like so ... i don't know how to recreate the error in a way to publish it here :(
 

Mike1970

Well-Known Member
Licensed User
Longtime User
UPDATE:
I don't know if it's the usual randomness of this thing, but i changed the code from:

B4X:
Wait For (RegistrazioneCompletata) Complete (Result As Int)
Select Result
    Case 1
        ...
    
    Case 2
        ...
    
    Case 3
        ...
    
    Case 4
        ...
    
End Select

To

B4X:
Wait For (RegistrazioneCompletata) Complete (Result As String)
Select Result
    Case "1"
        ...
    
    Case "2"
        ...
    
    Case "3"
        ...
    
    Case "4"
        ...
    
End Select

And it seems to works :/
 

emexes

Expert
Licensed User
UPDATE:
I don't know if it's the usual randomness of this thing, but i changed the code from:

And it seems to works :/
This makes me think you have some race going on in your program, between RegistrazioneCompletata completing and Result being set, and string conversions/operations and debug mode slow things down enough for the Result to be set before it is used by the Select Case.

If it reliably fails (!) in release mode with Result As Int, then try adding a small delay in-between the Complete and the Select.

Eg either a loop (although do-nothing loops have a nasty tendency of being optimized to NOP or less) or:
B4X:
Wait For (RegistrazioneCompletata) Complete (Result As Int)

Dim IntResult As Int = Result
Dim StringResult As String = Result

If Result <> IntResult Then
    'send out a wtf call for help, bearing in mind that we're in release mode and probably without Log()
End If

Select Result
 
Last edited:

Mike1970

Well-Known Member
Licensed User
Longtime User
If it reliably fails (!) in release mode with Result As Int, then try adding a small delay in-between the Complete and the Select.
I tried also this thing D:
Nothing to do, randomly in debug it is skipped.
In release alsways work, but is a annoying thing because i can't debug properly :/
 

emexes

Expert
Licensed User
Nothing to do, randomly in debug it is skipped.
Arghh, I misunderstood anyway: I thought it was working in debug mode and not in release mode, but I've got it arse-about.

In release alsways work, but is a annoying thing because i can't debug properly :/
Annoying indeed. But I still feel like it could be a timing issue.

Can you set Result, before calling RegistrazioneCompletata, be some value that never happens eg Result = -123456, and then after the Complete event but before you use Result, make sure that it (Result) has actually been changed by RegistrazioneCompletata ?

Clutching at straws, I know, but... if it happens during testing, it's gonna happen to your users too. :oops:
 

agraham

Expert
Licensed User
Longtime User
if it happens during testing, it's gonna happen to your users too
Not necessarily if it only happens in Debug mode. The structure of a program when compiled to debug is drastically different to a release build. I am so old-fashioned and burned from the days when just adding a program statement could change the behaviour of a buggy program that, however good Erel's coding is, the restructuring makes me unsure and so I very very rarely ever use debug mode but rely almost entirely on Log().
 

Mike1970

Well-Known Member
Licensed User
Longtime User
Post the code of RegistrazioneCompletata

In this days i got working on the project, so i arranged the code diffrently.
However, this was the code (i had a backup):

B4X:
Sub RegistrazioneCompletata As ResumableSub
    hud1.ProgressDialogShow("")
    
    Dim Job As HttpJob
    Job.Initialize("REjob", Me) 'Record Entry
    Dim msg As String
    msg = File.ReadString(File.DirAssets, "RecordEntry.xml")

    Dim cod As String = File.ReadMap(File.DirLibrary & $"/${Main.FileManager1.NomeCartella}"$, "tmpSession.txt").Get("tmpCC")
    Dim lit As String = File.ReadMap(File.DirLibrary & $"/${Main.FileManager1.NomeCartella}"$, "tmpSession.txt").Get("tmpVL")
    
    msg = msg.Replace("$code$", cod)
    msg = msg.Replace("$value$",lit)
    msg = msg.Replace("$recorderid$", Main.FileManager1.LeggiValore(Main.FileManager1.NomeFileSetup, "CO"))
    msg = msg.Replace("$picture$", General.EncodeBase64(File.DirLibrary & "/" & Main.FileManager1.NomeCartella, "cl.jpeg", False))
    Log(msg)
    
    Job.PostString(Main.SERVICEURL, msg)
    Job.GetRequest.SetContentType("application/soap+xml; charset=utf-8")
    Job.GetRequest.Timeout = 120000 '2 minuti
    
    
    Wait For (Job) JobDone(j As HttpJob)
    If j.Success Then
        Dim x2m As Xml2Map
        x2m.Initialize
                
        Dim rootx As Map = x2m.Parse(Job.GetString)
        Dim envelope As Map = rootx.Get("Envelope")
        Dim body As Map = envelope.Get("Body")
        'Log(body)
        
        Dim response As Map = body.Get("RecordEntryResponse")
        Dim daticlienti As String = response.Get("RecordEntryResult")
        'Log(daticlienti)
        
        Dim parser As JSONParser
        parser.Initialize(daticlienti)
        Dim root As Map = parser.NextObject
        Dim resultupload As List = root.Get("RecordEntry")
        'Log(resultupload)
        
        Job.Release
                
        For Each col As Map In resultupload
            If (col.Get("RowID") <> Null) And (col.Get("RowID") <> "-1") Then
                Sleep(100)
                Return col.Get("RowID")
            Else
                Sleep(100)
                Return 4
            End If
        Next
        
    Else
        Sleep(100)
        Return 4
    End If
End Sub
 

emexes

Expert
Licensed User
B4X:
Sub RegistrazioneCompletata As ResumableSub
...       
        For Each col As Map In resultupload
            If (col.Get("RowID") <> Null) And (col.Get("RowID") <> "-1") Then
                Sleep(100)
                Return col.Get("RowID")
            Else
                Sleep(100)
                Return 4
            End If
        Next
...
Are the Sleeps essential ? Don't they "Return" immediately, and the rest of the ResumableSub keep processing also ?
 

Mike1970

Well-Known Member
Licensed User
Longtime User
Are the Sleeps essential ? Don't they "Return" immediately, and the rest of the ResumableSub keep processing also ?
I tried to put the sleep to see if the behaviuor changes. Actually with/or not it make no difference
 

Mike1970

Well-Known Member
Licensed User
Longtime User
My guess is that the problem is here:
Return col.Get("RowID")

It returns a string instead of a number.

Change it to:
B4X:
Dim res As Int = col.Get("RowID")
Return res
Yes I had thought about it, but then i remembered this line:
B4X:
Wait For (RegistrazioneCompletata) Complete (Result As Int)

The Result is casted to Int, and the If statment it's done on that Result variable.. so teorically it should be an Int, not a string. Am I wrong?
 
Top