4

While debugging some C++ code with tons of pointers it would be useful if the memory addresses between runs were the same. Is there any way to make the series of addresses that are returned between consecutive runs of a program that perform the same memory allocations deterministic?

Maybe an environment variable or something that can be set for the debug heap?

I am aware that there are many good reasons you want randomization for release builds, but determinism is handy for debugging in some situations (e.g. something is not getting linked up correctly while modifying a graph).

Joe
  • 2,008
  • 1
  • 17
  • 25
  • 2
    _"Is there any way to make the series of addresses that are returned between consecutive runs of a program that perform the same memory allocations deterministic?"_ I'm afraid there isn't a way to get the same addresses from repeated runs of your program. – πάντα ῥεῖ Jan 26 '16 at 21:44
  • I agree with @πάνταῥεῖ. When asking for memory, be it from the static storage or dynamic, you are at the mercy of operation system. And if it loads your program at different addessess and gives you different addresses when you ask for memory, there is nothing your program can do about it. – SergeyA Jan 26 '16 at 21:47
  • Address Space Layout Randomization most likely is the largest cause of this. https://en.wikipedia.org/wiki/Address_space_layout_randomization#Microsoft_Windows – drescherjm Jan 26 '16 at 22:11
  • 1
    To disable ASLR on windows: http://stackoverflow.com/questions/9560993/how-do-you-disable-aslr-address-space-layout-randomization-on-windows-7-x64 – drescherjm Jan 26 '16 at 22:13
  • You may want to replace `operator new`. In your own version, create a single large memory mapping (obviously this requires x64) and allocate sequentially from this block. – MSalters Jan 26 '16 at 22:15
  • @drescherjm I tried disabling ASLR system-wide using EMET like described in one of the answers in your link. I still got different addresses from memory allocations though. Does ASLR only change where executables are loaded, but not where virtual memory is allocated for other purposes perhaps? Anyhow, it doesn't seem like the magic bullet I was hoping for. It would also be nice if there is something that can be set per-process so that overall security isn't compromised. :-/ – Joe Jan 26 '16 at 23:02
  • @MSalters I would still need to ensure that the large memory block is allocated deterministically for pointers inside of it to remain the same between runs. Theoretically I could do what you suggest and make a smart pointer class that adds base + offset for every dereference, but that sounds a complicated and silly workaround for what seems like a straightforward parameter to set in the memory system. – Joe Jan 26 '16 at 23:06
  • @Joe: No, you don't need a smart pointer class. Pick a fixed base address. The chances are >99% of it being free in a 64 bits address space. It's very easy to underestimate how mind-boggling big a 64 bit address space is; 16GB is is just a billionth. – MSalters Jan 27 '16 at 08:30
  • @MSalters I see that you are right that you can optionally specify a base address when calling VirtualAlloc, and I agree with you that it is extremely unlikely to choose an address range that overlaps preexisting allocations. Having to write an allocator isn't quite as drop-in as I would like, but is doable. – Joe Feb 01 '16 at 19:16
  • @MSalters I forgot to say: I doubt there is any better solution than yours, so if you write an answer I will accept it. – Joe Feb 01 '16 at 19:38

2 Answers2

2

(Converted from comment)

You may want to replace operator new. In your own version, create a single large memory mapping at a fixed base address. The chances are >99% of it being free in a 64 bits address space. Then just allocate sequentially from this block.

MSalters
  • 173,980
  • 10
  • 155
  • 350
1

there is a special debug heap that is used that performs extra checks and writes special values.

No, there's no such thing like a debug heap, but a debug heap manager that prepares layout and canaries. The extra checks and special values are just outcome of the code compiled in debug mode. Addresses are still arbitrary as gained from the operating system.

Is there any way to make the series of addresses that are returned between consecutive runs of a program that perform the same memory allocations deterministic?

No there's no way to obtain the same addresses for repeated executions of your program, no matter if you're running a debug or release build.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • There is definitely a debug heap. https://msdn.microsoft.com/en-us/library/974tc9t1.aspx – Joe Jan 26 '16 at 22:00
  • @Joe That doesn't mean the allocated memory appears at deterministic addresses, but just how the layout is prepared from the _debug heap manager_. – πάντα ῥεῖ Jan 26 '16 at 22:12