From 714fa49ec91a1115e9b41b1f394f2861d01fcd5b 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 8259682dd1e8f..091be6828ff31 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 baa03b9396ea0..0dd8db15a6d86 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -164,15 +164,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 df6404c368748..2dd712e91dcac 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 :