Page 1 of 1

DesktopWidth() crashes my app

Posted: Sat Oct 11, 2025 4:34 am
by BarryG
I've got the following procedure in my app that I only want to run with one monitor, but I keep getting an illegal memory access crash on the "DesktopWidth(0)" line. This happens on both 6.10 and 6.30 Beta 3 of PureBasic, using Windows 11 Pro. My PC has only one monitor (and thus one desktop). I have all current video drivers (it's a new PC).

The error is reported with my crash handler procedure, which is called by "OnErrorCall(@CrashHandler())". I also have error lines enabled for app so that the correct error line is reported, and it's the line for "DesktopWidth(0)".

Any ideas? The problem doesn't occur with this code, so I don't know why "DesktopWidth(0)" is crashing in my main app with this code.

Note: I do use threads in my app, and thread safety is enabled. But this procedure is NOT called as a thread.

Code: Select all

Global desktop_size_x, desktop_size_y, desktop_size_w, desktop_size_h

Procedure GetDesktopSize()
  If ExamineDesktops() = 1
    desktop_size_x = 0
    desktop_size_y = 0
    desktop_size_w = DesktopWidth(0) ; Illegal memory access.
    desktop_size_h = DesktopHeight(0)
  Else ; Irrelevant as only one monitor.
    [...]
  EndIf
EndProcedure

Re: DesktopWidth() crashes my app

Posted: Sat Oct 11, 2025 5:20 am
by RASHAD
Hi BarryG
Just guessing
Try

Code: Select all

Global Result ,desktop_size_x, desktop_size_y, desktop_size_w, desktop_size_h
result = ExamineDesktops()
Procedure GetDesktopSize()
  If result = 1
    desktop_size_x = 0
    desktop_size_y = 0
    desktop_size_w = DesktopWidth(0) ; Illegal memory access.
    desktop_size_h = DesktopHeight(0)
  EndIf
EndProcedure

Re: DesktopWidth() crashes my app

Posted: Sat Oct 11, 2025 7:56 am
by jacdelad
One Sidenote: ExamineDesktops() returns the number of desktops, so it can be more than "1". Don't know about your program, but this could be important.

Re: DesktopWidth() crashes my app

Posted: Sat Oct 11, 2025 7:57 am
by BarryG
But I said I only have one desktop/monitor. ;)

Re: DesktopWidth() crashes my app

Posted: Sat Oct 11, 2025 10:44 am
by jacdelad
Sure, I just wanted to mention it. Maybe your setup changes or you want to publish it, then Thai should be considered.

Re: DesktopWidth() crashes my app

Posted: Sun Oct 12, 2025 12:07 am
by BarryG
Had a user report this crash today. :( He also has only one monitor. Here's the screenshots of the crash report, and the relevant procedure from my app.

At least I know it's not my PC causing the crash, which is a relief. Maybe it's a Win 11 thing, since we're both using that?

Image

Image

Image

Re: DesktopWidth() crashes my app

Posted: Sun Oct 12, 2025 9:00 am
by mk-soft
What happens before the function is called. Sometimes a memory pointer problem (stack) can occur in advance,
which then leads to a crash when calling an API.

Here is something to test the PB function.

Code: Select all

;-TOP

Global DesktopWidth, DesktopHeight, cTest

Procedure GetDesktopSize()
  cnt = ExamineDesktops()
  If cnt
    DesktopWidth = DesktopWidth(0)
    DesktopHeight = DesktopHeight(0)
    cTest + 1
  Else
    DesktopWidth = 99999
    DesktopHeight = 99999
  EndIf
EndProcedure

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(0)
  dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
  ; Resize Gadgets
EndProcedure

Procedure Main()
  Protected dx, dy
  
  #WinStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(0, #PB_Ignore, #PB_Ignore, 600, 400, "Test Window", #WinStyle)
    ; MenuBar
    CreateMenu(0, WindowID(0))
    MenuTitle("&File")
    MenuItem(99, "E&xit")
    
    ; StatusBar
    CreateStatusBar(0, WindowID(0))
    AddStatusBarField(#PB_Ignore)
    
    ; Gadgets
    dx = WindowWidth(0)
    dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
    ButtonGadget(0, 10, 10, 120, 25, "Test")
    
    ; Bind Events
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), 0)
    
    ; Main Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case 0
              Break
          EndSelect
          
        Case #PB_Event_Menu
          Select EventMenu()
            Case 99
              PostEvent(#PB_Event_CloseWindow, 0, 0)
              
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
            Case 0
              GetDesktopSize()
              StatusBarText(0, 0, "Test " + cTest)
              
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()

Re: DesktopWidth() crashes my app

Posted: Sun Oct 12, 2025 9:44 am
by BarryG
mk-soft wrote: Sun Oct 12, 2025 9:00 amWhat happens before the function is called. Sometimes a memory pointer problem (stack) can occur in advance, which then leads to a crash when calling an API.
The problem doesn't occur when run as a standalone test like yours. But you've given me something to test: to look at all code just prior to when my procedure is called. This is in several areas of my app, so I will start checking. Thanks for the idea!

BTW, that user replied by saying "I do have the "open centered on the desktop" enabled in the global settings" which confirms it's the GetDesktopSize() procedure in my app causing the crash. :(

Re: DesktopWidth() crashes my app

Posted: Sun Oct 12, 2025 10:02 am
by mk-soft
Build this in your code for a diagnosis ...

Code: Select all

;-TOP by mk-soft
;
; Memory Debugging v0.5

CompilerIf #PB_Compiler_Debugger
  
  #MemoryStop = 1
  
  Global NewMap MemID()
  
  Procedure MyAllocateMemory(Size, Flags, Proc.s)
    Protected *mem
    *mem = AllocateMemory(Size, Flags)
    If *mem
      MemID(Hex(*mem)) = *mem
    Else
      DebuggerWarning("AllocateMemory: Out Of Memory : Proc /" + Proc)
      CompilerIf #MemoryStop : CallDebugger : CompilerEndIf
      ProcedureReturn #False
    EndIf
    ProcedureReturn *mem
  EndProcedure
  
  Procedure MyFreeMemory(Memory, Proc.s)
    If FindMapElement(MemID(), Hex(Memory))
      FreeMemory(Memory)
      DeleteMapElement(MemID())
      ProcedureReturn #True
    Else
      DebuggerWarning("FreeMemory: Memory not exists : Proc /" + Proc)
      CompilerIf #MemoryStop : CallDebugger : CompilerEndIf
      ProcedureReturn #False
    EndIf
  EndProcedure
  
  Procedure MyMemorySize(Memory, Proc.s)
    If FindMapElement(MemID(), Hex(Memory))
      ProcedureReturn MemorySize(Memory)
    Else
      DebuggerWarning("MemorySize: Memory not exists : Proc /" + Proc)
      CompilerIf #MemoryStop : CallDebugger : CompilerEndIf
      ProcedureReturn 0
    EndIf
  EndProcedure
  
  Procedure MyValidateMemory(Memory, Proc.s)
    If FindMapElement(MemID(), Hex(Memory))
      ProcedureReturn 1
    Else
      DebuggerWarning("MemorySize: Memory not exists : Proc /" + Proc)
      CompilerIf #MemoryStop : CallDebugger : CompilerEndIf
      ProcedureReturn 0
    EndIf
  EndProcedure
    
  Macro AllocateMemory(Size, Flags=0)
    MyAllocateMemory(Size, Flags, #PB_Compiler_Module + "/" + #PB_Compiler_Procedure + "() - Line " + #PB_Compiler_Line)
  EndMacro
  
  Macro FreeMemory(Memory)
    MyFreeMemory(Memory, #PB_Compiler_Module + "/" + #PB_Compiler_Procedure + "() - Line " + #PB_Compiler_Line)
  EndMacro
  
  Macro MemorySize(Memory)
    MyMemorySize(Memory, #PB_Compiler_Module + "/" + #PB_Compiler_Procedure + "() - Line " + #PB_Compiler_Line)
  EndMacro
  
  Macro ValidateMemory(Memory)
    MyValidateMemory(Memory, #PB_Compiler_Module + "/" + #PB_Compiler_Procedure + "() - Line " + #PB_Compiler_Line)
  EndMacro
  
CompilerEndIf

;- test

CompilerIf #PB_Compiler_IsMainFile
  
  Procedure Main()
    *mem1 = AllocateMemory(1024)
    ;*mem2 = AllocateMemory(2048)
    
    Debug "Size 1: " + MemorySize(*mem1)
    Debug "Size 2: " + MemorySize(*mem2)
    
    ;Debug ValidateMemory(*mem2)
    
    Debug "Free 1: " + FreeMemory(*mem1)
    Debug "Free 2: " + FreeMemory(*mem2)
  EndProcedure : main()
  
CompilerEndIf

Re: DesktopWidth() crashes my app

Posted: Sun Oct 12, 2025 11:43 am
by BarryG
Unfortunately I can't test with the debugger because I need to disable it to use windows in threads. Don't worry; I'll work it out.

Re: DesktopWidth() crashes my app

Posted: Sun Oct 12, 2025 1:48 pm
by mk-soft
That could be where the problem lies.
Some functions of the API are not thread-safe...