From a6d613cc266c22a7c9862d779371c23a2697847e Mon Sep 17 00:00:00 2001 From: Daniel Dragan Date: Sun, 20 Oct 2024 01:57:31 -0400 Subject: [PATCH] Update POD for Newx/Renew/Safefree vs libc analogs about heap corruption This isn't documented anywhere except in perlapi, in the per-macro/per-function section. A seasoned dev, will read perlguts ONCE, write code, then pass a Newx() pointer, to some 3rd party library or native OS API, and then instant disaster, or invisible disaster. If Newx() and libc malloc() pointers are interchangeable, on ONE particular OS, with ONE particular perl build, with ONE particular set of build flags, that is undefined behavior. Have fun with #define USE_MDH or -DUSE_MDH or -DDEBUGGING or #define MYMALLOC -DMYMALLOC. Also, for anyone reading this in the future. DO NOT EVER DOCUMENT the permutations where Newx() is libc malloc(). Perl core reserves the right, to separate Newx() and malloc(), at any time in a maint release if there are technical reasons to do so. Also libperl.so/.dll embedders, if libperl is unloaded from the process, and deallocs all Newx() blocks globally, and a 3rd party library still loaded in the process, thinking it owns that "malloc()" block, that was given ownership of, in 3rd party lib API contract, SEGV time. --- pod/perlclib.pod | 5 ++++- pod/perldelta.pod | 11 ++++++++--- pod/perlguts.pod | 5 ++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/pod/perlclib.pod b/pod/perlclib.pod index 8259682dd1e8..091be6828ff3 100644 --- a/pod/perlclib.pod +++ b/pod/perlclib.pod @@ -166,7 +166,10 @@ should use C instead: p = realloc(p, n) Renew(p, n, t) It is not portable to try to allocate 0 bytes; allocating 1 or more is -portable. +portable. Never pass pointers between C, C, C and +I equivalents C, C, C. They are not from the +same memory pool or allocator. Either an instant or delayed I will +occur, or subtle memory leaks or subtle heap corruption. memcpy(dst, src, n) Copy(src, dst, n, t) memmove(dst, src, n) Move(src, dst, n, t) diff --git a/pod/perldelta.pod b/pod/perldelta.pod index 7e2cb30bf842..1224f68de5aa 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -180,15 +180,20 @@ XXX Changes which significantly change existing files in F go here. However, any changes to F should go in the L section. + + Additionally, the following selected changes have been made: -=head3 L +=head3 F and F =over 4 -=item * +=item Memory Allocation in C/XS -XXX Description of the change here +Documentation was updated to reflect that mixing C, C, and +C vs C, C, and C not allowed, and mixing +pointers between the 2 classes of APIs is not allowed. Updates made in +F and F. =back diff --git a/pod/perlguts.pod b/pod/perlguts.pod index df6404c36874..2dd712e91dca 100644 --- a/pod/perlguts.pod +++ b/pod/perlguts.pod @@ -2384,7 +2384,10 @@ marked with correct flags. All memory meant to be used with the Perl API functions should be manipulated using the macros described in this section. The macros provide the necessary transparency between differences in the actual malloc implementation that is -used within perl. +used within perl. Never pass pointers between C, C, C +and I equivalents C, C, C. They are not from the +same memory pool or allocator. Either an instant or delayed I will +occur, or subtle memory leaks or subtle heap corruption. The following three macros are used to initially allocate memory :