Closed ecosSystem closed 11 months ago
Karl, did you get a callstack showing where the problem happened? I guess not inside the DoEvents() function itself, since this does not use an object that could be null.
Hi Chris,
It's a bit tricky to reproduce the problem, but I could create an example (attached solution). Problem occurs on OK-Button in About-Dialog. If you uncomment the DoEvents-Function, all is working.
Here is the errormessage:
Description : Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
Subsystem : Anonymously Hosted DynamicMethods Assembly
GenCode : EG_EXCEPTION Exception raised by CLR or external code
FuncSym : OOPHELPERS:SENDHELPER
Severity : ES_ERROR
Can Default : False
Can Retry : False
Can Substitute : False
Stack Trace :
{||DOEVENTS()} (Line: 0)
MACROCODEBLOCK:EVAL (Line: 0)
HELPABOUT:PUSHBUTTON1 (Line: 85)
OOPHELPERS:SENDHELPER (Line: 0)
OOPHELPERS:DOSEND (Line: 0)
SEND (Line: 0)
WINDOW:COMMANDFROMEVENT (Line: 0)
WINDOW:DISPATCH (Line: 0)
WCDIALOGPROC (Line: 0)
CALLWINDOWPROC (Line: 0)
WCCONTROLPROC (Line: 0)
ISDIALOGMESSAGE (Line: 0)
APP:EXEC (Line: 0)
DIALOGWINDOW:EXECMODAL (Line: 0)
DIALOGWINDOW:SHOWMODAL (Line: 0)
DIALOGWINDOW:SHOW (Line: 0)
RUNTIMEMETHODHANDLE:INVOKEMETHOD (Line: 0)
RUNTIMEMETHODINFO:UNSAFEINVOKEINTERNAL (Line: 0)
RUNTIMEMETHODINFO:INVOKE (Line: 0)
OOPHELPERS:SENDHELPER (Line: 0)
OOPHELPERS:SENDHELPER (Line: 0)
OOPHELPERS:DOSEND (Line: 0)
WINDOW:COMMANDFROMEVENT (Line: 0)
WINDOW:PREMENUCOMMAND (Line: 0)
WINDOW:DISPATCH (Line: 0)
APPWINDOW:DISPATCH (Line: 0)
SHELLWINDOW:DISPATCH (Line: 0)
WCSHELLWNDPROC (Line: 0)
DISPATCHMESSAGE (Line: 0)
APP:EXEC (Line: 0)
XAPP:START (Line: 19)
START (Line: 2)
VOMDIApp1.zip
Ah thanks, so the problem happens only when calling DoEvents() from the macro compiler. Or does it happen in regular code for you, too?
What I see here, is that the above runtime exception happens when trying to execute a macro with DoEvents() from inside a VOGUI application, as a response to a button click, like that:
METHOD PushButton1()
MExec(MCompile("DoEvents()")) // crash on MExec()
when executing the same macro as a direct response to a menu command, then the exception does not happen. Also when defining the function locally (even with the exact same code), the problem again does not happen, Karl I think that's the reason why you do not get the problem anymore with your redefined function.
It also happens in regular code but that is not so easy to show... I noticed it when printing a report in ReportPro. We have integrated RP into our application and it crashes in the StartPrint-method of PtrDevice. (integrating the original VO-Function into the RP-Runtime also solves the problem). Integrating the Doevents-function with the x#-version doesn't solve the problem for me. Problem seems to be msg as xMessage [DllImport("User32.dll", CharSet := CharSet.Ansi)]; PRIVATE STATIC METHOD PeekMessage(msg REF xMessage, hwnd as HandleRef, msgMin as INT, msgMax as INT, iremove as Int) AS LOGIC
PARTIAL CLASS PtrDevice IMPLEMENTS IPtrDevice
METHOD StartPrint() AS VOID STRICT
// This method is called from the print message window to allow start the printing process // This approach allows the print message window to be modal
LOCAL lResult,lFromPreview AS LOGIC // LOCAL dAbort AS _AbortProc32Delegate // MAY per 22.09.2011: Delegate darf nur Klassenvar. sein! LOCAL pAbort AS IntPtr IF SELF:nBusy > 0 RETURN ENDIF lResult:=TRUE // result of print to file dialog, if req
IF SELF:Print2File .AND. SELF:PromptForFile // prompt for the print file name if req SELF:cFileName := GetPrintFileName(SELF:oPrintWin:Handle(0),rpLangString(IDL_PRINT_FILE_NAME),"",SELF:cFileName,rpLangString(IDL_PRINT_FILES),rpLangString(IDL_ALL_PRINT_FILES)) lResult :=!Empty(SELF:cFileName) ENDIF IF lResult lFromPreview :=SELF:lInPreview // save if we came from preview SELF:lInPreview :=FALSE // reset the print preview flag SELF:lInPrint :=TRUE // set the print in progress flag SELF:nPageNo :=0 // initialize page numbers SELF:nNextPageNo :=1 SELF:nLastPageNo :=MAX_PAGE_COUNT SELF:nTotalPages := 0
DoEvents() // give windows some time slices
// start the printing process
IF !Empty(SELF:hDC:=SELF:CreatePrinterDC()) // create printer device context
SELF:hPrinterDC:=SELF:hDC // set the WYSIWYG DC for compatibility
SELF:InitPrintDeviceContext() // setup the device context...
// note if we came from preview, we
// don't have to call print start
IF (lFromPreview .OR. SELF:CallPrintStart()==PRINT_OK) .AND. !SELF:Quit
// set the printing abort proc
SELF:dAbort := _AbortProc32Delegate{ NULL, @_AbortProc32() }
pAbort := Marshal.GetFunctionPointerForDelegate( SELF:dAbort )
SetAbortProc(SELF:hDC,pAbort)
IF SELF:StartDoc() // start the windows print manager
IF SELF:lSupport1ofN // If we need to support the Page 1 of N, goto end of report
SELF:oPrintWin:SetPageNo(-1)
IF !SELF:_DetermineLastPage()
SELF:_AbortDoc()
SELF:QuitPrint()
RETURN // SELF
ENDIF
SELF:oPrintWin:SetRange(SELF:nTotalPages)
ENDIF
IF SELF:_CollectPrintPages() // print the report
SELF:EndDoc() // if we were sucessful close the job
ELSE
SELF:_AbortDoc() // else abort it
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF SELF:QuitPrint() RETURN // SELF
Hope this helps
Karl
OK, but if there was a general problem with the DoEvents() call in StartPrint(), then almost everybody using RP2 should be having problems, but I cannot recall any other similar report. I suspect that the underlying problem is still the one with the macrocompiler, maybe a previous macro compilation did some harm (like corrupted memory or similar) and that surfaced later when printing. Let's see if fixing the problem in the macro compiler will take care of this as well.
Might be just a problem with the macro compiler but maybe most others use RP as a standalone Application and do integrate the RP-Designer directly. Perhaps this might cause the problem. I'll check that as soon as you have fixed the macro-bug :)
Ah, you have integrated the designer, did not realize that before. Maybe you can try if you can reproduce the problem in a small test app integrating the designer in a similar way as in your real system?
Chris, Robert has converted a smaller part of our application to x# last year. I could send you this project via private mail. The problem is reproducable with it.
Yes, please do Karl!
Did you get the project ?
Karl, I think I have found something. Can you add a reference to XSharp.VFP to your project ? Do you still see the problem ?
Robert, same behaviour with the standard VOGUI-app and immediate crash in my test app:
Ok, thanks. I will look further.
Karl, yes I got it. Sorry I did not get back to you yet, I had trouble compiling it due to some change in the compiler. Will look further into it tomorrow and will get back to you.
Guys, unfortunately I could not get the app to run, I am getting runtime errors with ADS. Robert, since you helped converting this app, do you still have it, so you can reproduce the problem?
But the code really helps in investigating the other problem with passing values by references. And I would not be surprised if that has to do with the current problem as well...
Chris, I think the problem with the values by reference is solved with 2.9a. What kind of runtime errors do you get ? Are any ADS-files missing ?
Karl, there are still some "hidden" issues, as you can see in the discussion for https://github.com/X-Sharp/XSharpPublic/issues/810 One of the revealad problems is that your code in line 1041 of System-Masterabgleich.prg:
Send(SELF,sMethod,cVermNr,cTmpOrdner,@nSatz,nGesamt,nStep)
does not actually pass nSatz by reference, instead it passes a pointer to this var.Our current internal compiler reports an error on this code.
About running your app, I am getting an exception:
Managed Debugging Assistant 'LoaderLock' : 'Attempting managed execution inside OS Loader lock. Do not attempt to run managed code inside a DllMain or image initialization function since doing so can cause the application to hang.'
in the code
DBFAXSAdsIsServerLoaded ( String2Psz( cFileName ), @usLoaded )
which now I looking into it more closely, also has to do with values by reference! Will further investigate..
In #810 you wrote: this looks a lot like the DoEvents()-problem with the first parameter to PeekMessage...
Karl, Not sure about that, since this is relatively straightforward, a structure passed by reference, while the errors posted in this ticket are more complicated. But you never know..
For sure we have a reproducible problem with DoEvents() in the macro compiler for starters. Let's see if fixing that one fixes the rest as well.
Karl,
The problems in the DoEvents() code is certainly something different than the #810, That ticket is about how the compiler treats the @
operator, And the DoEvents() in the terminal code uses the REF modifier to pass the arguments and not the @
operator
I have changed DoEvents() to no longer use a HandleRef but an IntPtr. That way the code looks more like the VO implementation.
Hi Robert,
I did some more testing with Doevents() The following code produces an error in bBlock:Eval():
METHOD PushButton1() LOCAL bBlock AS _CODEBLOCK doevents() infobox{SELF,"","Start"}:Show() bBlock := &( "{||DoEvents()}" ) bBlock:Eval() infobox{SELF,"","Ok"}:Show() return self
Description : Exception raised by CLR or external code: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
Subsystem : Anonymously Hosted DynamicMethods Assembly
GenCode : EG_NULLVAR Variable not initialized
FuncSym : ERROR.WRAPRAWEXCEPTION
Severity : ES_ERROR
Can Default : False
Can Retry : False
Can Substitute : False
Stack Trace :
{||DOEVENTS()} (Line: 0)
MACROCODEBLOCK:EVAL (Line: 0)
HELPABOUT:PUSHBUTTON1 (Line: 95)
...
I don't think the problem is the HandleRef, I think there is a problem in
PRIVATE STRUCT xMessage PRIVATE hWnd AS IntPtr PRIVATE msg AS LONG PRIVATE wParam as IntPtr PRIVATE lParam as IntPtr PRIVATE result as IntPtr END STRUCT
In VO the _winMSG-structure is:
STRUCTURE _winMSG MEMBER hwnd AS PTR MEMBER message AS DWORD MEMBER wParam AS DWORD MEMBER lParam AS LONG MEMBER time AS DWORD MEMBER pt IS _winPOINT
If I enhance the xMessage-STRUCT to
PRIVATE STRUCT xMessage PRIVATE hWnd AS IntPtr PRIVATE msg AS LONG PRIVATE wParam AS IntPtr PRIVATE lParam AS IntPtr PRIVATE result AS IntPtr PRIVATE pt IS _winPOINT END STRUCT
no error occurs. (However I am not sure whether IS _winPoint is really correct here...)
In addition in _winMSG.PRG where the _winMSG-struct is defined in xSharp I found
PUBLIC SEALED STRUCTURE VO._winMSG INHERIT System.ValueType
PUBLIC hwnd AS PTR PUBLIC lParam AS INT PUBLIC message AS DWORD PUBLIC pt AS VO._winPOINT PUBLIC time AS DWORD PUBLIC wParam AS DWORD
END STRUCTURE
Is this correct ? The members seem to be in a wrong order, they are ordered alphabetically
Karl
Karl, We have changed HandleRef to an IntPtr for the next build. See commit https://github.com/X-Sharp/XSharpPublic/commit/1ab2a525298b3aa288155195735880f0a830818b
Robert, as I mentioned above, I don't think the Handleref is the problem but the xMessage struct...
Robert, this additional fix seems to solve it! No more crashes...
Also from me confirmed fixed
In Terminal.PRG exists the function DoEvents():
FUNCTION DoEvents() AS VOID UnSafeNativeMethods.DoEvents()
INTERNAL CLASS UnSafeNativeMethods STATIC METHOD DoEvents() AS VOID local msg as xMessage local handle as HandleRef msg := xMessage{} handle := HandleRef{} DO WHILE UnSafeNativeMethods.PeekMessage( REF msg,handle, 0,0, PM_NOREMOVE) IF UnSafeNativeMethods.GetMessage( REF msg, handle,0,0 ) UnSafeNativeMethods.TranslateMessage(REF msg) UnSafeNativeMethods.DispatchMessage(REF msg) ENDIF ENDDO RETURN
In VO this function was defined like this:
FUNCTION DoEvents() LOCAL msg IS _WINMSG WHILE(PeekMessage(@msg,0, 0,0, PM_NOREMOVE)) IF GetMessage(@msg, 0,0,0 ) TranslateMessage(@msg) DispatchMessage(@msg) ENDIF ENDDO
RETURN NIL
ReportPro (and our Application) uses Doevents() a lot which creates a crash:
Der folgende Fehler ist aufgetreten während der Bewegung auf den ersten logischen Satz.: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
If I insert the VO-Function into ReportPro-source and our Application-source everything works as before.