Page 1 of 1

Invalid memory access error

Posted: Mon Oct 26, 2015 3:16 pm
by captain_skank
Afternoon all,

Getting a strange error when freeing a gadget and then trying to recreate it.

i have a container gadget that I need to empty, so I first free the gadget using

Code: Select all

If IsGadget(fld_header) :  FreeGadget(fld_header)   : EndIf
then recreate it, but my code is throwing the following error :

Code: Select all

[13:45:31] [ERROR] Invalid memory access. (write error at address 0)
[13:45:46] The Program was killed.
Any idea why this would be happening ?

Re: Invalid memory access error

Posted: Mon Oct 26, 2015 3:22 pm
by ts-soft
I think, you are using #PB_Any? and the error comes with recreate it?
Without any code, i can't help.

Re: Invalid memory access error

Posted: Mon Oct 26, 2015 3:44 pm
by captain_skank
Hi ts_soft.

Yep using #pb_any, didn't think this would be a problem though.

Sorry for not posting code but it's a bit long and very messy :)

Re: Invalid memory access error

Posted: Mon Oct 26, 2015 4:50 pm
by ts-soft
With #PB_Any you can't use the same ID for new created Gadgets! You have to use a new #PB_Any ID!

Re: Invalid memory access error

Posted: Mon Oct 26, 2015 5:07 pm
by captain_skank
Thanks for the reply

I think it's something to do with changing to another window and then changing back.

The folowing code works ok before i change window

Code: Select all

  
;kill the fld_display
  FreeGadget(fld_display)
  
 Global fld_display = ScrollAreaGadget(#PB_Any, 15, 130, 970, 400, 940, 1000, #PB_ScrollArea_BorderLess)
 CloseGadgetList()
but once I open and then close another window and return to the main window it crashes when i try to recreate ( or use ) the fld_display gagdet.

Re: Invalid memory access error

Posted: Mon Oct 26, 2015 6:08 pm
by ts-soft
captain_skank wrote:I think it's something to do with changing to another window and then changing back.
It have to do with #PB_Any and ID. An ID, created with #PB_Any is a MemoryPointer, but you can't use a MemoryPointer
to recreate a Gadget (or something else).

Re: Invalid memory access error

Posted: Mon Oct 26, 2015 9:07 pm
by captain_skank
OK Thanks for that.

I've now tried it with an enumerated constant - still get the same error.

Looks like i'll have to disable stuff and turn it on section by section until i find whats causing it :cry:

It's odd though because freeing the gadget and then regenerating works fine and repeatedly with both #pb_any and an enumerated constant, but once I open and close a sub form it stops working by throwing the memory error.

Anyhoo thanks for the pointers ( no pun intended ) :lol:

Re: Invalid memory access error

Posted: Tue Oct 27, 2015 3:57 am
by netmaestro
You're storing the return value of #PB_Any in a variable. Then you talk about opening and closing a sub form and then there's the memory error. Is it possible that you jumped into and/or out of a procedure in the course of doing this and lost your access to the variable because it was no longer within the same scope? You can easily determine if this is the case by finding the line it's dying on, and just before that debug your variable and see if it's zero and then End (so as not to crash on the next line). If it isn't zero, see if it can pass IsGadget(). You'll suss out the problem pretty quickly like this, just keep coming up with ideas and hack away.

Re: Invalid memory access error

Posted: Tue Oct 27, 2015 10:31 am
by captain_skank
OK, a judicious bit of hacking this morning has led me to what triggers the problem.

Firstly an explanation.

I have my main window which has a scrollareagadget which the user populates on the fly by adding records. when finished they press a button and a second window opens which displays status messages as an email is sent. when finished this returns to the main window which clears the frees the scrollareagadget and we can start again. ( i've simplified this )

No the email status window uses a thread to display the ongoing email status and it's this that seems to cause this invalid memory issue, because if i disable it and close the form manualy the main form doesn't thow the error and works as required.

My problem is, i need the thread otherwise the email status is not updated real time it just waits until the process is complete then updates the status in one hit.

I do use the isgadget function and that proves that gadget still exist's and i've tried using an enumerated gadget and a gadget using #pb_any but get the same error. i've also check to see if the thread is still open with isthread().

It's a real head scratcher and I can't post code as it relies on database access amongst other things.

Gonna have to find a way of displaying status without a thread i guess.

Re: Invalid memory access error

Posted: Tue Oct 27, 2015 10:45 am
by TI-994A
captain_skank wrote:...I can't post code as it relies on database access amongst other things.
Still, a glimpse of the code could help find the fault.

Fresh eyes. :wink:

Re: Invalid memory access error

Posted: Tue Oct 27, 2015 11:44 am
by captain_skank
Right then - took out the thread and a liberal spinkiling of

Code: Select all

While WindowEvent():Wend
to imitate the thread has fixed the issue.

However i'll post the two offending procedures ( although you won't be able to run them ) but as you say fresh eye :)

Code: Select all

Procedure window_send_email(start_date.i)

  Global window_send_email = OpenWindow(#PB_Any, 164, 63, 330, 230, "Sending request email", #PB_Window_BorderLess|#PB_Window_ScreenCentered)
  
  If window_send_email
    
    StickyWindow(window_send_email, #True)
    DisableWindow(window_main, #True)
    
    update_log_file("Sending request email - opened form ", window_send_email)
    
    width.i = WindowWidth(window_send_email)
    height.i = WindowHeight(window_send_email)
    
    Global GBL_send_email_background = window_background_icon_bar(window_send_email, #WIN_STANDARD, 0, 0, width, height, hex_decode(GBL_colour_scheme), "Sending request email", #yes, #yes, #yes, #no)
    
    Global btn_send_email_min.i = CanvasGadget(#PB_Any, width-50, 0, 20, 20)
      form_control_button(btn_send_email_min, icn_minimise)
      GadgetToolTip(btn_send_email_min, "Minimise")
    
    Global btn_send_email_close.i = CanvasGadget(#PB_Any, width-28, 0, 20, 20)
      form_control_button(btn_send_email_close, icn_close)
      GadgetToolTip(btn_send_email_close, "Close")
      
    gadget_GBL_display_row.i = 35
    
    fld_send_email_status = EditorGadget(#PB_Any , 15, gadget_GBL_display_row, 300, 160, #PB_Editor_WordWrap|#PB_Editor_ReadOnly)
      SetGadgetText(fld_send_email_status, "")
      
    gadget_GBL_display_row + 165
      
    fld_send_email_progress= ProgressBarGadget(#PB_Any , 15, gadget_GBL_display_row, WindowWidth(window_send_email)-30, 20, 0, 100, #PB_ProgressBar_Smooth)
    
    ; repaint the calling window
    RedrawWindow_(WindowID(window_send_email),#NUL,#NUL,#RDW_ALLCHILDREN|#RDW_INVALIDATE)
    
    While WindowEvent():Wend
    
  Else
    update_log_file("engineering_frm_time_manager - window_send_email, UNABLE TO OPEN ", window_main)   
    window_warning("PAPERCLIP Error", "Sorry I was unable to open the engineering_frm_time_manager - window_send_email." + Chr(13) + "It could be locked Or may Not exist", "YES", window_send_email, 200)
    End    
  EndIf
  
  timer = CreateThread(@send_emails(), start_date)
  
  window_send_email_status = 0
  
  Repeat
    Event = WaitWindowEvent()
    Select Event
          
      ; enable dragging of window
      Case #WM_LBUTTONDOWN
        SendMessage_(WindowID(window_send_email), #WM_NCLBUTTONDOWN, #HTCAPTION , #Null)
        
      Case #PB_Event_Gadget
       
        ;button events
        
        ;  /----------------------------------------------------------------\
        ;  |                    btn_send_email_min events                   |
        ;{ \----------------------------------------------------------------/ 
        If EventGadget() = btn_send_email_min
          
          gadget_id = btn_send_email_min 
          icon = icn_minimise
          
          Select EventType()
            Case #PB_EventType_MouseEnter
              form_control_button_over(gadget_id, $0000CC, icon)
      
            Case #PB_EventType_MouseLeave
              form_control_button_over(gadget_id, GBL_layer_border, icon)
      
            Case #PB_EventType_LeftButtonDown

            Case #PB_EventType_LeftButtonUp ; button up action
              form_control_button_over(gadget_id, GBL_layer_border, icon)
              SetWindowState(GetActiveWindow(), #PB_Window_Minimize)
      
          EndSelect
          ;}
          
          
        ;  /----------------------------------------------------------------\
        ;  |                   btn_send_email_close events                  |
        ;{ \----------------------------------------------------------------/ 

        ElseIf EventGadget() = btn_send_email_close
          
          gadget_id = btn_send_email_close
          icon = icn_close
          
          Select EventType()
            Case #PB_EventType_MouseEnter
              form_control_button_over(gadget_id, $0000CC, icon)
      
            Case #PB_EventType_MouseLeave
              form_control_button_over(gadget_id, GBL_layer_border, icon)
      
            Case #PB_EventType_LeftButtonDown
      
            Case #PB_EventType_LeftButtonUp ; button up action
              window_send_email_status = 1
               
          EndSelect
          
        EndIf  
        ;}
        
     EndSelect 
     
 Until window_send_email_status = 1
 
 DisableWindow(window_main, #False)
 StickyWindow(window_send_email, #False)
 CloseWindow(window_send_email)
 ; repaint the calling window
 RedrawWindow_(WindowID(window_main),#NUL,#NUL,#RDW_ALLCHILDREN|#RDW_INVALIDATE)
 SetActiveWindow(window_main)
 SetActiveGadget(-1) ; set no active gadget on active window

EndProcedure


Procedure send_emails(start_date)
  
  InitNetwork()

  If CreateMail(0, hex_decode(GBL_email_user), "")
    
    SetGadgetText(fld_send_email_status, "Composing email")
    
    SetMailAttribute(0, #PB_Mail_Subject, "Timesheet for approval")
    SetMailBody(0,  "A new timesheet has been submitted by " + hex_decode(GBL_forename) + "." + hex_decode(GBL_surname) + " for your approval." +  #CRLF$ + #CRLF$ + 
                    "This  timesheet is for the week begining " + FormatDate("%dd/%mm/%yyyy", start_date))
    
    SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + "Getting email recipients")
    
    ; build the sql query
    ; this query gets all the email adressees
    GBL_sql = "SELECT "
    GBL_sql +   "email_user "
    GBL_sql + "FROM "
    GBL_sql +   "tbl_user "
    GBL_sql + "WHERE "
    GBL_sql +   "ets_approval = 1 "
    
    ; Execute a SQL query
    If DatabaseQuery(0, GBL_sql)
        
      While NextDatabaseRow(0)
        ; Change the recipients to real one
        recipient.s = GetDatabaseString(0, 0)
        AddMailRecipient(0, recipient, #PB_Mail_To)
        SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + recipient)
      Wend
        
    Else
      window_warning("D A T A B A S E   E R R O R", GBL_sql + Chr(13) + Chr(13) + " This sql failed", "YES", window_send_email, 500) 
    EndIf
    
    Result = SendMail(0, "xxxx.xxxx.com", 25, 1, hex_decode(GBL_email_user), hex_decode(GBL_email_pass))
    
    SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + "Sending email - Please wait...")
    
    
    direction = 0
    
    Repeat
      Progress = MailProgress(0)
      Delay(300)
      If direction = 0
        SetGadgetState(fld_send_email_progress, GetGadgetState(fld_send_email_progress) + 10)
        If GetGadgetState(fld_send_email_progress) = 100
          direction = 1
        EndIf
      Else
        SetGadgetState(fld_send_email_progress, GetGadgetState(fld_send_email_progress) - 10)
        If GetGadgetState(fld_send_email_progress) = 0
          direction = 0
        EndIf

      EndIf
      Progress = MailProgress(0)
      Delay(300)
      Select progress
        Case #PB_Mail_Connected ; The mail transfer is in its initialization phase.
          SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + "Sending...")
        Case #PB_Mail_Finished ; The mail transfer is finished correctly.
          SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + "Finished")
        Case #PB_Mail_Error
          SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + " + + + E R R O R + + + ")
      EndSelect
        
    Until Progress = #PB_Mail_Finished Or Progress = #PB_Mail_Error
  
    If Progress = #PB_Mail_Finished
      SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + "Mail correctly sent")
      SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + "Updating time sheet status for selected week")
      ResetList(employee())               ; Reset the list index before the first element.
      
      GBL_sql = "UPDATE "
      GBL_sql +   "tbl_time_sheet "
      GBL_sql + "SET "
      GBL_sql +   "tbl_time_sheet.approved = 1 "
      GBL_sql + "WHERE "
      GBL_sql +   "tbl_time_sheet.project_day >= '" + FormatDate("%yyyy-%mm-%dd", start_date) + "' "
      GBL_sql +   "AND tbl_time_sheet.project_day <= '" + FormatDate("%yyyy-%mm-%dd", AddDate(start_date, #PB_Date_Day, 6 )) + "' "
      GBL_sql +   "AND tbl_time_sheet.user_name = '" + hex_decode(GBL_username) + "' "

	    ; Execute a SQL query
      If DatabaseQuery(0, GBL_sql)
        SetGadgetText(fld_send_email_status, GetGadgetText(fld_send_email_status) + Chr(13) + "Completed - refreshing display")
        get_user_open_projects(start_date)
      Else
        window_warning("D A T A B A S E   E R R O R", GBL_sql + Chr(13) + Chr(13) + " This sql failed", "YES", window_send_email, 500) 
      EndIf
    Else
      MessageRequester("Error", "Can't sent the mail !")
    EndIf
  
  EndIf
  
  window_send_email_status = 1
  
EndProcedure

Re: Invalid memory access error

Posted: Tue Oct 27, 2015 1:03 pm
by TI-994A
captain_skank wrote:...the email status window uses a thread to display the ongoing email status and it's this that seems to cause this invalid memory issue, because if i disable it and close the form manualy the main form doesn't thow the error and works as required.
Best guess; the thread is referencing a gadget that no longer exists. This means that the thread may be persisting after the window_send_email window has been closed.

Thus the IMA, instead of a gadget-not-initialised error. IMHO. :wink: