orangeduck / ptest

DRY Microtesting Framework for C

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Segmentation Fault whenever nested functions tests are used

Oxore opened this issue · comments

My gcc -v output:

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/7.2.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib --disable-werror --enable-checking=release --enable-default-pie --enable-default-ssp
Thread model: posix
gcc version 7.2.1 20171128 (GCC)

When I simply run make it produces such an output:

gcc -ansi -Wall -Werror -Wno-unused -g example.c ptest.c -o example
./example; true

    +-------------------------------------------+
    | ptest          MicroTesting Magic for C   |
    |                                           |
    | http://github.com/orangeduck/ptest        |
    |                                           |
    | Daniel Holden (contact@theorangeduck.com) |
    +-------------------------------------------+


  ===== Suite Basic =====

    | Test Maths ... Failed! 

        1. Segmentation Fault

    | Stopping Execution.
gcc -ansi -Wall -Werror -Wno-unused -g example2.c ptest.c -o example2
./example2; true

    +-------------------------------------------+
    | ptest          MicroTesting Magic for C   |
    |                                           |
    | http://github.com/orangeduck/ptest        |
    |                                           |
    | Daniel Holden (contact@theorangeduck.com) |
    +-------------------------------------------+


  ===== Suite Basic =====

    | Test Maths ... Passed!
    | Test Strings ... Passed!


  ===== Suite Other =====

    | Test Stuff ... Passed!
    | Test Failure ... Failed! 

        1. Assert [ false == true ] (example2.c:26)


  +---------------------------------------------------+
  |                      Summary                      |
  +---------++------------+-------------+-------------+
  | Suites  || Total    2 | Passed    1 | Failed    1 |
  | Tests   || Total    4 | Passed    3 | Failed    1 |
  | Asserts || Total    9 | Passed    8 | Failed    1 |
  +---------++------------+-------------+-------------+

      Total Running Time: 0.000s

As far as I can see my gcc is able to compile nested functions, but when this function call is made (I think at ptest.c:293) a segfault occurs.

What am I doing wrong or is it a bug?

Hi Oxore,

This looks pretty weird - I've seen this happen occasionally when clang is used but not gcc. I assume ptest works fine if you use it without making use of nested functions?

Thanks,

Dan

Hi Daniel!

Yes, ptest works fine when no nested tests are used. I like this!

I have made a small investigation and figured out that error occurs most likely due to a changes made in newer gcc versions.

At first I took a look at PT_TEST(name) macro implementation: It declares a nested test function and passes it's pointer to pt_add_test() function. This nested test function exists in the parent test suite function only, but later we call this test function in a pt_run() by invoking test.func() (ptest.c:293). Maybe I do not understand some C language features and nested functions live by other rules than a loacal variables? Or they were... at the date you made last commit (Feb 22, 2015) and before?

In order to keep experiment clean I have downloaded old ubuntu 12.04.5 (gcc version 4.6.3) and newer one Ubuntu 17.10 (7.2.0).

As I expected on old Ubuntu with old gcc nested tests are compiled and work fine:

ubuntu@ubuntu:~/ptest$ make
gcc -ansi -Wall -Werror -Wno-unused -g example.c ptest.c -o example
./example; true

    +-------------------------------------------+
    | ptest          MicroTesting Magic for C   |
    |                                           |
    | http://github.com/orangeduck/ptest        |
    |                                           |
    | Daniel Holden (contact@theorangeduck.com) |
    +-------------------------------------------+


  ===== Suite Basic =====

    | Test Maths ... Passed!
    | Test Strings ... Passed!


  ===== Suite Other =====

    | Test Stuff ... Passed!
    | Test Failure ... Failed! 

        1. Assert [ 0 ] (example.c:29)


  +---------------------------------------------------+
  |                      Summary                      |
  +---------++------------+-------------+-------------+
  | Suites  || Total    2 | Passed    1 | Failed    1 |
  | Tests   || Total    4 | Passed    3 | Failed    1 |
  | Asserts || Total    9 | Passed    8 | Failed    1 |
  +---------++------------+-------------+-------------+

      Total Running Time: 0.000s

gcc -ansi -Wall -Werror -Wno-unused -g example2.c ptest.c -o example2
./example2; true

    +-------------------------------------------+
    | ptest          MicroTesting Magic for C   |
    |                                           |
    | http://github.com/orangeduck/ptest        |
    |                                           |
    | Daniel Holden (contact@theorangeduck.com) |
    +-------------------------------------------+


  ===== Suite Basic =====

    | Test Maths ... Passed!
    | Test Strings ... Passed!


  ===== Suite Other =====

    | Test Stuff ... Passed!
    | Test Failure ... Failed! 

        1. Assert [ false == true ] (example2.c:26)


  +---------------------------------------------------+
  |                      Summary                      |
  +---------++------------+-------------+-------------+
  | Suites  || Total    2 | Passed    1 | Failed    1 |
  | Tests   || Total    4 | Passed    3 | Failed    1 |
  | Asserts || Total    9 | Passed    8 | Failed    1 |
  +---------++------------+-------------+-------------+

      Total Running Time: 0.000s

ubuntu@ubuntu:~/ptest$ gcc0v
gcc0v: command not found
ubuntu@ubuntu:~/ptest$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

New Ununtu 17.10 gave me more interesting result:

ubuntu@ubuntu:~/ptest$ make
gcc -ansi -Wall -Werror -Wno-unused -g example.c ptest.c -o example
./example; true

    +-------------------------------------------+
    | ptest          MicroTesting Magic for C   |
    |                                           |
    | http://github.com/orangeduck/ptest        |
    |                                           |
    | Daniel Holden (contact@theorangeduck.com) |
    +-------------------------------------------+


  ===== Suite Basic =====

    | Test Maths ... Failed! 

        1. Illegal Instruction

    | Stopping Execution.
gcc -ansi -Wall -Werror -Wno-unused -g example2.c ptest.c -o example2
./example2; true

    +-------------------------------------------+
    | ptest          MicroTesting Magic for C   |
    |                                           |
    | http://github.com/orangeduck/ptest        |
    |                                           |
    | Daniel Holden (contact@theorangeduck.com) |
    +-------------------------------------------+


  ===== Suite Basic =====

    | Test Maths ... Passed!
    | Test Strings ... Passed!


  ===== Suite Other =====

    | Test Stuff ... Passed!
    | Test Failure ... Failed! 

        1. Assert [ false == true ] (example2.c:26)


  +---------------------------------------------------+
  |                      Summary                      |
  +---------++------------+-------------+-------------+
  | Suites  || Total    2 | Passed    1 | Failed    1 |
  | Tests   || Total    4 | Passed    3 | Failed    1 |
  | Asserts || Total    9 | Passed    8 | Failed    1 |
  +---------++------------+-------------+-------------+

      Total Running Time: 0.000s

ubuntu@ubuntu:~/ptest$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.2.0-8ubuntu3' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.2.0 (Ubuntu 7.2.0-8ubuntu3) 
ubuntu@ubuntu:~/ptest$

My current system is Arch GNU/Linux 4.14.8 with gcc version 7.2.1 (full gcc information in the fist post) produces result that is close to Ubuntu 17.10 with almost the same gcc version (7.2.0) result.

I'm actually a newbie at C language and gcc compilation, but I hope I am helping.

Great investigation. Yes that is entirely possible that gcc is now allocating nested functions locally inside their container function. It seems to match what is written here: http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html

I don't know if the documentation has been updated to match the new behavior of it I just didn't read it carefully before but it seems that it we shouldn't be able to call the test after the containing function has exited so I guess that is why it is crashing.

Looks like I may have to re-think the structure of this library for use in the nested form...