Incus J 10 Posted September 9, 2020 (edited) That sounds good. I've just tested the latest overnight zip, and D104InstallVclFmx builds successfully for macOS 64-bit. The sample app IcsHttpsTst builds successfully by adding the Ics.Fmx. prefix to a few IcsHttpTst1.pas uses units. When the sample app deploys and runs on macOS 64-bit I get an ERangeError "Range check error" at runtime. I think it occurs in Ics.Posix.Messages.pas but the IDE debugger can't find that unit, so I'm not sure. I must need to tell the IDE/Debugger the path to the ICS source units so it can step into them - but I'm not sure how to do this. The Delphi compiler already knows where the source units are, because the app builds and deploys OK, but the IDE itself seems unaware at the moment. Edited September 9, 2020 by Incus J Share this post Link to post
Angus Robertson 574 Posted September 9, 2020 Pleased you got the package built, I've put updating the sample uses sections on my list. Sorry, never tried debugging a non-windows platform. I have been wondering why ICS is using a lot of MacOS specific libraries to emulate Windows messages, when the FMX forms unit seems to have ProcessMessages which one assumes works similarly to the Windows forms unit, it might be early versions of FMX 10 years ago were more limited. But I have other delayed projects to finish and can not investigate yet. Angus Share this post Link to post
Incus J 10 Posted September 9, 2020 I remember back in Delphi 10.2 Tokyo FMX ProcessMessages seemed to behave differently to VCL ProcessMessages. With VCL I can call ProcessMessages and any queued mouse clicks are processed. With FMX I found that a call to ProcessMessages did not process queued mouse clicks. It was as though FMX UI events were handled separately. I don't know whether this is still the case. Share this post Link to post
Angus Robertson 574 Posted September 9, 2020 On a Windows form the entire application runs from ProcessMessages, if that is not the case with FMX then I guess it's a different design concept. Angus Share this post Link to post
Incus J 10 Posted September 9, 2020 (edited) I think FMX renders its UI to a surface/canvas, rather than having the OS render the controls (?) - so yes, it could be different. This is where the IcsHttpsTst seems to get stuck at startup: Line 1962 of Ics.Posix.Messages function TMultiReadExclusiveWriteSynchronizer.BeginWrite: Boolean; var Thread: PThreadInfo; HasReadLock: Boolean; ThreadID: Cardinal; Test: Integer; OldRevisionLevel: Cardinal; begin ... ThreadID := GetCurrentThreadID; The top of the call stack looks like this : :000000010001D0F0 System::_DbgExcNotify(int, void*, System::SmallString<(unsigned char)255>*, void*, void*) :000000010001D12E System::NotifyReRaise(System::TObject*, void*) :000000010001D1CA System::_RaiseAtExcept(System::TObject*, void*) :0000000100056AB8 System::Sysutils::ErrorHandler(unsigned char, void*) :0000000100015F30 System::ErrorAt(unsigned char, void*) :000000010001B252 System::_BoundErr() Ics.Posix.Messages.TMultiReadExclusiveWriteSynchronizer.BeginWrite()(0x0000000102521120) Ics.Posix.Messages.TIcsMessagePump.AfterConstruction()(0x000000020245bd80) :0000000100016B45 System::_AfterConstruction(System::TObject*) :0000000100011443 System::TObject::TObject() Ics.Fmx.Overbyteicswndcontrol.TIcsWndControl.AllocateHWnd()(0x0000000203080ff0) Ics.Fmx.Overbyteicshttpprot.THttpCli.THttpCli(System.Classes.TComponent*)(0x0000000203080ff0,true,0x000000020801e5f0) ... Maybe that contains useful information. On Posix, the System unit defines: TThreadID = NativeUInt; But local var ThreadID is Cardinal. Maybe Cardinal and NativeUInt are not compatible. If I redefine ThreadID as a NativeUInt too, then the ERangeError disappears, and the app is "[Running]" - but the UI does not appear. I think Thread #1 might be waiting for something. Edited September 9, 2020 by Incus J Share this post Link to post
Angus Robertson 574 Posted September 9, 2020 ThreadID: Cardinal; should really be ThreadID: TThreadID; to match all other use in the unit. Perhaps there is another mismatch somewhere that has caused truncation or something? Angus Share this post Link to post
Fr0sT.Brutal 900 Posted September 10, 2020 20 hours ago, Angus Robertson said: I have been wondering why ICS is using a lot of MacOS specific libraries to emulate Windows messages, when the FMX forms unit seems to have ProcessMessages which one assumes works similarly to the Windows forms unit, it might be early versions of FMX 10 years ago were more limited. But I have other delayed projects to finish and can not investigate yet. Could FMX message queue be used in console applications? Share this post Link to post
Angus Robertson 574 Posted September 10, 2020 ICS Windows console applications need a message pump anyway, and are relatively rare. I only have a single console application that sends emails when SVN is updated. An old version of ICS supported Kylix with a message pump which we could bring up to date, but if FMX supports this already, that is faster. Angus Share this post Link to post
Fr0sT.Brutal 900 Posted September 10, 2020 6 hours ago, Angus Robertson said: ICS Windows console applications need a message pump anyway, and are relatively rare. I only have a single console application that sends emails when SVN is updated. Well, I have several 24/7 network apps that I'd make console or service if I were starting them now. And as we're slowly moving to Linux, it's very common for it to have no GUI at all on servers Share this post Link to post
Angus Robertson 574 Posted September 10, 2020 Quote it's very common for it to have no GUI at all on servers Quite true, I use ICS in several Windows services. However all windows services need a message loop, that is how they are stopped and controlled. Obviously not the case with Linux. Angus Share this post Link to post
gyk 0 Posted September 13, 2020 (edited) I had to port only the TCP part of the ICS to OSX64 and I identified what the translation of the kevent and probably of the kevent_64 structures is inaccurate: the uint32_t, the data type of the fflags field should be not LongWord, but Cardinal. And the {$A4} directive should be removed for the kevent record. This way it works on both OSX32 and OSX64. I tried with Delphi 10.3.3. Edited September 13, 2020 by gyk Share this post Link to post
Angus Robertson 574 Posted September 14, 2020 Thanks for joining this thread and helping to get ICS working on MacOs64. I've updated Ics.Posix.KEventTypes,pas with your fixes, but am wondering whether I should also be changing WSocket to use EV_SET64 and TKEvent64 instead of EV_SET in TIcsEventQueue? Or does MacOS64 support both. Not in SVN yet. I don't believe there is much point in trying to retain MacOS32 compatibility going since 10.4 no longer supports it. Regarding your off-list comment about TMultiReadExclusiveWriteSynchronizer and ThreadID, I did change this to ThreadID: TThreadID; last week to match all other instances. Please be aware I can now build for Linux64 but not for MacOS since don't have any Apple hardware, so I can catch general Posix compiler issues, but not Mac only issues. And the Linux message handler is not done yet. Angus Share this post Link to post
gyk 0 Posted September 14, 2020 (edited) 51 minutes ago, Angus Robertson said: Thanks for joining this thread and helping to get ICS working on MacOs64. I've updated Ics.Posix.KEventTypes,pas with your fixes, but am wondering whether I should also be changing WSocket to use EV_SET64 and TKEvent64 instead of EV_SET in TIcsEventQueue? Or does MacOS64 support both. Not in SVN yet. I don't believe there is much point in trying to retain MacOS32 compatibility going since 10.4 no longer supports it. Regarding your off-list comment about TMultiReadExclusiveWriteSynchronizer and ThreadID, I did change this to ThreadID: TThreadID; last week to match all other instances. Please be aware I can now build for Linux64 but not for MacOS since don't have any Apple hardware, so I can catch general Posix compiler issues, but not Mac only issues. And the Linux message handler is not done yet. Angus kevent is usable on MacOS64 as well. It confused me as well but as I understood later the benefit of kevent_64 what it can hold some additional data So I think you don't have to switch to kevent_64. Btw technically you can run MacOs in the WmVare player 15 free edition on Widows host if you have enough RAM. in your PC. György Edited September 14, 2020 by gyk Share this post Link to post
Angus Robertson 574 Posted September 14, 2020 These MacOS changes are now in SVN and will be zipped overnight. Angus 1 Share this post Link to post
Incus J 10 Posted September 25, 2020 The latest overnight zip looks good. I can get both IcsHttpsTst and also my own app to Build successfully for macOS 64-bit (but not run successfully at present). IcsHttpsTst hangs when it starts up (the main form is never displayed). My own app runs OK, and is functional until it tries to use ICS - at which point it hangs too. Both apps are actually still running, but seem stuck in an infinite loop. If I select Program Pause from the IDE, a CPU tab appears filled with assembly language, showing the current execution point in Thread #1. I can perform commands such as Run Until Return. Thread #1 -> 00007FFF6E68AE36 C3 ret 00007FFF6E68AE37 90 nop 00007FFF6E68AE38 4989CA mov r10, rcx 00007FFF6E68AE3B B825000001 mov eax, 0x1000025 00007FFF6E68AE40 0F05 syscall 00007FFF6E68AE42 C3 ret 00007FFF6E68AE43 90 nop 00007FFF6E68AE44 4989CA mov r10, rcx 00007FFF6E68AE47 B826000001 mov eax, 0x1000026 00007FFF6E68AE4C 0F05 syscall Is there a 'Run Until Inside A Delphi Unit' command somewhere? Share this post Link to post
Lars Fosdal 1792 Posted September 25, 2020 Shift-F7 - Trace to Next Source Line Share this post Link to post
Incus J 10 Posted September 25, 2020 Thank you Lars - I wasn't sure as Trace to Next Source Line just hangs again - so it must never reach a Delphi Source Line to stop at. Which makes sense if it is stuck in an infinite loop somewhere - I guess that means it's getting stuck in the system somewhere outside of Delphi code. Share this post Link to post
Incus J 10 Posted September 25, 2020 (edited) I've had a go at stepping through code from my app. It's a bit tricky because the units such as Ics.Fmx.OverbyteIcsWndControl contain no actual code, just an include {$I OverbyteIcsWndControl.pas}, which the Debugger isn't pulling in, so I don't get to see the lines of code I Trace Into or Step Over in the IDE. It is stepping though, because the call stack changes when I press F7, and I occasionally step into the System unit. Shortly before the hang, the call stack looks like this : Ics.Fmx.Overbyteicshttpprot.THttpCli.SetTerminated(bool)(0x0000000203a33170,false) Ics.Fmx.Overbyteicswndcontrol.TIcsWndControl.TIcsWndControl(System.Classes.TComponent*)(0x0000000203a33170,false,0x000000020bd3b640) Ics.Fmx.Overbyteicshttpprot.THttpCli.THttpCli(System.Classes.TComponent*)(0x0000000203a33170,true,0x000000020bd3b640) And the hang occurs after/when the System unit executes : constructor TObject.Create; begin end; Oh, here we go - this looks more useful : :00007FFF6E68AE36 semaphore_wait_trap :00007FFF6E4F0AED _dispatch_sema4_wait :00007FFF6E4F0FBF _dispatch_semaphore_wait_slow System.Syncobjs.TEvent.WaitNoReset(unsigned int)(0x0000000205815ff0,4294967295) System.Syncobjs.TEvent.WaitFor(unsigned int)(0x0000000205815ff0,4294967295) Ics.Posix.Messages.TMultiReadExclusiveWriteSynchronizer.WaitForWriteSignal()(0x0000000105809620) Ics.Posix.Messages.TMultiReadExclusiveWriteSynchronizer.BeginWrite()(0x0000000105809620) Ics.Posix.Messages.TIcsMessagePump.AfterConstruction()(0x000000020beeb1b0) System._AfterConstruction(System.TObject*)(0x000000010bed9a40) System.TObject.TObject()(0x000000010bed9a40,true) Ics.Fmx.Overbyteicswndcontrol.TIcsWndControl.AllocateHWnd()(0x0000000203a33170) Ics.Fmx.Overbyteicshttpprot.THttpCli.THttpCli(System.Classes.TComponent*)(0x0000000203a33170,true,0x000000020bd3b640) So the app hangs at semaphore_wait_trap. Not sure what that is yet, but there is a Thread #7 labelled : TIcsAsyncSocketThread (7) with the following Call Stack kevent Ics.Fmx.Overbyteicswsocket.TIcsEventQueue.HandleEvents() Ics.Fmx.Overbyteicswsocket.TIcsAsyncSocketThread.Execute() System.Classes.ThreadProc(System.Classes.TThread*) System.ThreadWrapper(void*) _pthread_start thread_start Could Thread #1 be waiting for Thread #7 to complete or sync? Other threads do exist (4, 10, 14, 19) but are all unlabelled. Edited September 25, 2020 by Incus J Share this post Link to post
Lars Fosdal 1792 Posted September 28, 2020 On 9/25/2020 at 3:21 PM, Incus J said: Thank you Lars - I wasn't sure as Trace to Next Source Line just hangs again - so it must never reach a Delphi Source Line to stop at. Which makes sense if it is stuck in an infinite loop somewhere - I guess that means it's getting stuck in the system somewhere outside of Delphi code. It quite often doesn't work. I blame the debugger. One thing that helps a little, is to make sure that you switch the active thread to the one where you expect the break - but it is no guarantee. Share this post Link to post
Incus J 10 Posted September 30, 2020 Thanks Lars. I had no luck switching thread, but found the routine mentioned in the call stack manually. It is useful that the code gives the thread a label in Debug mode. I've set a Breakpoint prior to the hang so I can step through the code and see what parameters are being passed in. Unfortunately Breakpoints don't seem to be working in this unit. Breakpoints look to be set OK at design time, but become unavailable (X) at runtime, so the program runs past. Share this post Link to post