diff options
author | Ron Yorston <rmy@pobox.com> | 2024-01-14 11:07:37 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2024-01-14 11:07:37 +0000 |
commit | 03d68fb5cf6e47af479aa8a99a4b6aaba7da455a (patch) | |
tree | 2c853e4e686c03b788b2d616bc9f49d49a8c5576 | |
parent | 19458265b715108bb45f7fc5a7cdb43f9a3be73b (diff) | |
download | busybox-w32-03d68fb5cf6e47af479aa8a99a4b6aaba7da455a.tar.gz busybox-w32-03d68fb5cf6e47af479aa8a99a4b6aaba7da455a.tar.bz2 busybox-w32-03d68fb5cf6e47af479aa8a99a4b6aaba7da455a.zip |
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.
-rw-r--r-- | shell/ash.c | 51 |
1 files 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 */ | |||
9844 | static int fs_size; | 9844 | static int fs_size; |
9845 | # if FORKSHELL_DEBUG | 9845 | # if FORKSHELL_DEBUG |
9846 | static void *fs_start; | 9846 | static void *fs_start; |
9847 | static void *fs_funcstring; | ||
9847 | static const char **annot; | 9848 | static const char **annot; |
9848 | # endif | 9849 | # endif |
9849 | #endif | 9850 | #endif |
@@ -9995,36 +9996,55 @@ static union node *copynode(union node *); | |||
9995 | # if FORKSHELL_DEBUG | 9996 | # if FORKSHELL_DEBUG |
9996 | # define FREE 1 | 9997 | # define FREE 1 |
9997 | # define NO_FREE 2 | 9998 | # define NO_FREE 2 |
9998 | # define ANNOT(dst,note) { \ | 9999 | # define MARK_PTR(dst,note,flag) forkshell_mark_ptr((void *)&dst, note, flag) |
9999 | if (annot) \ | ||
10000 | annot[(char *)&dst - (char *)fs_start] = note; \ | ||
10001 | } | ||
10002 | # else | 10000 | # else |
10003 | # define FREE 1 | 10001 | # define FREE 1 |
10004 | # define NO_FREE 1 | 10002 | # define NO_FREE 1 |
10005 | # define ANNOT(dst,note) | 10003 | # define MARK_PTR(dst,note,flag) forkshell_mark_ptr((void *)&dst, flag) |
10006 | # endif | 10004 | # endif |
10007 | 10005 | ||
10008 | /* The relocation map is offset from the start of the forkshell data | 10006 | #if FORKSHELL_DEBUG |
10009 | * block by 'fs_size' bytes. The flag relating to a particular destination | 10007 | static void forkshell_mark_ptr(void *dst, const char *note, int flag) |
10010 | * pointer is thus at (dst+fs_size). */ | 10008 | #else |
10011 | # define MARK_PTR(dst,flag) {*((char *)&dst + fs_size) = flag;} | 10009 | static void forkshell_mark_ptr(void *dst, int flag) |
10010 | #endif | ||
10011 | { | ||
10012 | /* The relocation map is offset from the start of the forkshell data | ||
10013 | * block by 'fs_size' bytes. The flag relating to a particular | ||
10014 | * destination pointer is thus at (dst+fs_size). */ | ||
10015 | *((char *)dst + fs_size) = flag; | ||
10016 | |||
10017 | #if FORKSHELL_DEBUG | ||
10018 | if (dst < fs_start || dst >= fs_funcstring) { | ||
10019 | fprintf(stderr, "dst (%p) out of range (%p %p)\n", | ||
10020 | dst, fs_start, fs_funcstring); | ||
10021 | } | ||
10022 | if (annot) { | ||
10023 | if (annot[(char *)dst - (char *)fs_start]) { | ||
10024 | fprintf(stderr, "duplicate annotation: %s %s\n", | ||
10025 | annot[(char *)dst - (char *)fs_start], note); | ||
10026 | } | ||
10027 | annot[(char *)dst - (char *)fs_start] = note; | ||
10028 | } | ||
10029 | #endif | ||
10030 | } | ||
10012 | 10031 | ||
10013 | # define SAVE_PTR(dst,note,flag) { \ | 10032 | # define SAVE_PTR(dst,note,flag) { \ |
10014 | if (fs_size) { \ | 10033 | if (fs_size) { \ |
10015 | MARK_PTR(dst,flag); ANNOT(dst,note); \ | 10034 | MARK_PTR(dst,note,flag); \ |
10016 | } \ | 10035 | } \ |
10017 | } | 10036 | } |
10018 | # define SAVE_PTR2(dst1,note1,flag1,dst2,note2,flag2) { \ | 10037 | # define SAVE_PTR2(dst1,note1,flag1,dst2,note2,flag2) { \ |
10019 | if (fs_size) { \ | 10038 | if (fs_size) { \ |
10020 | MARK_PTR(dst1,flag1); MARK_PTR(dst2,flag2); \ | 10039 | MARK_PTR(dst1,note1,flag1); \ |
10021 | ANNOT(dst1,note1); ANNOT(dst2,note2); \ | 10040 | MARK_PTR(dst2,note2,flag2); \ |
10022 | } \ | 10041 | } \ |
10023 | } | 10042 | } |
10024 | # define SAVE_PTR3(dst1,note1,flag1,dst2,note2,flag2,dst3,note3,flag3) { \ | 10043 | # define SAVE_PTR3(dst1,note1,flag1,dst2,note2,flag2,dst3,note3,flag3) { \ |
10025 | if (fs_size) { \ | 10044 | if (fs_size) { \ |
10026 | MARK_PTR(dst1,flag1); MARK_PTR(dst2,flag2); MARK_PTR(dst3,flag3); \ | 10045 | MARK_PTR(dst1,note1,flag1); \ |
10027 | ANNOT(dst1,note1); ANNOT(dst2,note2); ANNOT(dst3,note3); \ | 10046 | MARK_PTR(dst2,note2,flag2); \ |
10047 | MARK_PTR(dst3,note3,flag3); \ | ||
10028 | } \ | 10048 | } \ |
10029 | } | 10049 | } |
10030 | #else | 10050 | #else |
@@ -16522,7 +16542,7 @@ spawn_forkshell(struct forkshell *fs, struct job *jp, union node *n, int mode) | |||
16522 | #undef SAVE_PTR | 16542 | #undef SAVE_PTR |
16523 | #undef SAVE_PTR2 | 16543 | #undef SAVE_PTR2 |
16524 | #undef SAVE_PTR3 | 16544 | #undef SAVE_PTR3 |
16525 | #define SAVE_PTR(dst,note,flag) {MARK_PTR(dst,flag); ANNOT(dst,note);} | 16545 | #define SAVE_PTR(dst,note,flag) {MARK_PTR(dst,note,flag);} |
16526 | 16546 | ||
16527 | static int align_len(const char *s) | 16547 | static int align_len(const char *s) |
16528 | { | 16548 | { |
@@ -17224,6 +17244,7 @@ forkshell_prepare(struct forkshell *fs) | |||
17224 | funcstring_end = (char *)new + size; | 17244 | funcstring_end = (char *)new + size; |
17225 | #if FORKSHELL_DEBUG | 17245 | #if FORKSHELL_DEBUG |
17226 | fs_start = new; | 17246 | fs_start = new; |
17247 | fs_funcstring = (char *)new + sizeof(struct forkshell) + ds.funcblocksize; | ||
17227 | relocate = (char *)new + size; | 17248 | relocate = (char *)new + size; |
17228 | annot = (const char **)xzalloc(sizeof(char *)*relocatesize); | 17249 | annot = (const char **)xzalloc(sizeof(char *)*relocatesize); |
17229 | #endif | 17250 | #endif |