July 09, 2020, 10:44:09 AM

Author Topic: BlitzMaxNG Garbage collector issues  (Read 523 times)

Offline Ashmoor

  • Jr. Member
  • **
  • Posts: 52
BlitzMaxNG Garbage collector issues
« on: June 14, 2020, 09:00:08 PM »
I have some code that updates an image pixel by pixel

Code: BlitzMax
  1.         For Local i:Int = 0 Until h
  2.                 For Local j:Int = 0 Until w
  3.                         pixel = ReadPixel(basePM, j, i)
  4.                         'imgPixel = GetRGBvectorFromPixel(pixel)
  5.                         GetRGBvectorFromPixel1(pixel, imgPixel)
  6.                         imgPixel.DarkenByPercent(alpha)
  7.                         pixel = GetPixelFromRGBvector(imgPixel)
  8.                         WritePixel(finalPM, j, i, pixel)
  9.                 Next
  10.         Next
  11.  

After running it 3-4 times in a row, I get "exception access violation" unless I use GCSuspend() before and GCResume() after.

How exactly does the garbage collector work and how can I ensure it doesn't mess my color operations?

Offline Derron

  • Hero Member
  • *****
  • Posts: 3034
Re: BlitzMaxNG Garbage collector issues
« Reply #1 on: June 15, 2020, 06:35:21 AM »
Run in debug mode to see which variable became null.

I assume your imgPixel somewhere becomes null...and you access its not existing properties.

Bye
Ron

Offline Ashmoor

  • Jr. Member
  • **
  • Posts: 52
Re: BlitzMaxNG Garbage collector issues
« Reply #2 on: June 15, 2020, 07:33:13 AM »
Debug shows nothing, I just get EAV and app closes. It happens in other areas of the program and I can't track what is causing it.

Here is a video of how it happens. I press W a few times to set the wallpaper. You can see my print checkpoints since debug shows nothing.
https://drive.google.com/file/d/16nOH3nKE1JwjF9ns4jEr9OviFI2gOsC4/view?usp=sharing

Offline Derron

  • Hero Member
  • *****
  • Posts: 3034
Re: BlitzMaxNG Garbage collector issues
« Reply #3 on: June 15, 2020, 07:44:31 AM »
Recompile all modules for "debug" but enable "gdb" before. Then recompile your application with "debug + gdb" too. After compilation you execute your programme (it is there "MinGW's gcc" is installed):

path/to/gdb -r mybinary.exe

it starts, type in "r" to execute your binary.
When your binary is crashing ... type in "bt" to see where in the BlitzMax code it crashed.


A crash not catched by the BlitzMax debugger normally means it happens somewhere in the "C"-Codes.


bye
Ron

Offline Ashmoor

  • Jr. Member
  • **
  • Posts: 52
Re: BlitzMaxNG Garbage collector issues
« Reply #4 on: June 15, 2020, 08:20:35 AM »
Quote
Recompile all modules for "debug" but enable "gdb" before.

How do I do that? I checked "Program/developer options/GDB debug generation" and then "program/build modules". Is that how it should be?

Offline Derron

  • Hero Member
  • *****
  • Posts: 3034
Re: BlitzMaxNG Garbage collector issues
« Reply #5 on: June 15, 2020, 07:39:55 PM »
Yes ... so it did rebuild all the modules ?

Then recompile your app (non quick) with the same settings - then run gdb -r your binaryname

bye
Ron

Offline Ashmoor

  • Jr. Member
  • **
  • Posts: 52
Re: BlitzMaxNG Garbage collector issues
« Reply #6 on: June 15, 2020, 09:01:21 PM »
this is what i got
Quote
[New Thread 24932.0x1804]
[New Thread 24932.0x3f28]
[New Thread 24932.0x5a8]
[New Thread 24932.0x5124]
[New Thread 24932.0x6f18]
[New Thread 24932.0x3018]
[New Thread 24932.0x7c34]
[New Thread 24932.0x57d8]
[New Thread 24932.0x796c]
[New Thread 24932.0x4db8]
[New Thread 24932.0x734]
[New Thread 24932.0x3990]
[New Thread 24932.0x3924]
[Thread 24932.0x3924 exited with code 0]
[New Thread 24932.0xbf8]
[New Thread 24932.0x65d8]
[New Thread 24932.0x289c]
[New Thread 24932.0x7dfc]
warning: onecore\com\combase\objact\objact.cxx(836)\combase.dll!75E5C59C: (caller: 75E5B56B) ReturnHr(1) tid(1804) 800401F0 CoInitialize has not been called.
[New Thread 24932.0x7954]
[New Thread 24932.0x44b0]
[New Thread 24932.0x2cc4]
[New Thread 24932.0x7f6c]
[New Thread 24932.0x3a18]
[Thread 24932.0x7f6c exited with code 0]
[Thread 24932.0x3a18 exited with code 0]
[Thread 24932.0x2cc4 exited with code 0]
[New Thread 24932.0x7398]
[New Thread 24932.0x6d8c]
[New Thread 24932.0x67a8]
[New Thread 24932.0x68dc]
[New Thread 24932.0x22e4]
[New Thread 24932.0x3f14]
[New Thread 24932.0x62d0]
[New Thread 24932.0x7a08]

Thread 1 received signal SIGSEGV, Segmentation fault.
0x0061d434 in ?? ()
(gdb) bt
#0  0x0061d434 in ?? ()
#1  0xf8e483ec in ?? ()
#2  0x64084d8b in ?? ()
#3  0x0018158b in ?? ()
Backtrace stopped: Cannot access memory at address 0x8b55ff8f

I dont know what this means or where to look for in the code. My code came from Blitzmax Vanilla and should not be threaded. I don't know if the "new thread" messages mean that it's trying to be threaded.

Offline Derron

  • Hero Member
  • *****
  • Posts: 3034
Re: BlitzMaxNG Garbage collector issues
« Reply #7 on: June 16, 2020, 07:05:00 AM »
hmm "normally" the "bt" command would contain elements with additional information (source code position). So ... maybe it is something in the threads.

"NG" is threaded by default ... so if your code somewhere has
Code: [Select]
?threaded
do something
?not threaded
do something else
?
Then this is now running "do something" while it runs "do something else" in vanilla.


More interesting is this:
Code: [Select]
warning: onecore\com\combase\objact\objact.cxx(836)\combase.dll!75E5C59C: (caller: 75E5B56B) ReturnHr(1) tid(1804) 800401F0 CoInitialize has not been called.

What happens if you do not use this thing / lib ?


bye
Ron

Offline Ashmoor

  • Jr. Member
  • **
  • Posts: 52
Re: BlitzMaxNG Garbage collector issues
« Reply #8 on: June 16, 2020, 08:37:35 AM »
My code has nothing ?threaded. Is there a way to set not threaded by default?

Quote
What happens if you do not use this thing / lib ?

I don't know who calls that lib. How can I find out?

Below is a sample code that crashes in a similar way to my main app. You can replace "p1_wallpaper.bmp" with any image you want.

Code: BlitzMax
  1. SuperStrict
  2.  
  3.  
  4.  
  5. Global myImg:TImage=LoadImage("graphics/p1_wallpaper.bmp")
  6.  
  7. Const BI_RGB:Int = 0
  8.  
  9. Const SPI_SETDESKWALLPAPER:Int = 20
  10. Const SPIF_UPDATEINIFILE:Int = 01
  11.  
  12.  
  13. '-----------------------------------------
  14. '
  15. ' save an image as a bmp file
  16. '
  17. '------------------------------------------
  18. Global  bfh_Type:Short
  19. Global  bfh_Size:Int
  20. Global  bfh_Reserved:Int = 0
  21. Global  bfh_OffBits:Int
  22.  
  23. Global bfh_header_size:Int = 2 + 4 + 4 + 4
  24. Global cnt#=0
  25.  
  26. '----------------------------------------------------------------
  27.  
  28. '----------------------------------------------------------------
  29.  
  30.  
  31. Global wallPath$=CurrentDir()+"/graphics/savedwallpp.bmp"
  32. Print wallPath
  33. Print "proc wp:"+(CurrentDir()+"/graphics/savedwallpp.bmp")
  34. Global blackAlpha:Float=0.2
  35.  
  36. Graphics 800,600
  37. SetBlend ALPHABLEND
  38.  
  39. Repeat
  40.         Cls
  41.                 DrawImage (myImg,0,0)
  42.                 SetAlpha (blackAlpha)
  43.                 SetColor(0,0,0)
  44.                 DrawRect(0,0,800,600)
  45.                 SetColor(255,255,255)
  46.                 SetAlpha(1.0)
  47.         Flip
  48.        
  49.         If KeyHit(KEY_ESCAPE) Or AppTerminate() Then End
  50.         If KeyHit(KEY_W) Then
  51.                 'GCSuspend()
  52.                 SaveBitmapFromImage(AddBlackToImage(myImg,blackAlpha))         
  53.                 Wallpaper_Set(wallPath) 'CurrentDir()+"/graphics/savedwallpp.bmp"              
  54.                 cnt:+1
  55.                 'GCResume()
  56.         EndIf
  57.  
  58.         If KeyHit (KEY_P) Then blackAlpha:+0.1
  59.         If KeyHit(KEY_O) Then blackAlpha:-0.1  
  60.        
  61.  
  62.        
  63. Forever
  64.  
  65.  
  66. SaveBitmapFromImage(AddBlackToImage( myImg))
  67. Wallpaper_Set(wallPath) 'CurrentDir()+"/graphics/savedwallpp.bmp"
  68.  
  69. Wallpaper_Set(wallPath) 'CurrentDir()+"/graphics/savedwallpp.bmp"
  70.  
  71. '----------------------------------------------------------------
  72.  
  73.  
  74.  
  75. Extern "Win32"
  76.         Function SystemParametersInfo:Int(action:Int, param:Int, vparam:Byte Ptr, winini:Int) "win32"="WINBOOL __stdcall  SystemParametersInfo(UINT ,UINT ,PVOID ,UINT )!" '"SystemParametersInfoA@16"
  77.         Function SystemParametersInfoW:Int(uiAction:UInt, uiParam:UInt, pvParam:Byte Ptr, fWinIni:UInt) "win32"="WINBOOL __stdcall  SystemParametersInfoW(UINT ,UINT ,PVOID ,UINT )!"
  78.         'Function GetLastError() = "GetLastError@0"
  79. End Extern
  80.  
  81. Function Wallpaper_Set(filename:Byte Ptr)
  82. 'note: filename must be real path of the image, not truncated relative path.
  83.         Print "filename:"+filename[0]
  84.         Local res:Int   'this is to check if the wallpaper was set or an error happened
  85.         res=SystemParametersInfo(SPI_SETDESKWALLPAPER, Null, filename, SPIF_UPDATEINIFILE)
  86.         Print "res:"+res
  87.        
  88. EndFunction
  89.  
  90.  
  91.  
  92. Type BitmapInfoHeader
  93.         Field   biSize:Int
  94.         Field   biWidth:Int
  95.         Field   biHeight:Int
  96.         Field   biPlanes:Short
  97.         Field   biBitCount:Short
  98.         Field   biCompression:Int
  99.         Field   biSizeImage:Int
  100.         Field   biXPelsPerMeter:Int
  101.         Field   biYPelsPerMeter:Int
  102.         Field   biClrUsed:Int
  103.         Field   biClrImportant:Int
  104. EndType
  105.  
  106.  
  107.  
  108. 'Summary: Writes an TImage to an open file stream as a BMP format.
  109. Function Img_ToBmp:Int(img:TImage, file:TStream)
  110.         Local pxmp:TPixmap, x:Int, y:Int, ptr1:Byte Ptr
  111.         Local r:Int, g:Int, b:Int
  112.         Local bank1:TBank, size:Int
  113.         Local file_size:Int, data_size:Int
  114.         Local bih:BitmapInfoHeader=New BitmapInfoHeader
  115.        
  116.         Print "ImgToBMP start"
  117.        
  118.         pxmp = LockImage(img, , True, False)
  119.         If (pxmp = Null)
  120.                 Return False
  121.         EndIf
  122.        
  123.         file = LittleEndianStream(file)
  124.        
  125.         If (pxmp.format <> PF_BGR888)
  126.                 pxmp = pxmp.Convert(PF_BGR888)
  127.         EndIf
  128.        
  129.         ptr1 = pxmp.pixels
  130.        
  131.         data_size = pxmp.height * pxmp.pitch
  132.         file_size = data_size + bfh_header_size + SizeOf(bih)
  133.        
  134.         'go at start of file
  135.         SeekStream(file, 0)
  136.        
  137.         'write file header
  138.        
  139.         bfh_Type = Asc("B") + ( Asc("M") Shl 8 )
  140.         WriteShort(file, bfh_Type)
  141.        
  142.         bfh_Size = file_size
  143.         WriteInt(file, bfh_Size)
  144.        
  145.         bfh_Reserved = 0
  146.         WriteInt(file, bfh_Reserved)
  147.        
  148.         bfh_OffBits= bfh_header_size + SizeOf(bih)
  149.         WriteInt(file, bfh_OffBits)
  150.        
  151.        
  152.         'write info header
  153.         bih = New BitmapInfoHeader
  154.         bih.biSize = SizeOf(bih)
  155.         bih.biWidth = pxmp.width
  156.         bih.biHeight = pxmp.height
  157.         bih.biPlanes = 1
  158.         bih.biBitCount = 24
  159.         bih.biCompression = BI_RGB
  160.         bih.biSizeImage = data_size
  161.         bih.biXPelsPerMeter = 2835
  162.         bih.biYPelsPerMeter = 2835
  163.         bih.biClrUsed = 0
  164.         bih.biClrImportant = 0
  165.         bank1 = CreateStaticBank(bih, SizeOf(bih) )
  166.         WriteBank(bank1, file, 0, SizeOf(bih) )
  167.        
  168.         'write it top-down
  169.         ptr1 :+ (data_size - pxmp.pitch)
  170.         For y = 0 Until pxmp.height
  171.                
  172.                 bank1 = CreateStaticBank(ptr1, pxmp.pitch )
  173.                 WriteBank(bank1, file, 0, pxmp.pitch )
  174.                
  175.                 ptr1 :- pxmp.pitch
  176.         Next
  177.        
  178.        
  179.         UnlockImage(img)
  180.         Print "imgTOBMP done"
  181.         Return True
  182. EndFunction
  183.  
  184.  
  185. 'Summary: Opens a stream and writes ssImg to it as BMP format.
  186. Function SaveBitmapFromImage(ssImg:TImage)
  187. 'note: this will save a bmp to my roaming file.
  188.         Print "SBFI start"
  189.         Local path:String
  190.         Local file:TStream
  191.        
  192.         path = "graphics/savedwallpp.bmp"
  193.         file = OpenFile(path)
  194.        
  195.         'make sure there is no wallpaper of this name already
  196.         If file <> Null Then
  197.                 CloseStream(file)
  198.                 DeleteFile(path)
  199.         EndIf
  200.         CreateFile(path)
  201.         file = WriteFile(path)
  202.        
  203.         Img_ToBmp(ssImg, file)
  204.        
  205.         Print path + " image was created"
  206.        
  207.         CloseStream(file)
  208.        
  209. End Function
  210.  
  211.  
  212.  
  213. Function AddBlackToImage:TImage(img:TImage, alpha:Float=0.3)
  214. 'alpha is in the transparency with witch the black box is drawn on top
  215.         Print "add black to img start"
  216.         Local w:Int = ImageWidth(img)
  217.         Local h:Int = ImageHeight(img)
  218.        
  219.         Local r:Float, g:Float, b:Float
  220.         Local pixel:Int
  221.         Local imgPixel:TRGBvector= New TRGBvector
  222.        
  223.         Local basePM:TPixmap = TPixmap.Create(w, h, PF_RGB888)
  224.         Local finalPM:TPixmap = TPixmap.Create(w, h, PF_RGB888)
  225.        
  226.         Print "here1"
  227.        
  228.         basePM = LockImage(img)
  229.         UnlockImage(img)
  230.        
  231.         Print "here2"
  232.         For Local i:Int = 0 Until h
  233.                 For Local j:Int = 0 Until w
  234.                         pixel = ReadPixel(basePM, j, i)
  235.                         'imgPixel = GetRGBvectorFromPixel(pixel)
  236.                         GetRGBvectorFromPixel1(pixel, imgPixel)
  237.                         imgPixel.DarkenByPercent(alpha)
  238.                         pixel = GetPixelFromRGBvector(imgPixel)
  239.                         WritePixel(finalPM, j, i, pixel)
  240.                 Next
  241.         Next
  242.         Print "here3"
  243.         Local retImg:TImage = LoadImage(finalPM)
  244.        
  245.         Print "add black to img done"
  246.        
  247.         Return retImg
  248.        
  249. End Function
  250.  
  251.  
  252. Type TRGBvector
  253.         Field r:Float
  254.         Field g:Float
  255.         Field b:Float
  256.        
  257.         Method DrawSelf()
  258.                 Local rStr:String
  259.                 Local gStr:String
  260.                 Local bStr:String
  261.                
  262.                 rStr = r
  263.                 rStr = rStr[..5]
  264.                 gStr = g
  265.                 gStr = gStr[..5]
  266.                 bStr = b
  267.                 bStr = bStr[..5]
  268.                
  269.                 DrawText("r:" + rStr + " g:" + gStr + " b:" + bStr, 10, 30)
  270.                
  271.         End Method
  272.        
  273.         'Summary: Adds a little bit of black into
  274.         Method DarkenByPercent(alpha:Float)
  275.         'This is equivalent to drawing a black pixel on top of current one using "alpha" transparncy
  276.                 r = Truncate255(r - (r * alpha))
  277.                 g = Truncate255(g - (g * alpha))
  278.                 b = Truncate255(b - (b * alpha))
  279.         EndMethod
  280.        
  281.         'Summary: Tweaks brightness of all channels (-1 to 1)
  282.         Method AdjustBrightness(br:Float)
  283.         'This will add/remove a percent of each channel, acting somewhat like overlay layer.
  284.         'it is not perfect because on the negative side of the curve it should
  285.         'remove a percent of the missing value
  286.         'eg: 245 has 10 missing so at br=-1.0 it should be -235, that woud be similar to the br>0
  287.                
  288.                 r = Truncate255(r + (r * br))
  289.                 g = Truncate255(g + (g * br))
  290.                 b = Truncate255(b + (b * br))
  291.                
  292.         EndMethod
  293.        
  294.         'Summary: Sets RGB values
  295.         Method SetRGB:Int(re:Int, gr:Int, bl:Int)
  296.                 r = re
  297.                 g = gr
  298.                 b = bl
  299.         End Method
  300.        
  301. EndType
  302.  
  303.  
  304. 'Summary: Returns RGBvector from int pixel value
  305. Function GetRGBvectorFromPixel:TRGBvector(rgb:Int)
  306.         If cnt>=1 Then Print "here 4"
  307.         Local rgbV:TRGBvector= New TRGBvector
  308.         If cnt>=1 Then Print "here 5"
  309.         Local r:Float = ((rgb Shr 16) & $ff) / 255:Float
  310.         Local g:Float = ((rgb Shr 8) & $ff) / 255:Float
  311.         Local b:Float = ((rgb) & $ff) / 255:Float
  312.        
  313.         r = r * 255; g = g * 255; b = b * 255
  314.        
  315.         rgbV.r = r; rgbV.g = g; rgbV.b = b
  316.        
  317.         Return rgbV
  318.        
  319. End Function
  320.  
  321. 'Summary: Returns RGBvector from int pixel value
  322. Function GetRGBvectorFromPixel1(rgb:Int, rgbV:TRGBvector Var)
  323.        
  324.         Local r:Float = ((rgb Shr 16) & $ff) / 255:Float
  325.         Local g:Float = ((rgb Shr 8) & $ff) / 255:Float
  326.         Local b:Float = ((rgb) & $ff) / 255:Float
  327.        
  328.         r = r * 255; g = g * 255; b = b * 255
  329.        
  330.         rgbV.r = r; rgbV.g = g; rgbV.b = b
  331.        
  332. End Function
  333.  
  334.  
  335. 'Summary: truncates a value to the interval [0,255]
  336. Function Truncate255:Float(val:Float)
  337.         If val < 0 Then val = 0
  338.         If val > 255 Then val = 255
  339.        
  340.         Return val
  341. End Function
  342.  
  343. Function GetPixelFromRGBvector:Int(vec:TRGBvector)
  344.         Local pixel:Int
  345.  
  346.         Local r:Int = vec.r
  347.         Local g:Int = vec.g
  348.         Local b:Int = vec.b
  349.        
  350.         pixel = $ff000000 | (r Shl 16) | (g Shl 8) | b
  351.  
  352.        
  353.         Return pixel
  354.  
  355. End Function
  356.  

Offline Derron

  • Hero Member
  • *****
  • Posts: 3034
Re: BlitzMaxNG Garbage collector issues
« Reply #9 on: June 16, 2020, 09:05:39 AM »
Will check on a Windows machine later - but for now little "hints":

Code: BlitzMax
  1.         'Summary: Sets RGB values
  2.         Method SetRGB:Int(re:Int, gr:Int, bl:Int)
  3.                 r = re
  4.                 g = gr
  5.                 b = bl
  6.         End Method
  7.  

can become

Code: BlitzMax
  1.         'Summary: Sets RGB values
  2.         Method SetRGB:Int(r:Int, g:Int, b:Int)
  3.                 self.r = r
  4.                 self.g = g
  5.                 self.b = b
  6.         End Method
  7.  


Code: BlitzMax
  1.         file = OpenFile(path)
  2.        
  3.         'make sure there is no wallpaper of this name already
  4.         If file <> Null Then
  5.                 CloseStream(file)
  6.                 DeleteFile(path)
  7.         EndIf
  8.         CreateFile(path)
  9.         file = WriteFile(path)
  10.  

Why not simply try to "DeleteFile(path)" before "CreateFile(path)" or do a "If FileType(path) = FILETYPE_FILE Then DeleteFile(path)" ? Both variants (mine and yours) only check if "file" can be opened, not if writeable).
https://blitzmax.org/docs/en/api/brl/brl.filesystem/#function-writefiletstream-urlobject-
checkout the example there.

"WriteFile" (which is equal to "WriteStream") is already what you are looking for: open/creating a file (and result is "Null" if it fails to do so)
Code: BlitzMax
  1. SuperStrict
  2.  
  3. Framework Brl.StandardIO
  4. Import Brl.FileSystem
  5.  
  6. For local i:int = 0 until 10
  7.         local f:TStream = WriteFile("hi.txt")
  8.         f.WriteString(i)
  9.         CloseFile(f)
  10. Next
  11.  
  12. Local f:TStream = ReadFile("hi.txt")
  13. While Not Eof(f)
  14.     Print ReadLine(f)
  15. Wend
  16.  

Will output "9".


Code: BlitzMax
  1. 'Summary: Opens a stream and writes ssImg to it as BMP format.
  2. Function SaveBitmapFromImage(ssImg:TImage)
  3. 'note: this will save a bmp to my roaming file.
  4.         Print "SBFI start"
  5.         Local path:String
  6.         Local file:TStream
  7.        
  8.         path = "graphics/savedwallpp.bmp"
  9.         file = OpenFile(path)
  10.        
  11.         'make sure there is no wallpaper of this name already
  12.         If file <> Null Then
  13.                 CloseStream(file)
  14.                 DeleteFile(path)
  15.         EndIf
  16.         CreateFile(path)
  17.         file = WriteFile(path)
  18.        
  19.         Img_ToBmp(ssImg, file)
  20.        
  21.         Print path + " image was created"
  22.        
  23.         CloseStream(file)
  24.        
  25. End Function
  26.  

Could then become:
Code: BlitzMax
  1. 'Summary: Opens a stream and writes ssImg to it as BMP format.
  2. Function SaveBitmapFromImage:Int(ssImg:TImage)
  3. 'note: this will save a bmp to my roaming file.
  4.         Print "SBFI start"
  5.         Local path:String = "graphics/savedwallpp.bmp"
  6.         'create new or open to overwrite content
  7.         Local file:TStream = WriteFile(path)
  8.         If Not file
  9.                 Print "Failed to open existing or to create new file ~q" + path + "~q for writing."
  10.                 Return False
  11.         Else
  12.                 If Img_ToBmp(ssImg, file)
  13.                         Print path + " image was created"
  14.                         CloseStream(file)
  15.                         Return True
  16.                 EndIf
  17.        EndIf
  18. End Function
  19.  


bye
Ron

Offline Derron

  • Hero Member
  • *****
  • Posts: 3034
Re: BlitzMaxNG Garbage collector issues
« Reply #10 on: June 16, 2020, 09:15:13 AM »
Code: BlitzMax
  1.  
  2. Function AddBlackToImage:TImage(img:TImage, alpha:Float=0.3)
  3. 'alpha is in the transparency with witch the black box is drawn on top
  4.         Print "add black to img start"
  5.         Local w:Int = ImageWidth(img)
  6.         Local h:Int = ImageHeight(img)
  7.        
  8.         Local r:Float, g:Float, b:Float
  9.         Local pixel:Int
  10.         Local imgPixel:TRGBvector= New TRGBvector
  11.        
  12.         Local basePM:TPixmap = TPixmap.Create(w, h, PF_RGB888)
  13.         Local finalPM:TPixmap = TPixmap.Create(w, h, PF_RGB888)
  14.        
  15.         Print "here1"
  16.        
  17.         basePM = LockImage(img)
  18.         UnlockImage(img)
  19.        
  20.         Print "here2"
  21.         For Local i:Int = 0 Until h
  22.                 For Local j:Int = 0 Until w
  23.                         pixel = ReadPixel(basePM, j, i)
  24.                         'imgPixel = GetRGBvectorFromPixel(pixel)
  25.                         GetRGBvectorFromPixel1(pixel, imgPixel)
  26.                         imgPixel.DarkenByPercent(alpha)
  27.                         pixel = GetPixelFromRGBvector(imgPixel)
  28.                         WritePixel(finalPM, j, i, pixel)
  29.                 Next
  30.         Next
  31.         Print "here3"
  32.         Local retImg:TImage = LoadImage(finalPM)
  33.        
  34.         Print "add black to img done"
  35.        
  36.         Return retImg
  37.        
  38. End Function
  39.  

Does something unnecessary: Creating "basePM" with then just overriding it some steps later. also "LockImage" for now just returns the pixmap and does nothing more - so "UnlockImage" is not really necessary. BUT ... if it somewhen does something and you plan to alter the pixmap you extracted, then "UnlockImage()" should be called _after_ you manipulated the content.


Code: BlitzMax
  1.         Local basePM:TPixmap = TPixmap.Create(w, h, PF_RGB888)
  2.         Local finalPM:TPixmap = TPixmap.Create(w, h, PF_RGB888)
  3.        
  4.         Print "here1"
  5.        
  6.         basePM = LockImage(img)
  7.         UnlockImage(img)
  8.  
becomes
Code: BlitzMax
  1.         Local basePM:TPixmap = LockImage(img)
  2.         Local finalPM:TPixmap = TPixmap.Create(w, h, PF_RGB888)
  3.        
  4.         Print "here1"
  5.        
  6.         UnlockImage(img)
  7.  



But to your problem: what happens if you comment out "Wallpaper_Set()" in (When hitting "W") ... does it then run as it should?

If it works: then maybe this command runs "threaded" (from Windows then). This would mean:
- 00.00s: you write to a file ...
- 00.01s: you tell windows to set the wallpaper -> new thread
- 00.02s: command "fired"
- 00.09s: thread of windows plans to open file to set the wallpaper
- 00.10s: next "w" hit ... write to a file ....
- 00.11s: thread and your app want to modify the file - one fails as handle is not valid (you did not check for it)

In that case we might add some more "validity" checks


bye
Ron

Offline Ashmoor

  • Jr. Member
  • **
  • Posts: 52
Re: BlitzMaxNG Garbage collector issues
« Reply #11 on: June 16, 2020, 09:51:05 AM »
Thanks for the hints, it will take me a little bit to digest.

Offline Ashmoor

  • Jr. Member
  • **
  • Posts: 52
Re: BlitzMaxNG Garbage collector issues
« Reply #12 on: June 16, 2020, 01:44:34 PM »
Quote
But to your problem: what happens if you comment out "Wallpaper_Set()" in (When hitting "W") ... does it then run as it should?

Nope, it still crashes. It does not crash if I uncomment GCSuspend()

Offline Derron

  • Hero Member
  • *****
  • Posts: 3034
Re: BlitzMaxNG Garbage collector issues
« Reply #13 on: June 16, 2020, 04:37:08 PM »
NG's GC is a different one..... It is better in handling cyclic dependencies...and it cleans up a bit different to the original one.

Maybe you exposed a bug there...or your code is flawed  :-)

Will try to replicate it in a Windows VM when I find some sparetime.


Bye
Ron

Offline Pingus

  • Full Member
  • ***
  • Posts: 100
Re: BlitzMaxNG Garbage collector issues
« Reply #14 on: June 16, 2020, 05:19:11 PM »
@Ahmoor,
I think that the issue comes from Writebank
If I change the function Img_ToBmp with that simple test:

Code: [Select]
Function Img_ToBmp:Int(img:TImage, file:TStream)

    Print "ImgToBMP start"
Local pxmp:TPixmap
Local y:Int
Local bank1:TBank

    pxmp = LockImage(img, , True, False)
If (pxmp = Null)
Return False
    EndIf
       
    file = TStream(file)
Local ptr1:Byte Ptr
ptr1 = pxmp.pixels       
 

bank1 = CreateStaticBank(ptr1, pxmp.pitch )

For y = 0 To 1000
        WriteBank(bank1, file, 0, pxmp.pitch )
Print " test loop "+y
Next
   
UnlockImage(img)
   
Print "imgTOBMP done "
    Return True

EndFunction

It crashes after few hit on "W" to run the function (the normal function crash after 12 or 13 tries on my PC).
The same code in Blitzmax vanilla works flawless...

It may be tricky to find a bug in Writebank... ;/

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal