[PATCH 1/2] Add a test for longjmp from user context

H.J. Lu hjl.tools@gmail.com
Thu Dec 14 22:42:43 GMT 2023


On Thu, Dec 14, 2023 at 2:39 PM Noah Goldstein <goldstein.w.n@gmail.com> wrote:
>
> On Thu, Dec 14, 2023 at 1:37 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> >
> > Verify that longjmp works correctly after setcontext is called to switch
> > to a user context.
> > ---
> >  stdlib/Makefile           |  1 +
> >  stdlib/tst-setcontext10.c | 87 +++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 88 insertions(+)
> >  create mode 100644 stdlib/tst-setcontext10.c
> >
> > diff --git a/stdlib/Makefile b/stdlib/Makefile
> > index 0b154e57c5..8c6249aab4 100644
> > --- a/stdlib/Makefile
> > +++ b/stdlib/Makefile
> > @@ -234,6 +234,7 @@ tests := \
> >    tst-setcontext7 \
> >    tst-setcontext8 \
> >    tst-setcontext9 \
> > +  tst-setcontext10 \
> >    tst-strfmon_l \
> >    tst-strfrom \
> >    tst-strfrom-locale \
> > diff --git a/stdlib/tst-setcontext10.c b/stdlib/tst-setcontext10.c
> > new file mode 100644
> > index 0000000000..2926753cb1
> > --- /dev/null
> > +++ b/stdlib/tst-setcontext10.c
> > @@ -0,0 +1,87 @@
> > +/* Check longjmp from user context to main context.
> > +   Copyright (C) 2023 Free Software Foundation, Inc.
> > +   This file is part of the GNU C Library.
> > +
> > +   The GNU C Library is free software; you can redistribute it and/or
> > +   modify it under the terms of the GNU Lesser General Public
> > +   License as published by the Free Software Foundation; either
> > +   version 2.1 of the License, or (at your option) any later version.
> > +
> > +   The GNU C Library is distributed in the hope that it will be useful,
> > +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> > +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > +   Lesser General Public License for more details.
> > +
> > +   You should have received a copy of the GNU Lesser General Public
> > +   License along with the GNU C Library; if not, see
> > +   <https://www.gnu.org/licenses/>.  */
> > +
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <setjmp.h>
> > +#include <ucontext.h>
> > +#include <unistd.h>
> > +
> > +static jmp_buf jmpbuf;
> > +static ucontext_t ctx;
> > +
> > +static void f2 (void);
> > +
> > +static void
> > +__attribute__ ((noinline, noclone))
> > +f1 (void)
> > +{
> > +  printf ("start f1\n");
> > +  f2 ();
> > +}
> > +
> > +static void
> > +__attribute__ ((noinline, noclone))
> > +f2 (void)
> > +{
> > +  printf ("start f2\n");
> > +  if (setcontext (&ctx) != 0)
> > +    {
> > +      printf ("%s: setcontext: %m\n", __FUNCTION__);
> > +      exit (EXIT_FAILURE);
> > +    }
> > +}
> > +
> > +static void
> > +f3 (void)
> > +{
> > +  printf ("start f3\n");
> > +  longjmp (jmpbuf, 1);
> > +}
> > +
> > +static int
> > +__attribute__ ((noinline, noclone))
> > +do_test_1 (void)
> > +{
> > +  char st1[32768];
> > +
> > +  if (setjmp (jmpbuf) != 0)
> > +    return 0;
> > +
> > +  puts ("making contexts");
> > +  if (getcontext (&ctx) != 0)
> > +    {
> > +      printf ("%s: getcontext: %m\n", __FUNCTION__);
> > +      exit (EXIT_FAILURE);
> > +    }
> > +  ctx.uc_stack.ss_sp = st1;
> > +  ctx.uc_stack.ss_size = sizeof st1;
> > +  ctx.uc_link = NULL;
> > +  makecontext (&ctx, (void (*) (void)) f3, 0);
> > +  f1 ();
> > +  puts ("FAIL: returned from f1 ()");
> > +  exit (EXIT_FAILURE);
> > +}
> > +
> > +static int
> > +do_test (void)
> > +{
> > +  return do_test_1 ();
> > +}
> > +
> > +#include <support/test-driver.c>
> > --
> > 2.43.0
> >
>
> What is the success path here?

When longjmp is called from the user context, do_test_1
returns 0:

if (setjmp (jmpbuf) != 0)
  return 0;

-- 
H.J.


More information about the Libc-alpha mailing list