Announcement

Collapse
No announcement yet.

iPowerThread - what's going on

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • iPowerThread - what's going on

    I'm toying with doing a major internals re-write of a program, and was thinking of using iPowerThread to perhaps help with thread management. I've always done thread stuff the old manual way before.

    So I create a tiny class to experiment with and add it as an #INCLUDE file to the existing program. I don't do anything with the class, I don't create any instances of it - nothing, it is simply included in the existing program's source. I was just setting it up to be part of my normal PBProj file.

    A quick compile and execute and the program now crashes during initialization with a C0000005 error code. How is this possible? There IS other thread activity going on, does iPowerThread somehow expect all thread activity to be under it's control?

    Here's the INCLUDE file:
    Code:
    CLASS TMClass
    INSTANCE ThreadParam AS LONG
    
       THREAD METHOD MAIN() AS LONG
       END METHOD
    
       INTERFACE TMInterface
    
          INHERIT IPOWERTHREAD
    
          METHOD abc
          END METHOD
    
       END INTERFACE
    END CLASS
    Has PB now included some new iPowerThread code in the EXE that is somehow triggering this? If so, how on earth do I solve this?

    Please MCM don't ask for the crashing code, it's 50K+ lines.

    George

  • #2
    Is "C0000005 error code" something everyone should recognize?
    Dale

    Comment


    • #3
      Has PB now included some new iPowerThread code in the EXE that is somehow triggering this?
      Possibly;

      If so, how on earth do I solve this?
      Try "doing something" when invoking the methods 'main' and 'abc'; the 'empty' methods might be causing , er, "issues." That's about all I can see there which is "unusual."

      MCM
      PS: Thank you for thinking of me.

      Michael Mattias
      Tal Systems Inc.
      Racine WI USA
      mmattias@talsystems.com
      http://www.talsystems.com

      Comment


      • #4
        Don't ask me about com or classes but Google says "C0000005" is "Access Violation"
        There are only two speeds for computers: fast enough, and too bloody slow.
        And there are 10 types of programmer -- those that know binary, and those that don't.

        Comment


        • #5
          From MSDN:

          EXCEPTION_ACCESS_VIOLATION
          The thread attempts to read from or write to
          a virtual address for which it does not have access.
          This value is defined as STATUS_ACCESS_VIOLATION 0x0000005C.

          STATUS_ACCESS_VIOLATION 0x0000005C
          Memory access violation occurred.

          Comment


          • #6
            Is "C0000005 error code" something everyone should recognize?
            Not really, as long as you can look it up.

            It is, however, a very common "GPF Error Code" since an access violation is nearly always a fatal program error and is by far the most common "GPF error code" reported here. You can generate one with PB quite easily by committing an array access or a pointer error violation with error trapping (#ERROR ALL ON) disabled.

            Michael Mattias
            Tal Systems Inc.
            Racine WI USA
            mmattias@talsystems.com
            http://www.talsystems.com

            Comment


            • #7
              I could have looked it up. But George could have saved EVERYONE else from looking it up. And, if he didn't know, or hadn't already looked it up himself, then the post 1 question is premature!
              Last edited by Dale Yarker; 12 Sep 2017, 04:11 PM. Reason: "sh" to "c"
              Dale

              Comment


              • #8
                Not really [need to recognize an error code] as long as you can look it up
                ==>
                I could have looked it up...
                My point was more like, there's never a reason to memorize all these codes as long as you have the documentation handy.

                Which reminds me of a story from 1996 or 1997.... I was engaged as a consultant at Milwaukee Insurance, developing IBM mainframe COBOL code. If you are familiar with IBM mainframe shops, you know the "system and utilities documentation" is typically between one hundred and two hundred feet, so there's one copy in a designated library room or area.

                Anyway, we had one consultant there who NEVER visited the library or referred to the documentation. He knew by heart all the fine tuning syntax not just for COBOL, but for JCL, for control cards (Including DD name requirements) for IEBGENER and IDCAMS, for CAF (Call Attach Facility, used for databases) and you name it. It was utterly amazing! I had never seen anyone do this.

                BUT..
                One day he asked me to look over his program output, as he was having trouble getting it to foot and thought maybe ye olde "fresh set of eyes'" thing would work. It did; in about fifteen seconds I could see his problem was he had failed to account for the sales tax, which is why his output wouldn't foot.

                "Sales Tax?" asked the guy who knew two hundred feet of detailed technical documentation by heart. "I don't know what 'sales tax' is, could you please explain it?"

                Which is why I would not worry about memorizing codes you can always look up... there's more important stuff to store up there between the ears!
                Michael Mattias
                Tal Systems Inc.
                Racine WI USA
                mmattias@talsystems.com
                http://www.talsystems.com

                Comment


                • #9
                  George,
                  does iPowerThread somehow expect all thread activity to be under it's control?
                  iPowerThread co-exists with another thread quite comfortably in this test code.
                  Code:
                  #Dim All
                  #Compile Exe
                  #Register None
                  #Include "WIN32API.INC"
                  #Include "PThreadTest.inc"
                  '------------------/
                  
                  Function PBMain()
                   Local hThread, T1 As Long : T1 = 5
                  ' Create thread to run in background
                    Thread Create BGThread(T1) To hThread
                    Thread Close hThread To hThread : hThread = 0
                  
                  ' Use Thread Objects from PThreadTest.inc
                   Local xx As MyFace
                   Local oo As DataFace
                    Let xx =  Class "MyClass"
                    Let oo =  Class "DataClass"
                  
                    xx.launch(oo)
                    xx.join(xx, 0)
                    xx.abc
                  
                   Do While ThreadCount > 1
                     Sleep 100
                   Loop
                  End Function
                  '------------------/PBMain
                  
                  Thread Function BGThread(ByVal T1 As Long) As Long
                    Local T2 As Long
                    T2 = Timer + T1
                    Do While T2 > Timer
                      Sleep 1000
                      WinBeep 800,200
                    Wend
                  
                  End Function
                  '------------------/BGThread
                  '==============================================================
                  
                  'Code for PThreadTest.inc
                  #If 0
                  Class MyClass
                   Instance ThreadParam As DataFace
                  
                    Thread Method Main() As Long
                     WinBeep 1800,200
                     Local x As Long
                      x = ThreadParam.GetANumber()
                      MsgBox Dec$(x), %MB_SystemModal, "Method MAIN"
                    End Method
                  
                    Interface MyFace
                      Inherit IPowerThread
                  
                      Method abc
                        MsgBox "abc", %MB_SystemModal, "Method abc"'
                      End Method
                    End Interface
                  End Class
                  
                  Class DataClass
                  
                    Interface DataFace
                      Inherit Dual
                  
                      Method GetANumber() As Long
                      Method = 77
                    End Method
                  
                    End Interface
                  End Class
                  '------------------/PThreadTest.inc
                  #EndIf
                  Rgds, Dave

                  Comment


                  • #10
                    Georges,
                    If I got you right, when you REM the
                    #INCLUDE "YourClassStuff.inc" then all go well.

                    If so, what if you REM all lines in the inc file
                    and unREM them progressively until the program crash again.

                    About the abc METHOD, what if you rename it
                    to avoid any potential weard conflict with the abc type.

                    TYPE ABC
                    ...abcA AS LONG
                    ...abcB AS DWORD
                    ...abcC AS LONG
                    END TYPE

                    Added: I see abc method works nice in Dave's code. So proplem is somewhere else...
                    Last edited by Pierre Bellisle; 12 Sep 2017, 09:43 PM.

                    Comment


                    • #11
                      I didn't describe C0000005 because it is possibly the commonest 'crash' code in existence, and I find it hard to believe 99% of programmers wouldn't be instantly aware of what it was.

                      As to the skeleton code, I had done the comment / uncomment route, and at it's minimum, a single line is the trigger.
                      Code:
                      CLASS TMClass
                      'INSTANCE ThreadParam AS LONG         <==== Un-comment to trigger the error
                      
                      '   THREAD METHOD MAIN() AS LONG
                      '   END METHOD
                      '
                         INTERFACE TMInterface
                      '
                            INHERIT IUNKNOWN
                      '
                      '      METHOD abc
                      '      END METHOD
                      '
                         END INTERFACE
                      END CLASS
                      With almost everything else commented out, the single line defining ThreadParam (which is a mandatory part of the iPowerThread support) will trigger the error. So PB must be adding thread related code to the EXE based on that alone, since I never create an instance of the class, I never even mention it elsewhere. And the crash occurs at the point in my program's initialization where a thread is created to complete some background stuff.

                      I think perhaps rather than beat my head against this, I'll just continue to handle threads the old manual way. There's obviously something here I just don't get.

                      George

                      Comment


                      • #12
                        I didn't describe C0000005 because it is possibly the commonest ...
                        Then your answer to post #2 is"yes". I disaggree, but that was simple, and no need for drama.

                        Another question -
                        Is "ThreadParam" used as a name anywhere else in your code?

                        Cheers,
                        Last edited by Dale Yarker; 13 Sep 2017, 06:08 PM.
                        Dale

                        Comment


                        • #13
                          Originally posted by Michael Mattias View Post
                          ==>


                          My point was more like, there's never a reason to memorize all these codes as long as you have the documentation handy.

                          Which reminds me of a story from 1996 or 1997.... I was engaged as a consultant at Milwaukee Insurance, developing IBM mainframe COBOL code. If you are familiar with IBM mainframe shops, you know the "system and utilities documentation" is typically between one hundred and two hundred feet, so there's one copy in a designated library room or area.

                          Anyway, we had one consultant there who NEVER visited the library or referred to the documentation. He knew by heart all the fine tuning syntax not just for COBOL, but for JCL, for control cards (Including DD name requirements) for IEBGENER and IDCAMS, for CAF (Call Attach Facility, used for databases) and you name it. It was utterly amazing! I had never seen anyone do this.

                          BUT..
                          One day he asked me to look over his program output, as he was having trouble getting it to foot and thought maybe ye olde "fresh set of eyes'" thing would work. It did; in about fifteen seconds I could see his problem was he had failed to account for the sales tax, which is why his output wouldn't foot.

                          "Sales Tax?" asked the guy who knew two hundred feet of detailed technical documentation by heart. "I don't know what 'sales tax' is, could you please explain it?"

                          Which is why I would not worry about memorizing codes you can always look up... there's more important stuff to store up there between the ears!
                          Absolutely love the story

                          I have known guys like that too.

                          Give me some remembering time and I will try and cap it!

                          [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
                          Kerry Farmer

                          Comment


                          • #14
                            Yes, the "guy who knows it all by heart" is something else all right.

                            But I still like the description of these folks I read in a novel: "Smart in school, but dumb on the bus."
                            Michael Mattias
                            Tal Systems Inc.
                            Racine WI USA
                            mmattias@talsystems.com
                            http://www.talsystems.com

                            Comment


                            • #15
                              Dale: Good thought, I've seen problems in the past like that. But sadly, no, there are no other uses of that keyword.

                              George

                              Comment


                              • #16
                                Hi George,

                                I've played around with the sample code that I posted above to make the ThreadParam a LONG instead of an object and now see the error code that you reported..
                                Code:
                                #Dim All
                                #Compile Exe
                                #Register None
                                #Include "WIN32API.INC"
                                
                                
                                Class MyClass                                 ' Alt. add Class code in INC file..
                                 Instance ThreadParam As Long   ' DataFace
                                
                                  Thread Method Main() As Long
                                   Local x As Long
                                    x = ThreadParam '.GetANumber()
                                    MsgBox "ThreadParam: " + Dec$(x), %MB_SystemModal, "Method MAIN"
                                  End Method
                                
                                  Interface TMInterface
                                    Inherit IPowerThread
                                
                                    Method abc
                                 '      MsgBox "abc", %MB_SystemModal, "Method abc"'
                                    End Method
                                  End Interface
                                End Class
                                
                                 'Class DataClass                             ' Use Class to pass ThreadParam ??
                                 '
                                 '  Interface DataFace
                                 '    Inherit Dual
                                 '    '
                                 '    '    Method GetANumber() As Long
                                 '    '      Method = 77
                                 '    '    End Method
                                 '    '
                                 '  End Interface
                                 'End Class
                                '------------------/
                                
                                Function PBMain()
                                 Local hThread, T1 As Long : T1 = 5
                                  Thread Create BGThread(T1) To hThread       ' Create thread to run in background (REM to avoid ERROR)
                                  Thread Close hThread To hThread : hThread = 0
                                
                                 Local xx As TMInterface                      ' Use Thread Objects from Class declaration(s)
                                  Let xx =  Class "MyClass"
                                 ' Local oo As DataFace
                                 '  Let oo =  Class "DataClass"
                                 '  xx.launch(oo)
                                
                                 Local O2 As Long : O2 = 88
                                  xx.launch(ByVal O2)                         ' See use in 'Simpler cases' in THREAD Object help
                                  xx.join(xx, 0)
                                 '  xx.abc
                                
                                 Do While ThreadCount > 1
                                   Sleep 100
                                 Loop
                                End Function
                                '------------------/PBMain
                                
                                Thread Function BGThread(ByVal T1 As Long) As Long
                                  Local T2 As Long
                                  T2 = Timer + T1
                                  Do While T2 > Timer
                                    Sleep 1000
                                    WinBeep 800,200
                                  Wend
                                
                                End Function
                                '------------------/BGThread
                                The issue maybe alluded to in this comment from the THREAD Object help topic
                                Restrictions

                                Functions from the Thread Code Group and THREAD OBJECTS may co-exist in the same application.
                                However, it is important that they not be intermixed when you reference one particular thread.
                                Maybe they become 'intermixed' somehow when you don't pass the ThreadParam via an object??

                                THREADPARAM is a mandatory Instance variable which you must define in each thread class.
                                It is normally declared as the interface name of your choice:

                                INSTANCE ThreadParam as MyInterface

                                In simpler cases, you may choose to declare THREADPARAM as a pointer, Long Integer, or Dword.
                                In that case, you must pass the launch parameter using a byval option, to override the expected object variable.

                                INSTANCE ThreadParam as LONG
                                ...
                                MyThread.Launch(ByVal MyNumber&)
                                Last edited by Dave Biggs; 14 Sep 2017, 06:11 PM.
                                Rgds, Dave

                                Comment


                                • #17
                                  Dave: Looks like that may be the key. Obviously PB intended to allow other variable types and what we're seeing is just a plain (but obtuse) PB bug. If that's all it takes to make this work, then maybe I can still use it, but it does seem to me to be an awkward way to pass parameters. I'll go play some more and get back, but I fear it may be quite a while before I post a reply. We're off soon for an extended cruise (6 weeks) for our 50th anniversary. Right now I'm in the middle of packing. Packing for 6 weeks is sure different than packing for a week or two.

                                  George

                                  Comment


                                  • #18
                                    Doesn't seem to be a great incentive to abandon using the Thread Code Group of statements in favour of the Thread Object paradigm does there

                                    Bon voyage, enjoy your celebrations!
                                    Rgds, Dave

                                    Comment


                                    • #19
                                      Dave: I had a real quick try. Created another object like DataClass and modified things from the LONG parameter to using that Object. Still a no-go.

                                      As I said before, not worth bashing my head on this when the old tried and true methods work fine. It was one of those "If I'm ripping things apart anyway, why not re-write using the new support?"

                                      Anyway, maybe 6 weeks of the high life will clear my head.

                                      George

                                      Comment


                                      • #20
                                        I ran into the same problem a couple of years ago. I don't remember the solution right now, but I would be very careful with the Powerthread object. I have discovered that if the thread is going to run in a loop for the life of the program, say to monitor a comm port or tcp port, eventually you will run out of memory. In other words, there's a memory leak somewhere in the executable code. You can create a simple thread that does nothing but sleep and continue looping and you will eventually see the problem. I put together a demo of it and sent it off to Tom back before the purchase, but I don't know if he ever got to the bottom of it. Having said that, I've had good luck using it for actions that will do some work and finish up. In fact I like it a lot. Keep in mind that you don't have to pass anything via the ThreadParam (byval 0) and still set all kinds of variables. Since it's a normal object, you can create whatever instance variables you like and set them use the Property Set feature. It works fine.

                                        Russ
                                        "There are two novels that can change a bookish fourteen-year old's life: The Lord of the Rings and Atlas Shrugged. One is a childish fantasy that often engenders a lifelong obsession with its unbelievable heroes, leading to an emotionally stunted, socially crippled adulthood, unable to deal with the real world. The other, of course, involves orcs." - John Rogers

                                        Comment

                                        Working...
                                        X