* [LTP] [PATCH] thp01: Find largest arguments size @ 2017-08-31 8:34 Richard Palethorpe 2017-09-01 7:05 ` Li Wang 2017-09-01 10:03 ` Cyril Hrubis 0 siblings, 2 replies; 8+ messages in thread From: Richard Palethorpe @ 2017-08-31 8:34 UTC (permalink / raw) To: ltp Because of kernel commit da029c11e6b1 the arguments size for exec has been reduced considerably. This causes exec to fail with E2BIG, so we call it repeatedly with a decreasing number of arguments until it is successful. As far as I know, there is no other reliable and easy way to determine the maximum argument length. Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com> --- testcases/kernel/mem/thp/thp01.c | 83 ++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/testcases/kernel/mem/thp/thp01.c b/testcases/kernel/mem/thp/thp01.c index 101a9b5c8..b90b9b637 100644 --- a/testcases/kernel/mem/thp/thp01.c +++ b/testcases/kernel/mem/thp/thp01.c @@ -30,6 +30,7 @@ * .... */ +#include <errno.h> #include <sys/types.h> #include <sys/resource.h> #include <sys/wait.h> @@ -38,56 +39,72 @@ #include <stdlib.h> #include <unistd.h> #include "mem.h" +#include "tst_minmax.h" +#include "tst_safe_sysv_ipc.h" -#define ARRAY_SZ 256 +#define ARGS_SZ 256 -static int ps; -static long length; -static char *array[ARRAY_SZ]; +static int shm_id; +static char *args[ARGS_SZ]; static char *arg; -static struct rlimit rl = { - .rlim_cur = RLIM_INFINITY, - .rlim_max = RLIM_INFINITY, -}; +static long *arg_count; static void thp_test(void) { - int i; - pid_t pid; - - switch (pid = SAFE_FORK()) { - case 0: - memset(arg, 'c', length - 1); - arg[length - 1] = '\0'; - array[0] = "true"; - for (i = 1; i < ARRAY_SZ - 1; i++) - array[i] = arg; - array[ARRAY_SZ - 1] = NULL; - if (setrlimit(RLIMIT_STACK, &rl) == -1) { - perror("setrlimit"); - exit(1); - } - if (execvp("true", array) == -1) { - perror("execvp"); - exit(1); - } - default: - tst_reap_children(); + pid_t pid = SAFE_FORK(); + + if (!arg_count) + tst_brk(TBROK, "No shared memory"); + + if (!pid) { + args[*arg_count] = NULL; + + do { + TEST(execvp("true", args)); + args[--(*arg_count)] = NULL; + } while (*arg_count > 0 && TEST_ERRNO == E2BIG); + + tst_brk(TBROK | TTERRNO, "execvp(\"true\", ...)"); } + tst_reap_children(); tst_res(TPASS, "system didn't crash, pass."); } static void setup(void) { - ps = sysconf(_SC_PAGESIZE); - length = 32 * ps; - arg = SAFE_MALLOC(length); + struct rlimit rl = { + .rlim_cur = RLIM_INFINITY, + .rlim_max = RLIM_INFINITY, + }; + int i; + long arg_len; + + shm_id = SAFE_SHMGET(IPC_PRIVATE, sizeof(long), + IPC_CREAT | IPC_EXCL); + arg_count = SAFE_SHMAT(shm_id, NULL, 0); + + arg_len = 32 * sysconf(_SC_PAGESIZE); + arg = SAFE_MALLOC(arg_len); + memset(arg, 'c', arg_len - 1); + arg[arg_len - 1] = '\0'; + + args[0] = "true"; + *arg_count = ARGS_SZ - 1; + for (i = 1; i < *arg_count; i++) + args[i] = arg; + + SAFE_SETRLIMIT(RLIMIT_STACK, &rl); } static void cleanup(void) { - free(arg); + if (arg) + free(arg); + if (arg_count) + SAFE_SHMDT(arg_count); + if (shm_id) + SAFE_SHMCTL(shm_id, IPC_RMID, NULL); } static struct tst_test test = { -- 2.14.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [LTP] [PATCH] thp01: Find largest arguments size 2017-08-31 8:34 [LTP] [PATCH] thp01: Find largest arguments size Richard Palethorpe @ 2017-09-01 7:05 ` Li Wang 2017-09-01 9:34 ` Richard Palethorpe 2017-09-01 10:03 ` Cyril Hrubis 1 sibling, 1 reply; 8+ messages in thread From: Li Wang @ 2017-09-01 7:05 UTC (permalink / raw) To: ltp On Thu, Aug 31, 2017 at 4:34 PM, Richard Palethorpe <rpalethorpe@suse.com> wrote: > Because of kernel commit da029c11e6b1 the arguments size for exec has been > reduced considerably. This causes exec to fail with E2BIG, so we call it > repeatedly with a decreasing number of arguments until it is successful. > > As far as I know, there is no other reliable and easy way to determine the > maximum argument length. > > Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com> > --- > testcases/kernel/mem/thp/thp01.c | 83 ++++++++++++++++++++++++---------------- > 1 file changed, 50 insertions(+), 33 deletions(-) > > diff --git a/testcases/kernel/mem/thp/thp01.c b/testcases/kernel/mem/thp/thp01.c > index 101a9b5c8..b90b9b637 100644 > --- a/testcases/kernel/mem/thp/thp01.c > +++ b/testcases/kernel/mem/thp/thp01.c > @@ -30,6 +30,7 @@ > * .... > */ > > +#include <errno.h> > #include <sys/types.h> > #include <sys/resource.h> > #include <sys/wait.h> > @@ -38,56 +39,72 @@ > #include <stdlib.h> > #include <unistd.h> > #include "mem.h" > +#include "tst_minmax.h" > +#include "tst_safe_sysv_ipc.h" > > -#define ARRAY_SZ 256 > +#define ARGS_SZ 256 > > -static int ps; > -static long length; > -static char *array[ARRAY_SZ]; > +static int shm_id; > +static char *args[ARGS_SZ]; > static char *arg; > -static struct rlimit rl = { > - .rlim_cur = RLIM_INFINITY, > - .rlim_max = RLIM_INFINITY, > -}; > +static long *arg_count; Two queries: 1. Can't we declare the arg_count just as a global variable? why should we take use of share memory, only for the loop counting? 2. The kernel patch limit all arg stack usage to at most 75% of _STK_LIM (6MB), and here the size of arg_len is 32*PAGE_SIZE. So it means that there almost only have 6MB/(PAGE_SIZE*32) numbers can be accepted in args[(*arg_count)], if it is a ppc64 machine(*arg_count == 3) that's OK, but if a system PAGE_SIZE > 192KB, then the test will be break and your loop is absolutely useless. About that, if we shrink the arg_len size, things would be better I guess. -- Li Wang liwang@redhat.com ^ permalink raw reply [flat|nested] 8+ messages in thread
* [LTP] [PATCH] thp01: Find largest arguments size 2017-09-01 7:05 ` Li Wang @ 2017-09-01 9:34 ` Richard Palethorpe 2017-09-01 10:44 ` Li Wang 0 siblings, 1 reply; 8+ messages in thread From: Richard Palethorpe @ 2017-09-01 9:34 UTC (permalink / raw) To: ltp Hello, Thanks for the review, Li Wang writes: > On Thu, Aug 31, 2017 at 4:34 PM, Richard Palethorpe > <rpalethorpe@suse.com> wrote: >> Because of kernel commit da029c11e6b1 the arguments size for exec has been >> reduced considerably. This causes exec to fail with E2BIG, so we call it >> repeatedly with a decreasing number of arguments until it is successful. >> >> As far as I know, there is no other reliable and easy way to determine the >> maximum argument length. >> >> Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com> >> --- >> testcases/kernel/mem/thp/thp01.c | 83 ++++++++++++++++++++++++---------------- >> 1 file changed, 50 insertions(+), 33 deletions(-) >> >> diff --git a/testcases/kernel/mem/thp/thp01.c b/testcases/kernel/mem/thp/thp01.c >> index 101a9b5c8..b90b9b637 100644 >> --- a/testcases/kernel/mem/thp/thp01.c >> +++ b/testcases/kernel/mem/thp/thp01.c >> @@ -30,6 +30,7 @@ >> * .... >> */ >> >> +#include <errno.h> >> #include <sys/types.h> >> #include <sys/resource.h> >> #include <sys/wait.h> >> @@ -38,56 +39,72 @@ >> #include <stdlib.h> >> #include <unistd.h> >> #include "mem.h" >> +#include "tst_minmax.h" >> +#include "tst_safe_sysv_ipc.h" >> >> -#define ARRAY_SZ 256 >> +#define ARGS_SZ 256 >> >> -static int ps; >> -static long length; >> -static char *array[ARRAY_SZ]; >> +static int shm_id; >> +static char *args[ARGS_SZ]; >> static char *arg; >> -static struct rlimit rl = { >> - .rlim_cur = RLIM_INFINITY, >> - .rlim_max = RLIM_INFINITY, >> -}; >> +static long *arg_count; > > > Two queries: > > 1. Can't we declare the arg_count just as a global variable? why > should we take use of share memory, only for the loop counting? It forks so that it can call exec without overwriting the test process image. Global variables are copy-on-write for a child process (unless we use clone()), so the parent's memory would not be updated by the child. We need the parent to be updated so that, when the next child is run, it already has the correct argument count saving a lot of calls to exec. > > > 2. The kernel patch limit all arg stack usage to at most 75% of _STK_LIM (6MB), > and here the size of arg_len is 32*PAGE_SIZE. So it means that there > almost only have 6MB/(PAGE_SIZE*32) numbers can be accepted in > args[(*arg_count)], if it is a ppc64 machine(*arg_count == 3) that's > OK, but if a system PAGE_SIZE > 192KB, then the test will be break and > your loop is absolutely useless. About that, if we shrink the arg_len > size, things would be better I guess. That is true, but even on PPC64 with a default page size of 64Kb, the default huge page size is 15MB (I think). So, on PPC64, we are only doing a very basic test of exec on current kernels. Systems with page sizes over 192KB seem even less likely to have huge pages smaller than 6MB. However I don't see any harm in reducing the PAGE_SIZE coefficient to 1 and multiplying the ARGS_SZ by 32, this will make the test slower, but more accurate at finding the maximum argument size while maintaining the allocation size of the original reproducer. -- Thank you, Richard. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [LTP] [PATCH] thp01: Find largest arguments size 2017-09-01 9:34 ` Richard Palethorpe @ 2017-09-01 10:44 ` Li Wang 0 siblings, 0 replies; 8+ messages in thread From: Li Wang @ 2017-09-01 10:44 UTC (permalink / raw) To: ltp On Fri, Sep 1, 2017 at 5:34 PM, Richard Palethorpe <rpalethorpe@suse.de> wrote: > Hello, > > Thanks for the review, >> >> 1. Can't we declare the arg_count just as a global variable? why >> should we take use of share memory, only for the loop counting? > > It forks so that it can call exec without overwriting the test process > image. Global variables are copy-on-write for a child process (unless we > use clone()), so the parent's memory would not be updated by the > child. We need the parent to be updated so that, when the next child is > run, it already has the correct argument count saving a lot of calls to > exec. Yep! But for this test, it does not need to update 'arg_count' in the parent process, and after fork a child, it call execvp() to create a new process image. So I think here is OK to take use of global variable. Did I miss anything? I do change the 'arg_count' to a global variable and get pass: (see attachment) static void thp_test(void) { pid_t pid = SAFE_FORK(); if (!pid) { args[arg_count] = NULL; do { TEST(execvp("true", args)); args[--arg_count] = NULL; printf("debuginfo: arg_count = %d\n", arg_count); } while (arg_count > 0 && TEST_ERRNO == E2BIG); tst_brk(TBROK | TTERRNO, "execvp(\"true\", ...)"); } tst_reap_children(); tst_res(TPASS, "system didn't crash, pass."); } ========== # ./thp01 tst_test.c:908: INFO: Timeout per run is 0h 05m 00s debuginfo: arg_count = 254 ... debuginfo: arg_count = 49 debuginfo: arg_count = 48 thp01.c:69: PASS: system didn't crash, pass. Summary: passed 1 failed 0 skipped 0 warnings 0 >> >> >> 2. The kernel patch limit all arg stack usage to at most 75% of _STK_LIM (6MB), >> and here the size of arg_len is 32*PAGE_SIZE. So it means that there >> almost only have 6MB/(PAGE_SIZE*32) numbers can be accepted in >> args[(*arg_count)], if it is a ppc64 machine(*arg_count == 3) that's >> OK, but if a system PAGE_SIZE > 192KB, then the test will be break and >> your loop is absolutely useless. About that, if we shrink the arg_len >> size, things would be better I guess. > > That is true, but even on PPC64 with a default page size of 64Kb, the > default huge page size is 15MB (I think). So, on PPC64, we are only > doing a very basic test of exec on current kernels. Systems with page > sizes over 192KB seem even less likely to have huge pages smaller than > 6MB. > > However I don't see any harm in reducing the PAGE_SIZE coefficient to 1 > and multiplying the ARGS_SZ by 32, this will make the test slower, but > more accurate at finding the maximum argument size while maintaining the > allocation size of the original reproducer. > > -- > Thank you, > Richard. -- Li Wang liwang@redhat.com -------------- next part -------------- A non-text attachment was scrubbed... Name: thp01.c Type: text/x-csrc Size: 2434 bytes Desc: not available URL: <http://lists.linux.it/pipermail/ltp/attachments/20170901/27ea9726/attachment.c> ^ permalink raw reply [flat|nested] 8+ messages in thread
* [LTP] [PATCH] thp01: Find largest arguments size 2017-08-31 8:34 [LTP] [PATCH] thp01: Find largest arguments size Richard Palethorpe 2017-09-01 7:05 ` Li Wang @ 2017-09-01 10:03 ` Cyril Hrubis 2017-09-01 14:13 ` [LTP] [PATCH v2] " Richard Palethorpe 1 sibling, 1 reply; 8+ messages in thread From: Cyril Hrubis @ 2017-09-01 10:03 UTC (permalink / raw) To: ltp Hi! > +#include <errno.h> > #include <sys/types.h> > #include <sys/resource.h> > #include <sys/wait.h> > @@ -38,56 +39,72 @@ > #include <stdlib.h> > #include <unistd.h> > #include "mem.h" > +#include "tst_minmax.h" > +#include "tst_safe_sysv_ipc.h" > > -#define ARRAY_SZ 256 > +#define ARGS_SZ 256 > > -static int ps; > -static long length; > -static char *array[ARRAY_SZ]; > +static int shm_id; > +static char *args[ARGS_SZ]; > static char *arg; > -static struct rlimit rl = { > - .rlim_cur = RLIM_INFINITY, > - .rlim_max = RLIM_INFINITY, > -}; > +static long *arg_count; > > static void thp_test(void) > { > - int i; > - pid_t pid; > - > - switch (pid = SAFE_FORK()) { > - case 0: > - memset(arg, 'c', length - 1); > - arg[length - 1] = '\0'; > - array[0] = "true"; > - for (i = 1; i < ARRAY_SZ - 1; i++) > - array[i] = arg; > - array[ARRAY_SZ - 1] = NULL; > - if (setrlimit(RLIMIT_STACK, &rl) == -1) { > - perror("setrlimit"); > - exit(1); > - } > - if (execvp("true", array) == -1) { > - perror("execvp"); > - exit(1); > - } > - default: > - tst_reap_children(); > + pid_t pid = SAFE_FORK(); > + > + if (!arg_count) > + tst_brk(TBROK, "No shared memory"); > + > + if (!pid) { > + args[*arg_count] = NULL; > + > + do { > + TEST(execvp("true", args)); > + args[--(*arg_count)] = NULL; > + } while (*arg_count > 0 && TEST_ERRNO == E2BIG); Hmm, for how long does this loop runs? If it's more than half of a second or so we should consider using binary search to reach the maximal size of arguments... > + tst_brk(TBROK | TTERRNO, "execvp(\"true\", ...)"); > } > > + tst_reap_children(); > tst_res(TPASS, "system didn't crash, pass."); > } > > static void setup(void) > { > - ps = sysconf(_SC_PAGESIZE); > - length = 32 * ps; > - arg = SAFE_MALLOC(length); > + struct rlimit rl = { > + .rlim_cur = RLIM_INFINITY, > + .rlim_max = RLIM_INFINITY, > + }; > + int i; > + long arg_len; > + > + shm_id = SAFE_SHMGET(IPC_PRIVATE, sizeof(long), > + IPC_CREAT | IPC_EXCL); > + arg_count = SAFE_SHMAT(shm_id, NULL, 0); Can we, pretty please, use mmap() to map a page of shared memory instead of using the System V shared memory that has ugly API and system persistence? > + arg_len = 32 * sysconf(_SC_PAGESIZE); > + arg = SAFE_MALLOC(arg_len); > + memset(arg, 'c', arg_len - 1); > + arg[arg_len - 1] = '\0'; > + > + args[0] = "true"; > + *arg_count = ARGS_SZ - 1; > + for (i = 1; i < *arg_count; i++) > + args[i] = arg; > + > + SAFE_SETRLIMIT(RLIMIT_STACK, &rl); > } > > static void cleanup(void) > { > - free(arg); > + if (arg) > + free(arg); > + if (arg_count) > + SAFE_SHMDT(arg_count); > + if (shm_id) > + SAFE_SHMCTL(shm_id, IPC_RMID, NULL); > } > > static struct tst_test test = { > -- > 2.14.1 > > > -- > Mailing list info: https://lists.linux.it/listinfo/ltp -- Cyril Hrubis chrubis@suse.cz ^ permalink raw reply [flat|nested] 8+ messages in thread
* [LTP] [PATCH v2] thp01: Find largest arguments size 2017-09-01 10:03 ` Cyril Hrubis @ 2017-09-01 14:13 ` Richard Palethorpe 2017-09-04 11:29 ` Li Wang 0 siblings, 1 reply; 8+ messages in thread From: Richard Palethorpe @ 2017-09-01 14:13 UTC (permalink / raw) To: ltp Because of kernel commit da029c11e6b1 the arguments size for exec has been reduced considerably. This causes exec to fail with E2BIG, so we call it repeatedly with a decreasing number of arguments until it is successful. As far as I know, there is no other reliable and easy way to determine the maximum argument length. Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com> --- V2 - Reduced the argument length, but increased the argument array and switched to a binary search testcases/kernel/mem/thp/thp01.c | 96 ++++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 29 deletions(-) diff --git a/testcases/kernel/mem/thp/thp01.c b/testcases/kernel/mem/thp/thp01.c index 101a9b5c8..cd14bec14 100644 --- a/testcases/kernel/mem/thp/thp01.c +++ b/testcases/kernel/mem/thp/thp01.c @@ -30,6 +30,7 @@ * .... */ +#include <errno.h> #include <sys/types.h> #include <sys/resource.h> #include <sys/wait.h> @@ -38,56 +39,92 @@ #include <stdlib.h> #include <unistd.h> #include "mem.h" +#include "tst_minmax.h" +#include "tst_safe_sysv_ipc.h" -#define ARRAY_SZ 256 +#define ARGS_SZ 256 * 32 -static int ps; -static long length; -static char *array[ARRAY_SZ]; +static char *args[ARGS_SZ]; static char *arg; -static struct rlimit rl = { - .rlim_cur = RLIM_INFINITY, - .rlim_max = RLIM_INFINITY, -}; +static long *arg_count, *change, *arg_count_next; static void thp_test(void) { - int i; pid_t pid; - switch (pid = SAFE_FORK()) { - case 0: - memset(arg, 'c', length - 1); - arg[length - 1] = '\0'; - array[0] = "true"; - for (i = 1; i < ARRAY_SZ - 1; i++) - array[i] = arg; - array[ARRAY_SZ - 1] = NULL; - if (setrlimit(RLIMIT_STACK, &rl) == -1) { - perror("setrlimit"); - exit(1); - } - if (execvp("true", array) == -1) { - perror("execvp"); - exit(1); + while (*change > 1) { + *arg_count = *arg_count_next; + *change /= 2; + *arg_count_next = *arg_count + *change; + + pid = SAFE_FORK(); + if (!pid) { + args[*arg_count] = NULL; + + TEST(execvp("true", args)); + if (TEST_ERRNO != E2BIG) + tst_brk(TBROK | TTERRNO, "execvp(\"true\", ...)"); + + *arg_count_next = *arg_count - *change; + exit(0); } - default: + tst_res(TINFO, "count: %ld, change: %ld, next: %ld", + *arg_count, *change, *arg_count_next); tst_reap_children(); } + pid = SAFE_FORK(); + if (!pid) { + args[*arg_count] = NULL; + do { + TEST(execvp("true", args)); + if (TEST_ERRNO != E2BIG) + tst_brk(TBROK | TTERRNO, "execvp(\"true\", ...)"); + tst_res(TINFO, "Binary search finished on 2BIG value: %ld", + *arg_count); + args[--(*arg_count)] = NULL; + } while (*arg_count > 0); + exit(0); + } + tst_res(TPASS, "system didn't crash, pass."); } static void setup(void) { - ps = sysconf(_SC_PAGESIZE); - length = 32 * ps; - arg = SAFE_MALLOC(length); + struct rlimit rl = { + .rlim_cur = RLIM_INFINITY, + .rlim_max = RLIM_INFINITY, + }; + int i; + long arg_len; + + arg_count = SAFE_MMAP(NULL, sizeof(*arg_count) * 3, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_SHARED, -1, 0); + arg_count_next = arg_count + 1; + change = arg_count + 2; + + arg_len = sysconf(_SC_PAGESIZE); + arg = SAFE_MALLOC(arg_len); + memset(arg, 'c', arg_len - 1); + arg[arg_len - 1] = '\0'; + + args[0] = "true"; + *change = (ARGS_SZ - 1) / 2; + for (i = 1; i < ARGS_SZ - 1; i++) + args[i] = arg; + *arg_count_next += *change; + + SAFE_SETRLIMIT(RLIMIT_STACK, &rl); } static void cleanup(void) { - free(arg); + if (arg) + free(arg); + if (arg_count) + SAFE_MUNMAP(arg_count, sizeof(*arg_count)); } static struct tst_test test = { @@ -96,4 +133,5 @@ static struct tst_test test = { .setup = setup, .cleanup = cleanup, .test_all = thp_test, + .min_kver = "2.4", }; -- 2.14.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [LTP] [PATCH v2] thp01: Find largest arguments size 2017-09-01 14:13 ` [LTP] [PATCH v2] " Richard Palethorpe @ 2017-09-04 11:29 ` Li Wang 2017-09-11 9:26 ` Richard Palethorpe 0 siblings, 1 reply; 8+ messages in thread From: Li Wang @ 2017-09-04 11:29 UTC (permalink / raw) To: ltp On Fri, Sep 1, 2017 at 10:13 PM, Richard Palethorpe <rpalethorpe@suse.com> wrote: > > static void thp_test(void) > { > - int i; > pid_t pid; > > - switch (pid = SAFE_FORK()) { > - case 0: > - memset(arg, 'c', length - 1); > - arg[length - 1] = '\0'; > - array[0] = "true"; > - for (i = 1; i < ARRAY_SZ - 1; i++) > - array[i] = arg; > - array[ARRAY_SZ - 1] = NULL; > - if (setrlimit(RLIMIT_STACK, &rl) == -1) { > - perror("setrlimit"); > - exit(1); > - } > - if (execvp("true", array) == -1) { > - perror("execvp"); > - exit(1); > + while (*change > 1) { > + *arg_count = *arg_count_next; > + *change /= 2; > + *arg_count_next = *arg_count + *change; > + > + pid = SAFE_FORK(); > + if (!pid) { > + args[*arg_count] = NULL; > + > + TEST(execvp("true", args)); Do binary search in shared memory is really good to performance. But here maybe we could NOT find the largest arguments size rightly. Cut from manual page: "Traditionally, the functions execlp() and execvp() ignored all errors except for the ones described above and ENOMEM and E2BIG, upon which they returned. They now return if any error other than the ones described above occurs." Let me give an example, if we just add one line in your thp01.c as: --- a/testcases/kernel/mem/thp/thp01.c +++ b/testcases/kernel/mem/thp/thp01.c @@ -65,6 +65,7 @@ static void thp_test(void) if (TEST_ERRNO != E2BIG) tst_brk(TBROK | TTERRNO, "execvp(\"true\", ...)"); + printf("debuginfo: *arg_count = %ld\n", *arg_count); *arg_count_next = *arg_count - *change; exit(0); } Compile and run thp01 as below: # ./thp01 tst_test.c:908: INFO: Timeout per run is 0h 05m 00s thp01.c:76: INFO: count: 4095, change: 2047, next: 6142 debuginfo: *arg_count = 4095 thp01.c:76: INFO: count: 2048, change: 1023, next: 3071 debuginfo: *arg_count = 2048 thp01.c:76: INFO: count: 1025, change: 511, next: 1536 thp01.c:76: INFO: count: 1536, change: 255, next: 1791 debuginfo: *arg_count = 1536 thp01.c:76: INFO: count: 1281, change: 127, next: 1408 thp01.c:76: INFO: count: 1408, change: 63, next: 1471 thp01.c:76: INFO: count: 1471, change: 31, next: 1502 thp01.c:76: INFO: count: 1502, change: 15, next: 1517 thp01.c:76: INFO: count: 1517, change: 7, next: 1524 thp01.c:76: INFO: count: 1524, change: 3, next: 1527 thp01.c:76: INFO: count: 1527, change: 1, next: 1528 thp01.c:95: PASS: system didn't crash, pass. Summary: passed 1 failed 0 skipped 0 warnings 0 Do you notice that some debuginfo sentence have not been printed? because it will be never return if the children process run successfully. Though the while loop finished and *chage == 1, the *arg_count == 1527 is still not the largest value as we expected. I'm not sure if that is on purpose, if yes, maybe you should not say find largest arguments size in the subject. :) > > + pid = SAFE_FORK(); > + if (!pid) { > + args[*arg_count] = NULL; > + do { > + TEST(execvp("true", args)); > + if (TEST_ERRNO != E2BIG) > + tst_brk(TBROK | TTERRNO, "execvp(\"true\", ...)"); > + tst_res(TINFO, "Binary search finished on 2BIG value: %ld", > + *arg_count); > + args[--(*arg_count)] = NULL; > + } while (*arg_count > 0); > + exit(0); > + } > + here also need: tst_reap_children(); > tst_res(TPASS, "system didn't crash, pass."); > } -- Li Wang liwang@redhat.com ^ permalink raw reply [flat|nested] 8+ messages in thread
* [LTP] [PATCH v2] thp01: Find largest arguments size 2017-09-04 11:29 ` Li Wang @ 2017-09-11 9:26 ` Richard Palethorpe 0 siblings, 0 replies; 8+ messages in thread From: Richard Palethorpe @ 2017-09-11 9:26 UTC (permalink / raw) To: ltp Hello Li, Li Wang writes: > Cut from manual page: > "Traditionally, the functions execlp() and execvp() ignored all > errors except for the ones described above and ENOMEM and E2BIG, upon > which they returned. They now return if any error other than the ones > described above occurs." > > Let me give an example, if we just add one line in your thp01.c as: > > --- a/testcases/kernel/mem/thp/thp01.c > +++ b/testcases/kernel/mem/thp/thp01.c > @@ -65,6 +65,7 @@ static void thp_test(void) > if (TEST_ERRNO != E2BIG) > tst_brk(TBROK | TTERRNO, > "execvp(\"true\", ...)"); > > + printf("debuginfo: *arg_count = %ld\n", *arg_count); > *arg_count_next = *arg_count - *change; > exit(0); > } > > > > Compile and run thp01 as below: > > # ./thp01 > tst_test.c:908: INFO: Timeout per run is 0h 05m 00s > thp01.c:76: INFO: count: 4095, change: 2047, next: 6142 > debuginfo: *arg_count = 4095 > thp01.c:76: INFO: count: 2048, change: 1023, next: 3071 > debuginfo: *arg_count = 2048 > thp01.c:76: INFO: count: 1025, change: 511, next: 1536 > thp01.c:76: INFO: count: 1536, change: 255, next: 1791 > debuginfo: *arg_count = 1536 > thp01.c:76: INFO: count: 1281, change: 127, next: 1408 > thp01.c:76: INFO: count: 1408, change: 63, next: 1471 > thp01.c:76: INFO: count: 1471, change: 31, next: 1502 > thp01.c:76: INFO: count: 1502, change: 15, next: 1517 > thp01.c:76: INFO: count: 1517, change: 7, next: 1524 > thp01.c:76: INFO: count: 1524, change: 3, next: 1527 > thp01.c:76: INFO: count: 1527, change: 1, next: 1528 > thp01.c:95: PASS: system didn't crash, pass. > > Summary: > passed 1 > failed 0 > skipped 0 > warnings 0 > > > Do you notice that some debuginfo sentence have not been printed? > because it will be never return if the children process run > successfully. Though the while loop finished and *chage == 1, the > *arg_count == 1527 is still not the largest value as we expected. > > I'm not sure if that is on purpose, if yes, maybe you should not say > find largest arguments size in the subject. :) > I set the initial value of change incorrectly, so it wasn't finding the highest arg count value. It should now finish on either the correct value or the correct value plus one (which is then corrected by the linear search afterwards). Note that I am setting *arg_count_next before and after execvp(). Overwriting the first value if execvp fails. So I am deliberately using the fact it does not return on success. > >> >> + pid = SAFE_FORK(); >> + if (!pid) { >> + args[*arg_count] = NULL; >> + do { >> + TEST(execvp("true", args)); >> + if (TEST_ERRNO != E2BIG) >> + tst_brk(TBROK | TTERRNO, "execvp(\"true\", ...)"); >> + tst_res(TINFO, "Binary search finished on 2BIG value: %ld", >> + *arg_count); >> + args[--(*arg_count)] = NULL; >> + } while (*arg_count > 0); >> + exit(0); >> + } >> + > > here also need: tst_reap_children(); Thanks, added. -- Thank you, Richard. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2017-09-11 9:26 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-08-31 8:34 [LTP] [PATCH] thp01: Find largest arguments size Richard Palethorpe 2017-09-01 7:05 ` Li Wang 2017-09-01 9:34 ` Richard Palethorpe 2017-09-01 10:44 ` Li Wang 2017-09-01 10:03 ` Cyril Hrubis 2017-09-01 14:13 ` [LTP] [PATCH v2] " Richard Palethorpe 2017-09-04 11:29 ` Li Wang 2017-09-11 9:26 ` Richard Palethorpe
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox