On 7 August 2018 at 19:47, Ben Coman btc@openinworld.com wrote:
it gets stuck the following loop... https://github.com/bencoman/
opensmalltalk-vm/blob/8231b96f9b/platforms/win32/vm/ sqWin32SpurAlloc.c#L139-L183
whoops, that was meant to be the minheadless file.... https://github.com/bencoman/opensmalltalk-vm/blob/8231b96f9b/platforms/minhe...
In the meantime, I'll forge ahead to play with osvm_run();
I've hardly used Visual Studio before, and never combined with CMake, so I'll record a few things I discover in case others might find it interesting or advise a better way.
To try with the Stack Interpreter first, in CMakeLists.txt changed... option(COG_JIT "Cog JIT" ON) to... option(COG_JIT "Cog JIT" OFF) then cleared the cache... Right-clicked on "CMakeLists.txt > Cache(x64-Debug only) > Delete cache folder..." otherwise it didn't seem to pick up that change.
To give the VM an image to run and something to do... Right-clicked on "CMakeLists.txt > Debug and Launch Settings > pharo.exe" then edited the presented "launch.vs.json" as follows... { "version": "0.2.1", "defaults": {}, "configurations": [ { "type": "default", "project": "CMakeLists.txt", "projectTarget": "pharo.exe (dist\pharo.exe)", "name": "pharo.exe minImage+eval (dist\pharo.exe)", "args": [ "C:\#Dev\latest-minimal-64\Pharo7.0-metacello-64bit-65cff7b.image eval 19 + 23", ] }, ] }
Then... "CMake > Build All" followed by starting... "x64-Debug" with "pharo.exe minImage+eval" which opened a console window that doesn't do much besides output like this... GIV(remapBufferCount) == 0 47923
Now I notice the file "dist\stderr" says... "Your VM is too old for this image. Please download the latest VM." so probably I need to run "scripts\updateSCCSVersions" but thats a shell script. How to run it under Windows?
Luckily my installed Git Windows has Git Bash which opens a cygwin environment. where I do... cd /c/#Repos/OpenSmalltalk/opensmalltalk-vm/ ./scripts/ updateSCCSVersions
Now to give a bit more visibility to program execution, in "spurstack64src/interp.c" I inserted the following into main interpreter loop...
"+" unsigned long long debugCountBytecode = 0; while (1) { "+" debugCountBytecode += 1; "+" if ((debugCountBytecode % 100000 == 0)) "+" { "+" printf("%llu\n", debugCountBytecode); "+" }
Then... "CMake > Build All" followed by starting... "x64-Debug" with "pharo.exe minImage+eval" which opened a console window with the following output... GIV(remapBufferCount) == 0 47923 GIV(remapBufferCount) == 0 42469 100000 200000 300000 400000 500000 600000 700000 800000 900000 1000000 1100000 1200000 1300000 1400000 1500000
and updated contents of these files... yay! dist\stderr ==> #'EvaluateCommandLineHandler successfully finished' dist\stdout ==> 42
However the VM/Image keeps running. Adding "--quit" to the command line didn't help. I'm not really familiar with the command line handlers. Doing... "Debug > Break All" bring me up some warnings like... "winmm.pdb not loaded" "winmm.pdb contains the debug information required to find the source for the module winmm.dll"
Never heard of a PDB, but loaded them by following these instructions... "Specify Symbol (.pdb) and Source Files in the Visual Studio Debugger" https://msdn.microsoft.com/en-us/library/ms241613.aspx and learnt a lot more about them... "PDB Files: What Every Developer Must Know" https://www.wintellect.com/pdb-files-what-every-developer-must-know/ Now the next few times I started... "x64-Debug" with "pharo.exe minImage+eval" it got hung up downloading the symbols. I had to terminate & restart debugging it a few times as it progressed a bit each time.
When finally got running again and after 1500000 printed I did... "Debug > Break All" and... "Debug > Windows > Threads" and now it shows the proper names rather than just addresses...
A little surprised by the number of threads. No clue what ntdll.dll!NtWaitForWorkViaWorkerFactory or winmm.dll!timeThread are, but leave that for later.
Now with all thread stopped, trying... "Debug > Windows > Parallel Stacks"...
shows the two application threads are "in external code" invoked from ioRelinquishProcessorForMicroseconds() and beatThreadStateMachine(). Clicking on each of those displays their source code indicating the "external code" for each is MsgWaitForMultipleObjects() and WaitForSingleObject() respectively .
Its very easy to flip back and forth between the two application threads, stepping-out of the "external code" with Shift-F11, to observe a tiny window of VM operation.
Well thats enough for one post! Success running a MSVC compiled Spur Stack "minheadless" VM.
Next I'll try... option(COG_JIT "Cog JIT" ON)
cheers -ben
P.S. Definitions for the curious...
sqInt ioRelinquishProcessorForMicroseconds(sqInt microSeconds) { /* wake us up if something happens */ ResetEvent(vmWakeUpEvent); MsgWaitForMultipleObjects(1, &vmWakeUpEvent, FALSE, microSeconds / 1000, QS_ALLINPUT); ioProcessEvents(); /* keep up with mouse moves etc. */ return microSeconds; }
static DWORD WINAPI beatThreadStateMachine(void *careLess) { beatThreadState = active; while (beatThreadState != condemned) { DWORD res = WaitForSingleObject(beatSemaphore, beatThreadState == active ? beatMilliseconds : INFINITE); if (res == WAIT_TIMEOUT) heartbeat(); else if (res == WAIT_FAILED) abortMessage(TEXT("Fatal: WaitForSingleObject(beatSemaphore) %ld"), GetLastError()); else printLastError(TEXT("beatThreadStateMachine WaitForSingleObject")); } beatThreadState = dead; return 0; }