Is there a way I can find out all changes to memory by a particular piece of code( a function or a line of code ) without knowing in advance where I expect the changes(I want to watch the whole program memory space)? watch in gdb requires me to know what I expect is changing...
Well, there are various debugging techniques you can use to monitor memory allocation in a C app. For example, here are some options for Linux.
Not in software, because the software itself executes in the memory you are trying to monitor. The on-chip debug hardware that GDB uses does not have sufficient resources to achieve what you are after. Technically I suppose it would be possible to virtualise all of the memory that a process uses, and have a separate handler perform the monitor, but I suggest that is rather advanced and not something you could implement easily.
It would be possible using external hardware (such as a logic analyser) but it would be impractical to probe the address and data bus unless the board were specifically constructed to allow that.
In the end, it is probably not practical to do what you suggest, but I have to wonder why you need such functionality?
If you can run the software you wish to probe on Linux or Mac OS, I'd suggest looking into Valgrind, specifically Valgrind's Memcheck tool.
In a nutshell, Valgrind runs your program on a "synthetic CPU". It doesn't directly execute the program's code on the real hardware. As a result, it's able to instrument everything that the program does. The Memcheck tool is able to watch all of the program's memory accesses. It can do an amazing job of helping to find various types of memory errors.
If you wanted to catch all access to a particular page of memory, you might find mprotect
handy. But you want to limit your monitoring based on the instruction address, not the target address.
There are a couple approaches, and all of them require identifying pointer use within the source code. Unless you intend to do this frequently on different functions, it's probably easier to do that by hand.
One method is to find instructions which do indirect memory access and set conditional breakpoints (i.e. break if the pointer is outside the buffer you expect to be changed).
Another method would be to patch the function code to insert code to test or print all the pointers being used.
Yet another way would be to mark the function code non-executable (with e.g. mprotect). Then your signal handler (segmentation fault) will be run instead of the function. Then a VM technique can be used to interpret the code instead of executing it directly on the hardware.
The last technique would be the most general method, the first technique would be the least amount of effort if you only want to track memory access in a single function, the second technique is probably the most work but also the smallest performance hit.