Hard to replicate, code not getting run.

Just starting out? Need help? Post your questions and find answers here.
jassing
Addict
Addict
Posts: 1774
Joined: Wed Feb 17, 2010 12:00 am

Hard to replicate, code not getting run.

Post by jassing »

I am working on a bigger project, and don't have access to everything. But here's what I do know.
I have a module that works 'on it's own' in a test file. Works if I put it in a thread, works if I put it in 3 threads. All is ok.
However, when I run it as part of the bigger program; code is getting skipped; here's an example (not usable code)

Code: Select all

EnableExplicit
declaremodule something
...
endeclaremodule
module something
  EnableExplicit
  define myVar,myFile.s
  newlist myList()

  Procedure Init()
    shared myList()
    foreach myList() <<<< This generates an Invalid memory Access
    ....
if I put a "calldebugger" before the newlist line, the debugger is not called.
If I put "End" before newlist, the program does not end

Thinking that maybe it's a module issue, I removed the module and renamed all the variables so they were ensured to be unique, same thing.

If I put put "if listsize( myList() ) > 0" before the foreach line; I get a run-time error that says the list has not been initialised.
But the program compiles error-free. and "syntax check" says it's all OK too.

if I comment out the newlist line; it won't compile, erroring on the Shared myList() as not being declared.

Since the module code works when run by itself, I think I can safely say it's not the module. The fact that the codecompiles but then complains the list doesn't exist at runtime tells me there's a compiler issue.
I am slowly just deleting blocks of code and then fixing the errors that generates to try to reduce the code (over 130K lines) to try to get the code to work; I have not been successful.

Image to show an error.
Image
User avatar
idle
Always Here
Always Here
Posts: 5095
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Hard to replicate, code not getting run.

Post by idle »

It sounds like a threading issue to me, try a mutex around access to filefound(), just for a sanity check
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
Paul
PureBasic Expert
PureBasic Expert
Posts: 1252
Joined: Fri Apr 25, 2003 4:34 pm
Location: Canada
Contact:

Re: Hard to replicate, code not getting run.

Post by Paul »

If the simplest of modules works fine then one would have to assume you've made a mistake somewhere.
Really hard to comment when you don't post code that actually demonstrates the problem ;)

Code: Select all

DeclareModule Test
  Declare t()  
EndDeclareModule

Module Test
  NewList testdata()
  
  Procedure t()
    Shared testdata()
    AddElement(testdata()):testdata()=999
    ProcedureReturn ListSize(testdata())
  EndProcedure

EndModule

Debug Test::t()
Image Image
User avatar
Lord
Addict
Addict
Posts: 849
Joined: Tue May 26, 2009 2:11 pm

Re: Hard to replicate, code not getting run.

Post by Lord »

A Procedure() doesn't know List FilesFound() until
it's declared Global or Shared.
Maybe. I don't know.
Image
User avatar
Michael Vogel
Addict
Addict
Posts: 2677
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: Hard to replicate, code not getting run.

Post by Michael Vogel »

Hard to help here, would do a lot of logging into a file to see if everything is initialized...

Here's a simple macro which can replace debug commands easily...

Code: Select all

#LogLevel=3
#LogFile=0
CompilerIf #LogFile
	CreateFile(#LogFile,"Log.txt")
CompilerEndIf

Macro Delog(level,text)

	CompilerIf level>=#LogLevel

		Debug FormatDate("%hh:%ii:%ss.",Date())+RSet(Str(ElapsedMilliseconds()%1000),3,"0")+" "+Str(level)+" "+RSet(Str(#PB_Compiler_Line),5,"0")+" "+#PB_Compiler_Procedure+": "+text
		CompilerIf #LogFile
			WriteStringN(#LogFile,FormatDate("%hh:%ii:%ss.",Date())+RSet(Str(ElapsedMilliseconds()%1000),3,"0")+" "+Str(level)+" "+RSet(Str(#PB_Compiler_Line),5,"0")+" "+#PB_Compiler_Procedure+": "+text)
		CompilerEndIf

	CompilerEndIf

EndMacro



Global panic
Global mutex

Procedure drawlogos(nil)

	Protected n

	Repeat
		Delog(2,"lock mutex")
		LockMutex(mutex)
		
		Delog(2,"create image")
		CreateImage(0,1,1,32,Random(#White))
		Delog(1,"resize #1")
		ResizeImage(0,1000,1000)
		Delog(1,"resize #2")
		ResizeImage(0,400,400)
		n+1
		Delog(3,"drawing start")
		StartDrawing(ImageOutput(0))
		DrawText(0,0,Str(n),#Black,#White)
		StopDrawing()
		Delog(3,"drawing done")
		Delay(Random(10))
		SetGadgetState(0,ImageID(0))
		
		UnlockMutex(mutex)
		Delog(2,"unlock mutex")
		
	Until panic

EndProcedure

Procedure stop()

	Delog(3,"quit now")
	End

EndProcedure
Procedure main()
	
	Delog(3,"start now")
	OpenWindow(0,0,0,400,400,"")
	ImageGadget(0,0,0,400,400,0)

	mutex=CreateMutex()
	CreateThread(@drawlogos(),#Null)

	Repeat
	Until WaitWindowEvent()=#PB_Event_CloseWindow

	stop()

EndProcedure

main()
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Hard to replicate, code not getting run.

Post by #NULL »

Do you have any DisableDebugger anywhere in some code? Maybe the Debugger doesn't know the list if NewList was done while debugger is disabled.
Not sure if a DisableDebugger in another thread could cause such too.

<edit>
What happens if you put EnableDebugger before CallDebugger, NewList, ListSize()?
jassing
Addict
Addict
Posts: 1774
Joined: Wed Feb 17, 2010 12:00 am

Re: Hard to replicate, code not getting run.

Post by jassing »

#NULL wrote:Do you have any DisableDebugger anywhere in some code? Maybe the Debugger doesn't know the list if NewList was done while debugger is disabled.[/qoute]
No.

<edit>
What happens if you put EnableDebugger before CallDebugger, NewList, ListSize()?
Nothing -- see the updated image, debug and end commands are obvious ones. I get debug output for other statements, in fact, I get right before including the module, so the debugger is working...
Lord wrote:A Procedure() doesn't know List FilesFound() until
it's declared Global or Shared.
Maybe. I don't know.
You don't need to declare as global, just need to mention in the procedure it's shared.
See the updated image; I changed to global, tried w/ and w/o 'shared'
The problem is that the code doesn't get executed when run as part of the project.
When run as it's own file (not included in the project) the module works perfectly...
Paul wrote:If the simplest of modules works fine then one would have to assume you've made a mistake somewhere.
Really hard to comment when you don't post code that actually demonstrates the problem ;)
Sorry... I really can't post the code to replicate, using the module by itself works fine. Look at the image -- "END" does not get executed when run as part of hte project, when using the exact same source file outside of hte project (ie: as main file) it works perfectly.


Here's a stripped down version.
When run as it's own source code, it works; code stops executing at "End"
when run in the project, the error occurs.

Code: Select all

EnableExplicit

;XIncludeFile "iniFileModule.pbi"

DeclareModule WatchDirOrFile
  Declare WatchThread( *folder )
  Declare init( cWatchFolder.s = "c:\")
EndDeclareModule

Module WatchDirOrFile
  Debug "WatchDirOrFile module" ;<=- does not get executed.
  EnableExplicit
  EnableDebugger
  
  Macro dbgout( txt )
    Debug txt
  EndMacro
  Import "kernel32.lib"
    ReadDirectoryChangesW(hDir, *buffer, nBufLen, bWatchSubtree, dwNotifyFilter, *bytesRetured, *Overlapped, *CompletionRoutine)
  EndImport
  ;{ Structures
  Structure FILE_NOTIFY_INFORMATION
    NextEntryOffset.l
    Action.l
    FileNameLength.l
    Filename.s{255}
  EndStructure
  ;}
  
  ;{ Enumeration & constants
  
  ;- Constants
  ;{ File notify Constants
  #FILE_NOTIFY_CHANGE_FILE_NAME = 1
  #FILE_NOTIFY_CHANGE_DIR_NAME = 2
  #FILE_NOTIFY_CHANGE_ATTRIBUTES = 4
  #FILE_NOTIFY_CHANGE_SIZE = 8
  #FILE_NOTIFY_CHANGE_LAST_WRITE = $10
  #FILE_NOTIFY_CHANGE_LAST_ACCESS = $20
  #FILE_NOTIFY_CHANGE_CREATION = $40
  #FILE_NOTIFY_CHANGE_SECURITY = $100
  #FILE_NOTIFY_CHANGE_ALL = $17F
  #FILE_SHARE_DELETE = 4
  #FILE_ACTION_ADDED = 1
  #FILE_ACTION_REMOVED = 2
  #FILE_ACTION_MODIFIED = 3
  #FILE_ACTION_RENAMED_OLD_NAME = 4
  #FILE_ACTION_RENAMED_NEW_NAME = 5
  ;}
  ;- Variables for Module
  ;}
  Debug "Creaing list..." ;<=- does not get executed.
  Global NewList FilesFound()
  Debug "Created" ;<=- does not get executed.
  End ;<=- does not get executed.
  
  Define.s onedrive,googledrive,dropbox
  
  Procedure ProcessThread( *bContinue.Byte )
    ;Shared FilesFound()
    Protected *p
    
    dbgout("FilesFound() processing thread started.")
    Repeat 
      Delay(100)
      CompilerIf Defined( FilesFound, #PB_List)
        If ListSize( FilesFound() ) > 0  ; <=- "Linkd List not intialisd"
          ForEach FilesFound()
                    
            If *bContinue\b = #False
              Break
            EndIf
            
            *p = FilesFound() 
            
          Next
        EndIf 
      CompilerElse
        CompilerWarning "List FoundFiles() is not defined"
      CompilerEndIf
    Until *bContinue\b = #False 
  EndProcedure
  
  Procedure.s addbs( str.s )
    str = Trim(str)
    If Right(str,1)<>"\" : str+"\" : EndIf
    ProcedureReturn str
  EndProcedure
  
  Procedure WatchThread(*folder)
    Protected DirectoryName.S
    Protected NotifyFilter.l = #FILE_NOTIFY_CHANGE_ALL
    Protected buffer.FILE_NOTIFY_INFORMATION, ovlp.OVERLAPPED
    Protected FileAction_Filename.s
    Protected hDir
    Protected bytesRead
    Protected *work.FILE_NOTIFY_INFORMATION, tmp.s, *ffbuffer
    Shared FilesFound()
    
    dbgout("Watching folder: "+DirectoryName)
    
    hDir = CreateFile_(DirectoryName, #FILE_LIST_DIRECTORY, #FILE_SHARE_READ | #FILE_SHARE_WRITE | #FILE_SHARE_DELETE, #Null, #OPEN_EXISTING, #FILE_FLAG_BACKUP_SEMANTICS, #Null)
    
    While ReadDirectoryChangesW(hDir, @buffer, SizeOf(FILE_NOTIFY_INFORMATION), #True, NotifyFilter, @bytesRead, @ovlp, #NUL )
      
      ;-todo: "copy *.cmd" into folder doesn't catch both files.
      ;-todo: 
      
      *ffbuffer = #NUL 
      FileAction_Filename = PeekS(@buffer\Filename, -1, #PB_Unicode)
      
      Select buffer\Action
        Case #FILE_ACTION_ADDED
          dbgout("!Added: " + DirectoryName.s + FileAction_Filename)
          ;CopyToFolders( DirectoryName.s + FileAction_Filename )
          *work = @buffer
          While *work
            FileAction_Filename = PeekS(@*work\Filename,-1,#PB_Unicode)
            dbgout(">added "+DirectoryName+FileAction_Filename)
            ; CopytoFolders( DirectoryName +  FileAction_Filename )
            
          Wend
          
        Case #FILE_ACTION_REMOVED
          dbgout("Removed: " + DirectoryName.s + FileAction_Filename)
          
        Case #FILE_ACTION_MODIFIED
          dbgout("Modified: " + DirectoryName.s + FileAction_Filename)
          
        Case #FILE_ACTION_RENAMED_OLD_NAME
          ;Dateiumbenennung: Alter Dateiname
          dbgout("Renamed from: "+DirectoryName+FileAction_Filename)
          
        Case #FILE_ACTION_RENAMED_NEW_NAME
          ;Dateiumbenennung: Neuer Dateiname
          dbgout("Renamed To: "+DirectoryName+FileAction_Filename)
          
        Default
          dbgout("Unknown action: "+Str(buffer\Action) )
      EndSelect
      
      If *ffbuffer
        dbgout("Adding buffer to FilesFound list")
        AddElement( FilesFound() ) : FilesFound() = *ffbuffer
        *ffbuffer = #NUL 
      EndIf
      
      buffer\Filename = ""
    Wend
  EndProcedure
  
  Procedure init( cWatchFolder.s = "c:\" )
    Shared onedrive,googledrive,dropbox, FilesFound()
    Static.s SpecialFolder
    Static hProcessThread, hWatchThread, bStop.b = #False 
    dbgout("Watch/Folder init")
    
    If IsThread( hProcessThread ) Or IsThread( hWatchThread )
      dbgout("Killing old threads...")
      bStop = #True : Delay(15000)
      If IsThread(hProcessThread ): KillThread( hProcessThread ) : EndIf
      If IsThread( hWatchThread ) : KillThread( hWatchThread ) : EndIf
    EndIf
    If cWatchFolder = ""
      dbgout("Resetting FilesFound list ("+Str(ListSize( FilesFound()))+")")
      ClearList( FilesFound() )
    ElseIf FileSize( cWatchFolder ) = -2
      dbgout("Watch folder: "+cWatchFolder)
      
      If #True ;LCase(iniFile::iReadString("Misc","WatchSpecialFolder","no")) = "yes"
        dbgout("Monitoring special folder: "+SpecialFolder)
        hWatchThread    = CreateThread( @WatchThread(),    @SpecialFolder ) 
        hProcessThread  = CreateThread( @ProcessThread(),  #NUL )           
      EndIf
    EndIf
    
  EndProcedure
  
  init()
  
EndModule


CompilerIf #PB_Compiler_IsMainFile
  While #True
    Delay(100)
  Wend
CompilerEndIf
jassing
Addict
Addict
Posts: 1774
Joined: Wed Feb 17, 2010 12:00 am

solved, sort of. Re: Hard to replicate, code not getting ru

Post by jassing »

I got it down to literally the declare section, and just 'end' in the module section.
Never ran.
I moved the 'xincludefile' line up towards the top of the file, and problem went away.
There were no naming conflicts, no duplications of any variable or procedure or module name. Changed nothing else, except line # of xincludefile -- and problem went away.

Very weird.
Post Reply