I’ve found that calling FolderItem.TrueItemsMBS in a preemptive thread can produce weird behaviours concerning debugging.
In my case, I’m using TrueItemsMBS for a folder on a remote server. That folder has a lot of items inside it.
After TrueItemsMBS has been called, breakpoints are ignored, stepping won’t work and pausing is also odd (e.g. the thread won’t appear in the list).
Another attempt: putting a breakpoint right at the TrueItemsMBS line, the debugger correctly breaks, then I use “Step over” and either of these happens:
1: if the call returns immediately (few files or fast file system), debugging stays reliable and the next line is executed.
2: if the call takes more than a few seconds, the IDE goes to the “no code view” and the weird behaviours described above apply.
At this stage, I don’t know whether this behaviour is specific to the TrueItemsMBS/TrueFilesMBS/TrueFoldersMBS calls or if any method which takes time in the framework would cause this too. If the former, I’d ask Christian to take a look at these functions (are they perhaps not thread-safe?); if the latter, it’d call it a bug in the framework and fill a bug report.
I currently have no idea to test quickly using other functions, so I thought discussing about it could be a good idea.
Here’s one. The project is rather straightforward, but the condition is to have a huge folder on a network share. In my setup, it’s a folder on a NAS share (SMB protocol) which contains 11’521 files. The bug I’m seeing appears when the duration to enumerate the files is more than around 2 seconds.
Just replace the folder path in the beginning of the thread in code (a #pragma error line is there for quick access).
You may see that the label updates and breakpoints work before TrueItemsMBS is called, but not after that.
As a detail, please keep in mind that it’s a very simplified version of my working project and there could be unexpected/not cleaned parts remaining (although I don’t think there is actually).
I tried with Xojo folderitems, which is really slow:
if Folder<>nil then
if PDLGCallback<>nil then PDLGCallback.Invoke ENCallbackReason.Started,Folder
for i as Integer=0 to Folder.Count - 1
Var Item As FolderItem=folder.ChildAt(i)
if Item=nil or Item.IsFolder then Continue
if PDLGCallback<>nil then PDLGCallback.Invoke ENCallbackReason.FileCollected,Item
Result.Add Item
next
end if
Agreed. I’m hoping this thread could help Xojo improve them (if we can pinpoint the issues).
Interesting result…
Did TrueItemsMBS take a while in your case? (i.e. if you step over TrueItemsMBS, the IDE temporarily clears out the code view and continues after a few seconds).
I was getting the same thing once, when I tried quitting the app while the thread was running (thus the thread was nil). In your case, I can’t see what would be nil.
Accustomed to that, hence the reason I started with the MBS way directly. Of course, if TrueItemsMBS can fail (which is yet to be proven), better a slow method than no method at all.
My original project handles recursion. When I stripped it down to post it here, I made it simple for anyone giving a try. I didn’t want to bother with a more complex project where issues could be more random to reproduce.
Would it add something for you if I post the actual project?
Thanks; I’ll try as soon as possible.
As Beatrix says, speed is the visible part of the iceberg.
In my observations, when the call is nearly instant, I don’t see the main bug I’m describing. If TrueItemsMBS is faster, I bet it’ll handle the problem better, but one could still have a situation where it takes time to complete and the problem remains.
I’m starting to wonder if these issues are related to functions yielding .
I tried with the new version and (1) the call was faster and (2) the weird debugger issues I had seem to have vanished (but I tried only once). It looks like your fix made effect for more than speed only.
Would be interesting if you could try as well, Beatrix.
I thought the bomb was designed to occur when some exceptions happen, that were not caught in earlier Xojo versions (like SegFaults and BadAccess exceptions, where the app would previously just crash), regardless of the thread it’s happening on (main, cooperative or preemptive)
The bomb is displayed when the app is about to crash and the debugger is able to somewhat pause the app to show the current state.
This can happen in a pre-emptive thread but also on the main thread.