0

I use jemalloc 3.6.0-11. I call posix_memalign to allocate a very large block. After allocating, I am calling madvise(ptr, size, MADV_DONTDUMP); to exclude this allocation from the core dump.

Before freeing this memory, I call madvise(ptr, size, MADV_DODUMP); because I want that if these pages will be allocated in a future allocation, they will not remain marked as DONTDUMP.

The problem is that in most of the cases, the memory that I have just freed is not returned to the OS (that is, the virtual memory of the process still includes the allocation; in /proc//status the allocation size is still a part of VmSize); and it turns out that the core dump is based on the process's virtual memory; so after freeing the memory, the freed pages will be included in the core dump.

Does anybody know how to solve this problem?

Thanks in advance!

  • I'm not sure that the `madvise` really has anything to do with this. It sounds like it's just the fact that memory which is `free()`d but not returned to the OS (e.g. with `munmap()`) will continue to be included in a core dump just like all other memory which the OS has allocated to the process. After all, the kernel has no way of knowing whether you're currently using that memory or not. – Nate Eldredge Nov 15 '20 at 17:01
  • I think your options are (1) ignore it, (2) modify or wrap `malloc/free` to do `DODUMP/DONTDUMP` after/before, (3) arrange somehow for `malloc` to return your block to the OS when you `free()` it, (4) bypass `malloc`, allocate your block with `mmap` and then `munmap` it yourself when you are done. – Nate Eldredge Nov 15 '20 at 17:03
  • Where is the memory actually allocated? If it's on the heap and not created with a separate `mmap()` call, calling `madvise(ptr, size, MADV_DONTDUMP)` on it is either a bad idea if the call is not ignored since it likely would cause other memory in the heap that you might very well **need** for your core dump analysis to not be dumped, and your call might very well be ignored anyway because it **is** for heap memory. Are you checking the return values from your `madvise()` calls, or just assuming they succeed? – Andrew Henle Nov 15 '20 at 17:20

2 Answers2

0

Is your memory page-aligned? Per the Linux madvise() man page, madvise() will fail if it's not:

   EINVAL `addr` is not page-aligned or `length` is negative.
Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
0

I think that by far the simplest way to solve your problem is to just bypass malloc and use mmap directly to allocate your large block, and munmap when finished. This has several benefits:

  • You know that you have exclusive use of the pages in question, without worrying about them overlapping other stuff on the heap (depending on the alignment and size you requested), or about where malloc's metadata might be. In particular you can madvise them however you wish without affecting anything else.

  • For a very large block, it's courteous to the rest of the system if you can return it to the OS immediately when you're done with it, whereas your malloc may possibly (as it seems to be doing) sit on it for use in later allocations, which perhaps you never do anyway.

  • munmaping the block will certainly ensure that it isn't dumped.

There shouldn't really be any performance issues since for a very large block, posix_memalign is almost certainly going to have to get the memory from the OS, so there is a system call anyway, and it sounds like you're not going to be allocating and freeing it very frequently.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82