Juce - setLookAndFeel - error - xcode

I work with Projucer (Juce v5.2.0) and xCode 9.2 and I have some strange error when I use setLookAndFeel on Slider.
I go step by step with that tutorial:
https://www.youtube.com/watch?v=po46y8UKPOY&t=1020s
And I make exactly the same code. On the video there is no problem. My error appear when I compile the same code as it's in the 17:13 duration of the movie.
My problem is: when I compile the code everything is OK, my compiled app works great, "setLookAndFeel" works as expect. But the problem is when I close app. Then app looks like closed, but the icon is on the dock, and xCode shows "Stop" button active, so it looks like my app still works in some way. And xCode takes me automatically to something called "Juce Massage Thread (1)" and there is error:
Juce Message Thread (1): EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0
It's next to that code:
jassert (masterReference.getNumActiveWeakReferences() == 0
|| (masterReference.getNumActiveWeakReferences() == 1
&& this == &getDefaultLookAndFeel()));
Could anyone help me?
Thanks in advance.

There's a large comment block above the assertion that you've hit explaining why you have hit it:
/* This assertion is triggered if you try to delete a LookAndFeel object while something
is still using it!
Reasons may be:
- it's still being used as the default LookAndFeel; or
- it's set as a Component's current lookandfeel; or
- there's a WeakReference to it somewhere else in your code
Generally the fix for this will be to make sure you call
Component::setLookandFeel (nullptr) on any components that were still using
it before you delete it, or call LookAndFeel::setDefaultLookAndFeel (nullptr)
if you had set it up to be the default one. This assertion can also be avoided by
declaring your LookAndFeel object before any of the Components that use it as
the LookAndFeel will be destroyed before the Components.
Deleting a LookAndFeel is unlikely to cause a crash since most things will use a
safe WeakReference to it, but it could cause some unexpected graphical behaviour,
so it's advisable to clear up any references before destroying them!
*/
So you need to call setLookAndFeel (nullptr) on your slider before it is deleted, probably in the destructor of its parent component.

Related

VFP Database contention issue

I have a very large VFP app. I use the VFE framework. My app uses the native VFP database. App is 20 years old and grows daily. For 10 years I very intermittently get crashes. It can occur multiples times in same day. It may not occur for a week or 2 and then twice in a single day. I have 20+ customer sites with anywhere from 5 to 30 users concurrently per site. The busier the site, the more often the crashes. I have always thought it was due to the VFP DBC contention issue but have never proven. Over past 10+ years I have tried many times to resolve but have never been able to do so. I'm ready to try again. I have a DBC that has approx 125 tables. All views are in a separate "views" DBC that contains about 1500 views.
I receive a 1925 error "unknown member PARAMETERS" when the crashes occur. I will gladly supply a lot more info but first I would like to just get a better understanding of the locking/contention issue with my views database. Can someone please help me understand exactly what that issue is?
This is the code where the error is occurring. This can occur in several other places but this is probably the simplest example:
I have multiple apps. I have an app that is used as the user interface. That is the app my users are using all day every day. The error we are discussing never occurs in that app. I have an app that is used to do "background stuff". It has no user interface and I will not say this exactly right but it is a "COM object" meaning it is OLE Public. I call this program ITFCOM001. It is an EXE. ITFCOM001.EXE is where these errors ALWAYS occur. ITFCOM001 is basically a "endless loop" program that does things like imports from vendors, exports to vendors, generating reports data, etc. Both my user interface app and ITFCOM001 make use of the same tables DBC and views DBC.
The errors occur when ITFCOM001 goes to do something like a vendor export.
Code from ITFCOM001 where the error occurs:
lojpayexportsbo=CREATEOBJECT("v_jpayexportsbizobj")
&& 11/13/2017 - add cd to try stop com001 crashes
IF NOT VARTYPE(lojpayexportsbo)='O'
lojpayexportsbo = NULL
RELEASE lojpayexportsbo
RETURN .f.
ENDIF
lojpayexportsbo.setparameter("vp_ctransfer_acct_id",tctransfer_acct_id)
lojpayexportsbo.requery()
lnretval=lojpayexportsbo.navigate("FIRST")
&& 11/30/2017 added lnretval= to above statement and then checking to ensure = FILE_OK below here
IF NOT lnretval>=-7
IF VARTYPE(lojpayexportsbo)="O"
lojpayexportsbo.release()
ENDIF
lojpayexportsbo = NULL
RELEASE lojpayexportsbo
RETURN .f.
ENDIF
lojpayexportsrec=lojpayexportsbo.getvalues()
In the above code, the setparameter is where the error is occurring.
Looking at the VFE class libraries The error is actually occurring on line 41 of the FindViewParameter method.
*==============================================================================
* Method: FindViewParameter
* Purpose: Finds the Parameter object associated with the passed
* view parameter name.
* Author: F1 Technologies
* Parameters: tcParameterName, The name of the view parameter.
* Returns: Object, The Parameter object.
* Modifications:
* 12/03/1999 Initialized loParameter to .NULL.
*==============================================================================
LPARAMETERS ;
tcParameter
LOCAL ;
loParameter, ;
loCursor, ;
lcCursor, ;
lcParameter
loParameter = .NULL.
WITH This
IF "." $ tcParameter
lcParameter = TRIM(SUBSTR(tcParameter, AT(".", tcParameter) + 1))
lcCursor = LEFT(tcParameter,AT(".", tcParameter) - 1)
ELSE
lcParameter = tcParameter
lcCursor = ""
ENDIF
IF "!" $ lcCursor
lcCursor = SUBSTR(lcCursor,AT("!", lcCursor) + 1)
ENDIF
IF NOT EMPTY(lcCursor)
loCursor = .FindCursor(lcCursor)
ELSE
loCursor = .oCursor
ENDIF
IF VARTYPE(loCursor) = T_OBJECT
loParameter = loCursor.Parameters.Item(lcParameter)
ENDIF
* If the view parameter could not be found in the business object, check
* its parent.
IF VARTYPE(loParameter) <> T_OBJECT AND VARTYPE(.oParentBizObj) = T_OBJECT
loParameter = .oParentBizObj.FindViewParameter(tcParameter)
ENDIF
ENDWITH
RETURN loParameter
line 41 is "loParameter = loCursor.Parameters.Item(lcParameter)"
This is the value from error logging. This is the call stack:
0000KF7T0193
ITFCOM001APPLICATIONOBJECT.INIT
ITFCOM001APPLICATIONOBJECT.INIT_POST
ITFCOM001APPLICATIONOBJECT.EXPORTTOEDV
V_JPAYEXPORTSBIZOBJ.SETPARAMETER
V_JPAYEXPORTSBIZOBJ.FINDVIEWPARAMETER
V_JPAYEXPORTSBIZOBJ.ERROR
I should probably add one more thing: The code shown above executes every 15 minutes 24/7 on all my customer sites. The error/crashes only occur very intermittently across all sites.
Stefan, I have never used ASSERTS but I did look it up in VFP help. Use of ASSERTS will not help because this is a COM object
and it has no user interface so even if the debug dialog would display(and I don't believe it would), ASSERTS would only work
in my development environment and NOT in the live system. Also, this error would never occur in my development environment
unless I also set up a very complex test that would simulate users doing data entry while the COM object is also running and
doing that would be unbelievably complex. BUT, conceptually you have given me an idea that I believe could work. I could
modify the FindViewParameter method to write additional information out to a text file for better debugging information or
perhaps I could do that in the ON ERROR routine when an error gets logged.
I will try to do that today and see what I get.
OK, I set out to do as described above. I decided to modify my ON ERROR routine to write out additional debugging info when the error 1925 occurs. I found out that I already have code in my ON ERROR routine to do that but that code is not working properly. I need some help with determining why. Here is the code in my ON ERROR routine:
LPARAMETERS tnError, tcMethod, tnLine
LOCAL lcfacility,lcsubject,lctmpfilename,lntmpfilehndl
&& 01/06/2016 - added property and adding line here to set property true.
this.lerrorhasoccurred=.t.
&& will check in code where i suspect an untrapped error is occurring
&& 01/06/2016 - I should see one of these files everytime com001 errors.
lctmpfilename=ADDBS(ALLTRIM(this.capphomeonserver))+"TEMP\ITFCOM001_Log_errors_"+TTOC(DATETIME(),1)+".txt"
lntmpfilehndl=FCREATE(lctmpfilename)
FPUTS(lntmpfilehndl,"in oappcom001.error. errno="+ALLTRIM(STR(tnError,6,0)))
FFLUSH(lntmpfilehndl,.t.)
FCLOSE(lntmpfilehndl)
DO CASE
&& Ignore error caused by issuing a CLEAR ALL in the init of this class.
CASE tnError = 1951 AND UPPER(ALLTRIM(tcMethod)) == "INIT"
RETURN
&& Ignore errors causes by issuing SET DATASESSION TO an invalid data session.
CASE tnError = 1540
RETURN
&& Ignore errors opening the project as a table. GetProjectData will use the
&& last copy of the meta data table if the project can't be opened. This allows
&& VFE to run in one instance of VFP and a second VFP instance to be used to
&& run the project.
CASE tnError = 1705 AND UPPER(ALLTRIM(tcMethod)) == "GETPROJECTDATA"
RETURN
&& Handle any other errors
OTHERWISE
&& send me a text
&& I took all the code out that sends me a text via Twilio to make this more readable.
DoDefault(tnError, tcMethod, tnLine)
ENDCASE
RETURN
About the above code:
VFE always generates an error 1951 when any VFE app starts. It is just always been that way. So, anytime I start this app, an error 1951 occurs, this ON ERROR routine gets executed, I see the text file in my temp folder and it contains the text, "in oappcom001.error. errno=1951". The error is ignored and the program runs.
When an error 1925 occurs this ON ERROR routine is NOT getting executed. How do I know that? The text file is NOT being created. That tells me something some where in my app or maybe in some class library that I am using, is changing ON ERROR and causing it to maybe use the default VFP error handling routine rather than this ON ERROR routine. I am going to need to find that first.
So, I am attempting to understand what could be changing which ON ERROR routine gets executed and it does not take long to realize I have done this sooooo many times and has always proven to be a dead end. Just reading the VFE help topic for how VFE handles errors is so complex it would take a me a month of doing nothing but trying to understand the help topic. I can't do that.
This needs to go back to my original question. I did not do a very good job of asking that original question. Let me try again:
Years and years of dealing with and studying what might cause these 1925 errors, I have come to the conclusion that this is somehow related to the VFP database contention issue where the database gets locked when a view is created. As wrong as it may sound, I have given up on ever determining WHY the 1925 errors occur and instead would prefer a workaround. So back to the basics:
My app that has the user interface is named INMATETRUSTFUND. It is compiled to an EXE. It has a tables database with 125 tables. It has a "views" database with 1200 views.
My app that is getting the 1925 errors is named ITFCOM001. It is a COM object compiled to an EXE. It has no display and no user interface. It just runs in the background. It uses the same tables and views databases.
I suspect something like the following is occurring and that is what is causing the 1925 errors:
A user in INMATETRUSTFUND is doing something that opens a view so the views database gets locked while the view is generated. At the same exact moment, ITFCOM001 determines it is time to do an export to a vendor and executes the code that creates the v_jpayexportsbizobj. Doing that would access the views database. VFP would attempt to lock the views database but it is already locked because INMATETRUSTFUND locked it to open some other view. Everything goes awry (and there is a lot of unknown stuff in that statement), and ITFCOM001 generates the 1925 error.
I believe, but would like a better understanding of the VFP database contention issue before I decide, that if I gave ITFCOM001 it's own separate views database that has the same views as the views database that is used by INMATETRUSTFUND, but it doesn't need all 1200 views and instead only needs the 100 or so views that ITFCOM001 uses, that this problem could simply go away meaning the VFP database contention issue would go away because the 2 apps would never use the same views database.
Again, I would really like to fully understand the exact nature of the "VFP database contention" issue before trying my possible solution of having separate views databases.
Thanks,
John
I wanted to leave a comment, but I don't have enough reputation apparently...
and I understand this post is 6 months old, but OP has been working on it for 10 years and if I can help, why not? :-)
Adding to the great comments from Stefan & Tamar, when I look at the error message and code I conclude that at the point of error, loCursor is an Object and is not null, but it doesn't have a member called Parameters. This suggests to me that This.FindCursor(lcCursor) or This.oCursor are either returning an unexpected object type or maybe an object that's not instantiated properly...?
As Stefan suggests, extra logging should help. I suggest adding a TRY..CATCH block to log the error, call stack,the value/type/class of loCursor and the value of tcParameter (which should allow you to identify if loCursor was returned by This.FindCursor(lcCursor) or by This.oCursor). My suspicion is that the root cause lies in This.FindCursor() or This.oCursor default values.
I think you should be able to implement a TRY...CATCH without making changes to the global ON ERROR code and throw/raise the original error (after logging) up to ON ERROR - either within the CATCH or after the TRY CATCH block - to keep any code called in the ON ERROR hierarchy running as before.
If upon consideration, you think it's a valid situation for FindViewParameter() to get a value from This.FindCursor(lcCursor) or This.oCursor that isn't a valid cursor object then you can suppress these errors by replacing:
IF VARTYPE(loCursor) = T_OBJECT
with:
IF TYPE("loCursor.Parameters") = T_OBJECT
or Maybe even:
IF TYPE("loCursor.Parameters") # "U" .and. VARTYPE(loCursor.Parameters) = T_OBJECT
(TYPE() won't throw an error if you pass it an invalid reference, but unhelpfully won't tell you if an object ref is null, so combine the two)
This might be enough, but you might just end up with errors regarding .item() not being a member of loCursor.Parameters instead.
In that case you could just catch and suppress the errors with a TRY CATCH block. Based on the comments it looks like FindViewParameter() was amended to return null in some situations back in 1999... They must have considered this important if, in 1999, it took precedence over "millennium bug" preparations! Oops, my age is showing! :-)
Hope this helps.
Good Luck!

Ignore errors in UFT without generating a warning

On certain pages in my tests I have are-you-sure-popups that my or may not show up.
I solve this obvious problem using
On Error Resume Next
[Click OK]
This works fine but for all the popups that have actually not been present but it generates a warning which does look unnecessarily alarming. Is there any way to suppress these warning in UFT?
On Error Resume Next
Reporter.Filter = rfDisableAll
Dialog("TITLE").Button("LABEL").Click
Reporter.Filter = rfEnableAll
On Error GoTo 0
This is the Hacky Way.
For a very pure implementation you should be deterministic: always be in control, always know, what will happen and use the Exist Property on the Object if it's optional.
For Random Events the UFT Solution is Recovery Scenarios - but I did not see many implementations for it.

Debugging Step Into, Over, Out within VB6 IDE closes the class window

I am experiencing very strange behavior within VB6 IDE whenever the break point hits(Step Into, Out, Over), the class is closed and makes it impossible to debug. Then within window-Cascade i can re-open the class but again when break point hits, the class is closed. Can anyone help please.
Step execution does sometimes behave that way. The reason is that VB is event driven and when an event occurs, then the code behind that event will run, and your code that you are stepping through might NOT be the code that gets run, so things change and code runs while your PAUSED code is still on hold.
When I encounter that I overcome it by using debug.print to send my monitored variables' current values to the OUTPUT window, or if you need more elaborate capability, write a sub that sends the data to a local text file and then invoke that sub as needed, passing into the variables ( and labels ) that you want displayed.
Once debug.print or a logging routine is in place then run the code WITHOUT pauses or breaks. The debugging output will tell you what is happening, in what order etc, so no need to stop the code or risk altering the order of execution.
Be sure to include lots of 'context' data such as : 'Entering SUB_XYZ, Param values are A, B, C... NOW at line 99 in SUB XYZ.... NOW in TRUE side of IF TEST # 1....
Include time stamps on all outputs.
Put your tracing logic only around the suspected problem area, expand from there only as needed.
It's a pain, but it works.
I finally resolved this issue and problem was within Display settings within windows 10. Basically if I apply vertical settings by placing both screen vertically 2nd on top of first then this issue happens,if i apply horizontal settings then this issue does not happen.
problematic settings with vb
settings that does solves debugging issue. VB is so weird and old cannot cope with display settings

How can I force VB6 to enter the debugger from the execution of a program without a break point?

I'm trying to watch the execution of a VB6 app and I'm running into an issue because once I enter the debugger and then hit Continue, it no longer lets me step through the code until I hit another break point. I want to be able to execute a program without stepping through something until I hit a point where I want to watch it execute. Ideally this would be something to the effect of holding a key down while I pressed a button to 'step into' that function.
Thanks in advance!
[EDIT]: I'm aware that I can use break points to stop the execution. To be more clear, the problem is that I don't know where the execution is going to, so I can't set the break point there (because I don't know where there is). That's why I essentially want to be able to say, 'after this next thing that I do, break, no matter what'. It sounds like this functionality does not exist, but I'm still keeping my fingers crossed.
While the code is running, press ctrl+break (or the 'VCR pause' button in the IDE) then press F8 (or choose 'Step Into'from the Debug menu in the IDE) to continue running the app. The next action will cause execution to break.
Note that the which causes the break will not always be the one you hoped it would be. Particularly annoying is the _MouseOver event which prevents you from doing a mouse down or a timer firing quckier than you can perform your action. Some breaks may even be fatal as regards running your app e.g. where Windows messages have been hooked (subclassing). Also consider there may not be an event handler in code (yet) for your action where it can break. But usually this technique identifies where you should be setting your breakpoint.
There is a Stop statement available for use in VB6 that will drop to the debugger when the statement is executed from code running through the IDE. (Just be sure to remove the all of the Stop statements from the code when compiling a release build.)
There are several techniques you can use.
These two have been mentioned
Using F8 and Shift-F8 to step through the program
Adding Stops (and later removing)
Others
Use a global variable to create a collection. Use it as a stack and have the subroutines you are interested in push and and pop strings. Conversely don't pop anything and you will get a trace.
Use Watches to monitor and break at selection conditions. You can setup just about any condition to break.
Make a Global String and have your procedures set when you enter them. Monitor it through a Watch.
Use Debug.Print in your code. Also Unlike Stop you can leave these in without effecting the production code.
Use the File System Object to create a text file to act as a log.
Sometimes problem only occurs in the Complied version then you need to use MsgBox or log to a text file. MsgBox can alter the behavior of complex user interactions with forms.
These are all techniques I used in debugging an application. If I had to monitor an application I would use Debug.Print. If that doesn't do the trick compile then log to a text file.
If you have something really complex going on then I recommend moving all your code out of the events into classes implementing a Command Pattern. Your commands classes should interact with the form through and interface.
In the Execute method of the command classes you will something like
<save the current state>
<Do your original code>
<save the modified state>
<push the command onto a stack>
What will happen is that you wind up with a list of all the commands you have executed (even things like mouseover) with the state they encountered and the modified state. You can then examine each object in turn to see what is happening. This is nearly the equivalent of creating Undo/Redo
Note however things like MouseOver can push a lot of classes on the command stack so you will have to structure your tests carefully or be overloaded with information. Remember you can always skip pushing the command onto the stack.
The downside of using commands is that you gone beyond debugging into redesigning. You will to decide whether the problem is worth doing this.
You can press the F8 key to step through the code line by line. Alternatively, you can press SHIFT-F8 to step through line by line.
F8 will step you in to a function, where SHIFT-F8 will step you over the function. If you click on the DEBUG menu in the VB IDE, you will see other options too.
EDIT:
You can also put a permanent break point in your code by using:
Debug.Assert False
By doing it this way, the 'breakpoint' is saved in your code. When you compile the app, debug code is ignored.

Difference between CFRunLoopRemoveSource and CFRunLoopSourceInvalidate

I was debugging a crash in my HID driver code on the Mac and found that the crash happened in the CFRunLoop. In the driver code I open the USB handles for the devices which match the VID and the PID which match my HID device and then set up an Interrupt call back for it using setInterruptReportHandlerCallback function and then add it to the CFRunLoop using CFRunLoopAddSource call. In my call to the close handles I freed them up using CFRunLoopRemoveSource and then a CFRelease on the CFRunLoopSourceRef .
The problem occurs when I try to Open the handles wait for a while( 5ms) and then close the handles in a loop.
When I searched for the problem I came across a link where they had a similar problem to mine http://lists.apple.com/archives/usb/.../msg00099.html where they had used CFRunLoopSourceInvalidate call instead of teh Remove Source call. When I changed it to Invalidate source in my close handles call, it fixed my crash. I wanted to know what is the difference between the crash and why this call fixed my crash?
Thanks
jbsp72
First, let me thank you. I type CFRunLoopRemoveSource in google, find your message which is exactly the problem I was trying to solve, and your solution by calling CFRunLoopSourceInvalidate instead also solves my problem.
Now, the difference between CFRunLoopRemoveSource an CFRunLoopSourceInvalidate is:
CFRunLoopRemoveSource removes the
source from the specific run loop you
specify.
CFRunLoopSourceInvalidate renders the
source invalid, and will remove it
from all the run loops where was
added.
Now, the crash, which I suspect is the same as the one I got, is that the run loop the source was added to has disappeared, and trying to remove the source from it results in a crash. Actually, an infinite loop in __spin_lock in my case.
Now, how can a run loop disappear? Run loops are tied to threads. You create a new thread, you have a new run loop, automatically. If a thread ends, the run loop disappears with it. The thread I attached the run loop to has exited, and subsequently removing the source from the run loop results in the crash.
The reason why invalidating the run loop solves the problem is because it removes the source from all the run loops it was added to, ignoring run loops that now do not exist anymore.

Resources