FBMemCheck

User projects written in or related to FreeBASIC.
Post Reply
Xusinboy Bekchanov
Posts: 679
Joined: Jul 26, 2018 18:28

FBMemCheck

Post by Xusinboy Bekchanov »

I changed fbmld. It is now possible to handle memory leaks in New and Delete too. To use this library you need to include FBMemCheck.bi to your source and also you need to rename Allocate, CAllocate, Reallocate, Deallocate, New, Delete and Delete[] to Allocate_, CAllocate_, Reallocate_, Deallocate_, New_, Delete_ and Delete_SquareBrackets. All of them must be with brackets.
To facilitate this work, I added FBMemCheck Assist Addin to VisualFBEditor.

You can also add #define MEMCHECK 1 (before #include lines) to check for memory leaks or #define MEMCHECK 0 to work in the usual way.

Another convenience, if you make Dealloсate\Delete a already deallocated\deleted variable, the library tells you where it was done before.

FBMemCheсk.bi source here:
https://github.com/XusinboyBekchanov/My ... emCheck.bi
Dr_D
Posts: 2439
Joined: May 27, 2005 4:59
Contact:

Re: FBMemCheck

Post by Dr_D »

Nice! I used to use fbmld on every project. Thanks!
VANYA
Posts: 1773
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: FBMemCheck

Post by VANYA »

Xusinboy! Sorry, but I don't see any real benefit from fbmld or FBMemCheck. If only they could check such constructions:

Code: Select all

dim as long ptr  p1 = 120000 , p2 
  
p2 = Allocate(10)

p2 = Allocate(10) ' here's a warning that buffer is not freed

? *p1 ' here's a warning that a pointer is being used that has no memory allocated
It is these problems (especially the second) that most often cause headaches. I understand that this can only be done at the level of the compiler or a special utility that will parse the code and modify it like this:

from this:

p2 = Allocate(10)

in it:

fbmld_alloc(p2,10)

and then check the pointer p2
jj2007
Posts: 2327
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: FBMemCheck

Post by jj2007 »

Like this?

Code: Select all

#include "Windows.bi"	' for GlobalAlloc & GlobalFree

function allo(bytes as Long, byref pDest as any ptr) As BOOLEAN
Dim p as any ptr
  p=GlobalAlloc(GMEM_FIXED OR GMEM_ZEROINIT, bytes)
  if p then
	if pDest Then
		Print "Lazy programmer, eh? You should not allocate without freeing it first"
		GlobalFree(pDest)
	endif
	pDest=p
	return 1
  else
	Print "Something went wrong"
	pDest=0
	return 0
  endif
end function

Dim buffer as any ptr

for count as long = 1 to 5
  if allo(1000, buffer) then
	print "success, I got a buffer: "; buffer
  else
	print "failure"
  endif
Next

sleep
Compliments to Xusinboy, this is a nice project!
Xusinboy Bekchanov
Posts: 679
Joined: Jul 26, 2018 18:28

Re: FBMemCheck

Post by Xusinboy Bekchanov »

Thanks to all.
VANYA wrote:Xusinboy! Sorry, but I don't see any real benefit from fbmld or FBMemCheck. If only they could check such constructions:

Code: Select all

dim as long ptr  p1 = 120000 , p2 
  
p2 = Allocate(10)

p2 = Allocate(10) ' here's a warning that buffer is not freed

? *p1 ' here's a warning that a pointer is being used that has no memory allocated
It is these problems (especially the second) that most often cause headaches. I understand that this can only be done at the level of the compiler or a special utility that will parse the code and modify it like this:

from this:

p2 = Allocate(10)

in it:

fbmld_alloc(p2,10)

and then check the pointer p2
We need to think about it.
VANYA
Posts: 1773
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: FBMemCheck

Post by VANYA »

jj2007 wrote:Like this?
Yes, at least. I just don't understand how a utility can account for memory leaks if the simplest example , that I have given is not counted (one variable is allocated memory that has not yet been freed)? What is she even counting? Can you give an example of the usefulness of this project? And again, I know that it is unrealistic to pass the construction with macros:

Code: Select all

p = allocate(10)
Therefore, I say that such a mechanism can be implemented using a compiler (the best option), or using a utility that parses the code and prepares it for compilation and working with the output of questionable code sections (this is a difficult option).
Xusinboy Bekchanov
Posts: 679
Joined: Jul 26, 2018 18:28

Re: FBMemCheck

Post by Xusinboy Bekchanov »

VANYA wrote:
jj2007 wrote:Like this?
Yes, at least. I just don't understand how a utility can account for memory leaks if the simplest example , that I have given is not counted (one variable is allocated memory that has not yet been freed)? What is she even counting? Can you give an example of the usefulness of this project? And again, I know that it is unrealistic to pass the construction with macros:

Code: Select all

p = allocate(10)
Therefore, I say that such a mechanism can be implemented using a compiler (the best option), or using a utility that parses the code and prepares it for compilation and working with the output of questionable code sections (this is a difficult option).
Regarding the first example, the program says that the memory was not released in such a line of such a file.
Regarding the second example, either the program exits with an error or if you debug with gdb then gdb will say the wrong place.
I think getting rid of memory leaks can reduce the used memory. The memory does not overflow. I know that at the end of the program the memory is freed anyway.
VANYA
Posts: 1773
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: FBMemCheck

Post by VANYA »

Russian:

Я напишу на русском (знаю, что вы говорите по-русски).

Я повторяю , что программы FBMemCheck и fbmld , используя пример:

Code: Select all

dim as long ptr p2
 
p2 = Allocate(10)

p2 = Allocate(10) ' here's a warning that buffer is not freed
у меня ничего не выводят (вообще ничего). Никаких предупреждений или ошибок. Тогда что они проверяют?

Что касается второго примера с фиктивным адресом , взятым с потолка , тот это было написано просто для понимания. В реальной программе , при частом использовании косвенной адресации, программист совершает неочевидные ошибки в коде и адресом может оказаться адрес из адресного пространства вашей программы. Однако этот адрес не выделялся с помощью функций allocate или new. В итоге ваша программа прочитает какой-нибудь мусор с этого адреса, обработает и пойдет дальше , а вылет программы будет происходить в таких местах , в которых по всем признакам быть не должно. И отладчик ничем не поможет , он будет выдавать случайные ошибки в разных местах. Если вы не сталкивались с подобными ситуациями , то у вас все еще впереди :) Но не забивайте себе голову вторым примером , поскольку реализация отслеживания подобного сложна для универсальных утилит. Однако первый то пример - как раз то, для чего FBMemCheck и fbmld создавались или нет?

English:


I repeat that the FBMemCheck and fbmld programs using the example:

Code: Select all

dim as long ptr p2
 
p2 = Allocate(10)

p2 = Allocate(10) ' here's a warning that buffer is not freed
they do not output anything (nothing at all). No warnings or errors. Then what are they checking?

As for the second example, with a bogus address taken from the ceiling, it was written just for understanding. In a real program, with frequent use of indirect addressing, the programmer commits non-obvious errors in the code and the address may be an address from the address space of your program. However, this address was not allocated using the allocate or new functions. As a result, your program will read some garbage from this address, process it and go on, and the program will crash in places that, by all indications, should not be. And the debugger won't help you, it will throw random errors in different places. If you have not faced similar situations, then you still have ahead :) It was the idea in the FBMemCheck, fbmld programs that gave me an idea and reminded me of such tricky situations for a programmer. But don't get overwhelmed with the second example, since the implementation of tracking this is difficult for universal utilities. However, the first example is exactly what FBMemCheck and fbmld were created for or not?
Xusinboy Bekchanov
Posts: 679
Joined: Jul 26, 2018 18:28

Re: FBMemCheck

Post by Xusinboy Bekchanov »

Russian: Вот в этом коде:
English: Here in this code:

Code: Select all

#define MEMCHECK 1

#include once "mff/FBMemCheck.bi"

Dim As Long Ptr p2
 
p2 = Allocate_(10)

p2 = Allocate_(10) ' here's a warning that buffer is not freed
Russian: Выводит это:
English: Outputs this:
GNU gdb (GDB) 7.6.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
[New Thread 6388.0x1958]
[New Thread 6388.0x15b4]
(FBMEMCHECK) ---- memory leaks ----
(FBMEMCHECK) error: 10 bytes allocated/created at Untitled.bas(__FB_MAINPROC__): 9 [&H00812E48][8465992] not deallocated/deleted
(FBMEMCHECK) error: 10 bytes allocated/created at Untitled.bas(__FB_MAINPROC__): 7 [&H00812D50][8465744] not deallocated/deleted
(FBMEMCHECK) totally 20 bytes memory not deallocated
[Inferior 1 (process 6388) exited normally]
(gdb)
I also set the initial MEMCHECK value to 1:
https://github.com/XusinboyBekchanov/My ... 0a58d9fb3e
VANYA
Posts: 1773
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: FBMemCheck

Post by VANYA »

Я то думал , что программа без помощи отладчика выводит все предупреждения и ошибки, ведь есть же макросредства в freebasic для обозначения места в коде, где произошла ошибка\предупреждение , например __FILE__ , __FUNCTION__ , __LINE__.

Ну хотя бы понятно стало.

English:

I thought that the program, without the help of a debugger, displays all warnings and errors, because there are macro tools in freebasic to indicate the place in the code where the error / warning occurred, for example __FILE__ , __FUNCTION__ , __LINE__.

Well, at least it became clear.
Xusinboy Bekchanov
Posts: 679
Joined: Jul 26, 2018 18:28

Re: FBMemCheck

Post by Xusinboy Bekchanov »

VANYA wrote:Я то думал , что программа без помощи отладчика выводит все предупреждения и ошибки, ведь есть же макросредства в freebasic для обозначения места в коде, где произошла ошибка\предупреждение , например __FILE__ , __FUNCTION__ , __LINE__.

Ну хотя бы понятно стало.

English:

I thought that the program, without the help of a debugger, displays all warnings and errors, because there are macro tools in freebasic to indicate the place in the code where the error / warning occurred, for example __FILE__ , __FUNCTION__ , __LINE__.

Well, at least it became clear.
Russian: Да, без отладчика тоже покажет, только при завершении консоль не должен закрываться (а то покажет и закроет):
English: Yes, without a debugger it will also show, only on completion the console should not close(otherwise it will show and close):
(FBMEMCHECK) ---- memory leaks ----
(FBMEMCHECK) error: 10 bytes allocated/created at Untitled.bas(__FB_MAINPROC__): 9 [&H00572C28][5712936] not deallocated/deleted
(FBMEMCHECK) error: 10 bytes allocated/created at Untitled.bas(__FB_MAINPROC__): 7 [&H005716A0][5707424] not deallocated/deleted
(FBMEMCHECK) totally 20 bytes memory not deallocated

D:\GitHub\VisualFBEditor\Projects>
Russian: Эти функции тоже используется __FILE__ , __FUNCTION__ , __LINE__. Вот здесь:
English: These functions are also used by __FILE__, __FUNCTION__, __LINE__. Here:

Code: Select all

#if MEMCHECK = 0
		#define Allocate_(bytes) Allocate(bytes)
		#define CAllocate_(bytes) CAllocate(bytes)
		#define Reallocate_(pt, bytes) Reallocate(pt, bytes)
		#define Deallocate_(pt) Deallocate pt
		#define New_(type_) New type_
		#define Delete_(pt) Delete pt
		#define Delete_SquareBrackets(pt) Delete[] pt
	#else
		#include "crt.bi"
		
		#define Allocate_(bytes) fbmld_allocate(bytes, __FILE__, __FUNCTION__, __LINE__)
		#define CAllocate_(bytes) fbmld_callocate(bytes, __FILE__, __FUNCTION__, __LINE__)
		#define Reallocate_(pt, bytes) fbmld_reallocate(pt, bytes, __FILE__, __FUNCTION__, __LINE__, #pt)
		#define Deallocate_(pt) fbmld_deallocate(pt, __FILE__, __FUNCTION__, __LINE__, #pt)
		#macro New_(type_)
			Cast(Typeof(New type_), fbmemcheck_new(New type_, __FILE__, __FUNCTION__, __LINE__))
		#endmacro
		#macro Delete_(pt)
			fbmemcheck_delete(pt, __FILE__, __FUNCTION__, __LINE__, #pt): Delete pt
		#endmacro
		#macro Delete_SquareBrackets(pt)
			fbmemcheck_delete(pt, __FILE__, __FUNCTION__, __LINE__, #pt): Delete[] pt
		#endmacro
Russian: Программа так читает места ошибок.
English: This is how the program reads error locations.
VANYA
Posts: 1773
Joined: Oct 24, 2010 15:16
Location: Ярославль
Contact:

Re: FBMemCheck

Post by VANYA »

Russian: Да, без отладчика тоже покажет, только при завершении консоль не должен закрываться (а то покажет и закроет):
English: Yes, without a debugger it will also show, only on completion the console should not close(otherwise it will show and close):
О , я редко когда запускаю консоль , а потом в ней скомпилированную программу. Всегда использую в IDE "Быстрый запуск", поэтому и не видел вывода FBMemCheck и fbmld.

Спасибо за разъяснения!

Я надеюсь , вы не обидились на мои замечания в начале темы , я просто не разобрался. И кому то возможно ваша утилита сможет принести пользу. Удачи!

English:

Oh, I rarely run the console, and then the compiled program in it. I always use "Quick Launch" in the IDE, so I have not seen the output of FBMemCheck and fbmld.

Thanks for the clarification!

I hope you are not offended by my comments at the beginning of the topic, I just did not figure it out. And someone may be able to benefit from your utility. Good luck!
Xusinboy Bekchanov
Posts: 679
Joined: Jul 26, 2018 18:28

Re: FBMemCheck

Post by Xusinboy Bekchanov »

VANYA wrote:
Russian: Да, без отладчика тоже покажет, только при завершении консоль не должен закрываться (а то покажет и закроет):
English: Yes, without a debugger it will also show, only on completion the console should not close(otherwise it will show and close):
О , я редко когда запускаю консоль , а потом в ней скомпилированную программу. Всегда использую в IDE "Быстрый запуск", поэтому и не видел вывода FBMemCheck и fbmld.

Спасибо за разъяснения!

Я надеюсь , вы не обидились на мои замечания в начале темы , я просто не разобрался. И кому то возможно ваша утилита сможет принести пользу. Удачи!

English:

Oh, I rarely run the console, and then the compiled program in it. I always use "Quick Launch" in the IDE, so I have not seen the output of FBMemCheck and fbmld.

Thanks for the clarification!

I hope you are not offended by my comments at the beginning of the topic, I just did not figure it out. And someone may be able to benefit from your utility. Good luck!
Russian: Нет, я не обиделось. Я хорошо отношусь на критику. Я думал, что вы сказали "мало пользы, все равно в конце освобождается память". Вам тоже удачи!
English: No, I'm not offended. I'm good at criticism. I thought you said "little benefit, memory is freed at the end". Good luck to you too!
Dr_D
Posts: 2439
Joined: May 27, 2005 4:59
Contact:

Re: FBMemCheck

Post by Dr_D »

The program was vey helpful to me because I was terrible with memory management. ;)
Xusinboy Bekchanov
Posts: 679
Joined: Jul 26, 2018 18:28

Re: FBMemCheck

Post by Xusinboy Bekchanov »

Thanks for the good feedback.
Post Reply