From 03d68fb5cf6e47af479aa8a99a4b6aaba7da455a Mon Sep 17 00:00:00 2001 From: Ron Yorston <rmy@pobox.com> Date: Sun, 14 Jan 2024 11:07:37 +0000 Subject: ash: add more checks to forkshell debug Rearrange the handling of pointer relocation during forkshell and add a couple of additional sanity checks. There's no functional change to non-debug builds. --- shell/ash.c | 51 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index e45c8d61d..90f4c9773 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -9844,6 +9844,7 @@ static char *funcstring_end; /* end of block to allocate strings from */ static int fs_size; # if FORKSHELL_DEBUG static void *fs_start; +static void *fs_funcstring; static const char **annot; # endif #endif @@ -9995,36 +9996,55 @@ static union node *copynode(union node *); # if FORKSHELL_DEBUG # define FREE 1 # define NO_FREE 2 -# define ANNOT(dst,note) { \ - if (annot) \ - annot[(char *)&dst - (char *)fs_start] = note; \ - } +# define MARK_PTR(dst,note,flag) forkshell_mark_ptr((void *)&dst, note, flag) # else # define FREE 1 # define NO_FREE 1 -# define ANNOT(dst,note) +# define MARK_PTR(dst,note,flag) forkshell_mark_ptr((void *)&dst, flag) # endif -/* The relocation map is offset from the start of the forkshell data - * block by 'fs_size' bytes. The flag relating to a particular destination - * pointer is thus at (dst+fs_size). */ -# define MARK_PTR(dst,flag) {*((char *)&dst + fs_size) = flag;} +#if FORKSHELL_DEBUG +static void forkshell_mark_ptr(void *dst, const char *note, int flag) +#else +static void forkshell_mark_ptr(void *dst, int flag) +#endif +{ + /* The relocation map is offset from the start of the forkshell data + * block by 'fs_size' bytes. The flag relating to a particular + * destination pointer is thus at (dst+fs_size). */ + *((char *)dst + fs_size) = flag; + +#if FORKSHELL_DEBUG + if (dst < fs_start || dst >= fs_funcstring) { + fprintf(stderr, "dst (%p) out of range (%p %p)\n", + dst, fs_start, fs_funcstring); + } + if (annot) { + if (annot[(char *)dst - (char *)fs_start]) { + fprintf(stderr, "duplicate annotation: %s %s\n", + annot[(char *)dst - (char *)fs_start], note); + } + annot[(char *)dst - (char *)fs_start] = note; + } +#endif +} # define SAVE_PTR(dst,note,flag) { \ if (fs_size) { \ - MARK_PTR(dst,flag); ANNOT(dst,note); \ + MARK_PTR(dst,note,flag); \ } \ } # define SAVE_PTR2(dst1,note1,flag1,dst2,note2,flag2) { \ if (fs_size) { \ - MARK_PTR(dst1,flag1); MARK_PTR(dst2,flag2); \ - ANNOT(dst1,note1); ANNOT(dst2,note2); \ + MARK_PTR(dst1,note1,flag1); \ + MARK_PTR(dst2,note2,flag2); \ } \ } # define SAVE_PTR3(dst1,note1,flag1,dst2,note2,flag2,dst3,note3,flag3) { \ if (fs_size) { \ - MARK_PTR(dst1,flag1); MARK_PTR(dst2,flag2); MARK_PTR(dst3,flag3); \ - ANNOT(dst1,note1); ANNOT(dst2,note2); ANNOT(dst3,note3); \ + MARK_PTR(dst1,note1,flag1); \ + MARK_PTR(dst2,note2,flag2); \ + MARK_PTR(dst3,note3,flag3); \ } \ } #else @@ -16522,7 +16542,7 @@ spawn_forkshell(struct forkshell *fs, struct job *jp, union node *n, int mode) #undef SAVE_PTR #undef SAVE_PTR2 #undef SAVE_PTR3 -#define SAVE_PTR(dst,note,flag) {MARK_PTR(dst,flag); ANNOT(dst,note);} +#define SAVE_PTR(dst,note,flag) {MARK_PTR(dst,note,flag);} static int align_len(const char *s) { @@ -17224,6 +17244,7 @@ forkshell_prepare(struct forkshell *fs) funcstring_end = (char *)new + size; #if FORKSHELL_DEBUG fs_start = new; + fs_funcstring = (char *)new + sizeof(struct forkshell) + ds.funcblocksize; relocate = (char *)new + size; annot = (const char **)xzalloc(sizeof(char *)*relocatesize); #endif -- cgit v1.2.3-55-g6feb