Stack Corruption

Just starting out? Need help? Post your questions and find answers here.
LiK137
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Jun 23, 2010 5:13 pm

Stack Corruption

Post by LiK137 »

Hi,
I noticed when using #PB_Any to return values there might be stack corruption during ProcedureReturn
But is there a method to pay attention to prevent such problems to continue using #PB_Any .



[17:16:21] Executable type: Windows - x64 (64bit, Unicode, Thread, Purifier)
[17:44:56] [ERROR] PGSelectAll2Array_v560.pb (Line: 857)
[17:44:56] [ERROR] Procedure stack has been corrupted.
[17:44:57] Execution continued.
[17:44:57] [ERROR] PGSelectAll2Array_v560.pb (Line: 859)
[17:44:57] [ERROR] Procedure stack has been corrupted.
[17:44:58] Execution continued.
[17:44:58] [ERROR] PGSelectAll2Array_v560.pb (Line: 860)
[17:44:58] [ERROR] Procedure stack has been corrupted.
[17:45:01] Execution continued.
[17:45:29] The debugged executable quit unexpectedly.

and code itself

Code: Select all

Procedure.l Hbitmap2PBImage(hbitmap.l) 
  ;-    pbImg.l = Hbitmap2PBImage(hbitmap.l)  
  ;-    Returns pbImg Handle from hBitmap
  ;-    Manually Release hBitmap and pbImg
  Protected *idb.PB_StructureDataBase
  GetObject_(hbitmap, SizeOf(BITMAP), @bm.BITMAP)
  If bm\bmBits
    *idb = CreateImage(#PB_Any, bm\bmWidth, bm\bmHeight, bm\bmBitsPixel)
    If IsImage(*idb)
      DeleteObject_(*idb\Bitmap)
      *idb\Bitmap = hbitmap
    EndIf
  EndIf
  ProcedureReturn *idb
EndProcedure


Procedure.l h2pbImg(hImg.l)
  
    Protected pbImg.l, pbImgTemp.l
    pbImgTemp=Hbitmap2PBImage(hImg)       ;Line857
    If IsImage(pbImgTemp)
      pbImg=ResizeImage(pbImgTemp, 30,30)  ;Line859
      DeleteObject_(pbImgTemp)                      ;Line860
    EndIf  
    ProcedureReturn pbImg
EndProcedure  


Thanx in Advance
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: Stack Corruption

Post by ts-soft »

Procedure.l ???

Procedure.i !!!
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
LiK137
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Jun 23, 2010 5:13 pm

Re: Stack Corruption

Post by LiK137 »

Does it mean I have to change Procedure.L to Procedure.i
or if You ask me (L or i) I used to return values then (L)
fryquez
Enthusiast
Enthusiast
Posts: 369
Joined: Mon Dec 21, 2015 8:12 pm

Re: Stack Corruption

Post by fryquez »

You should remove all these ".l". Or if you like it more replace them with ".i".

A long is to small to hold a handle on x64.
normeus
Enthusiast
Enthusiast
Posts: 415
Joined: Fri Apr 20, 2012 8:09 pm
Contact:

Re: Stack Corruption

Post by normeus »

search help for:

Code: Select all

UserGuide - Dynamic numbering of windows and gadgets using #PB_Any
I think that section of help calls #PB_Any an "integer" type.

From ts-soft:

??? <------ = why are you ussing this???

!!! <------ = you have to use this!!!


Norm.
google Translate;Makes my jokes fall flat- Fait mes blagues tombent à plat- Machte meine Witze verpuffen- Eh cumpari ci vo sunari
LiK137
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Jun 23, 2010 5:13 pm

Re: Stack Corruption

Post by LiK137 »

Huge thanx to ts-soft and all who replied.
U R absolutely right as in 32bit there never been overflows and this is 1st my adaptation of 1 of x86 source to x64.
Thanx, U R great.
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: Stack Corruption

Post by ts-soft »

normeus wrote:From ts-soft:

??? <------ = why are you ussing this???

!!! <------ = you have to use this!!!
You are right, thank you.
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
LiK137
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Jun 23, 2010 5:13 pm

Re: Stack Corruption

Post by LiK137 »

I have changed step by step until crash gone (by now but have to test more to be sure)

The only (for now that I discovered after crash gone) is according to code:

Code: Select all

Declare.i GetBlobImg(dbSession, guid.s)
Declare PrintImg(dbSession, guid$)
Declare.i imgm_InvertColors(iMg.i)
Declare.i GRAY(iMg.i)     ; Ctrl+G
#imGad=10

;{ Problemmy
Procedure.i GetBlobImg(dbSession, guid.s)
  
    Protected imgMemBlobSize, imgMemCMPsize
    
    If DatabaseQuery(dbSession,"SELECT * FROM imgTbl WHERE LOWER(guid)='"+LCase(guid)+"' LIMIT 1")
      Protected  imgColIndex.l=DatabaseColumnIndex(dbSession,"img")
      
      If imgColIndex>=0
        NextDatabaseRow(dbSession)
      
        imgMemBlobSize=DatabaseColumnSize(dbSession,imgColIndex)
        If imgMemBlobSize
          Protected *imgMem = AllocateMemory(imgMemBlobSize)
          GetDatabaseBlob(dbSession,imgColIndex,*imgMem,imgMemBlobSize)
          Protected iMg.i=CatchImage(#PB_Any,*imgMem) 
          FreeMemory(*imgMem)
        EndIf
      EndIf
      FinishDatabaseQuery(dbSession)
    EndIf
    
    ProcedureReturn iMg
    
EndProcedure
  

  
Procedure PrintImg(dbSession, guid$)
  Protected tmpImg.i, iMg.i=GetBlobImg(dbSession, guid$)
  If IsImage(iMg)     ; change path/filename to your own 32x32 pixel image
    tmpImg = GRAY(iMg)
    FreeImage(iMg)
    iMg=imgm_InvertColors(tmpImg)
    If IsImage(iMg)
      SaveImage(iMg,Path.s);SetGadgetState(#imGad, ImageID(iMg)):SetActiveGadget(#imGad)
      FreeImage(iMg)
    EndIf
    If IsImage(tmpImg)
      FreeImage(tmpImg)
    EndIf  
  EndIf
  
EndProcedure  
;}  

;{  Working
Structure myBITMAPINFO
  bmiHeader.BITMAPINFOHEADER
  bmiColors.RGBQUAD[1]
EndStructure 

Procedure.i imgm_InvertColors(iMg.i)
  ;Invert the colors
   Protected tmpImg.i=CopyImage(iMg, #PB_Any)
   hBmp=ImageID(tmpImg)
  
  If hBmp 
    
    imageWidth=ImageWidth(tmpImg)
    imageHeight=ImageHeight(tmpImg)
    
    mem=AllocateMemory(imageWidth*imageHeight*4)
    bmi.myBITMAPINFO 
    bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
    bmi\bmiHeader\biWidth = imageWidth
    bmi\bmiHeader\biHeight = imageHeight
    bmi\bmiHeader\biPlanes = 1
    bmi\bmiHeader\biBitCount = 32
    bmi\bmiHeader\biCompression = #BI_RGB 
    
    hdc = StartDrawing(ImageOutput(tmpImg))
    Debug hdc
    GetDIBits_(hdc,hBmp,0,imageHeight,mem,bmi,#DIB_RGB_COLORS)
    
    *pixels.LONG = mem
    For A = 1 To imageWidth*(imageHeight)
      *pixels\l - *pixels\l - *pixels\l
      *pixels + 4
    Next A
    
  SetDIBits_(hdc,hBmp,0,imageHeight,mem,bmi,#DIB_RGB_COLORS) ;<> 0
  StopDrawing()
  ProcedureReturn tmpImg
EndIf

EndProcedure

Procedure.i GRAY(iMg.i)     ; Ctrl+G
   ; reduce colors to 256 grayscale
   ; color weights are R=0.286, G=0.571, B=0.143
   
   Static kb=$FF0000, kg=$00FF00, kr=$0000FF
   Protected x,y,d,Ymax,Xmax,lum
   
   Protected tmpImg.i=CopyImage(iMg, #PB_Any)

   If IsImage(tmpImg)
      
      StartDrawing(ImageOutput(tmpImg))
         Xmax = OutputWidth() - 1
         Ymax = OutputHeight() - 1
         
         For y = 0 To Ymax
            For x = 0 To Xmax
               d = Point(x,y)
               lum = ((d & kr)<<1 + (d & kg)>>6 + (d & kb)>>16) / 7
               Plot(x,y,lum<<16 | lum<<8 | lum)
            Next x
         Next y
      StopDrawing()
      
   EndIf
   
   ProcedureReturn tmpImg
   
   EndProcedure  
;}
I can get image from Database Blob only 22-23 times.
After that procedure doesn't return any value as it reaches maximum.


And handles (got by debugging) returned from GetBlobImg are strange.
As shown below,

GetBlobImg procedure return 8 symbol PB image handle (which seems ok and image applied to mageGadget ) for a while.

31498464
31498704
31498864
.
.
.
31501904

then the ImageHandle is returned 10 symbols (which makes image not shown in Gadget) for a while.

2760892400
2760892560
2760892720
.
,
,
2495609856
2495610016
2495610176

And then these handles again returned 8 Synvols and become OK to load ImageHandle to Window.
353089408
353089568
353089728
353089888
.
.
.
353099808
353099968
353100128
353100288
353100448
353100608
normeus
Enthusiast
Enthusiast
Posts: 415
Joined: Fri Apr 20, 2012 8:09 pm
Contact:

Re: Stack Corruption

Post by normeus »

It has to do with freeing images which you no longer have a pointer to and pointers that cannot be released because you are using them on another procedure.

Easiest solution:
Make some of those tmpImg global so that you know it is only one temp image you are using, releasing and allocating again.



Norm.
google Translate;Makes my jokes fall flat- Fait mes blagues tombent à plat- Machte meine Witze verpuffen- Eh cumpari ci vo sunari
LiK137
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Jun 23, 2010 5:13 pm

Re: Stack Corruption

Post by LiK137 »

Thanx, Global way is not suitable.
FreeImage releases the handle and it becomes invalid for any process continuing using that.
After FreeImage (I do check with IsImage to be sure that Handle is released), any new handle assigned to the new created image is growing. This new handle when becomes 10 digits even is valid but cannot be handled for use.
So how control this handle to stay 8 digits or make usable this 10 digit handle.
Because, even 10 digit handle I can use for SaveImage but not for ImageGadget.
Post Reply