Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] 1.0.0: The test step_callback fails #338

Open
yurivict opened this issue Aug 11, 2023 · 15 comments
Open

[BUG] 1.0.0: The test step_callback fails #338

yurivict opened this issue Aug 11, 2023 · 15 comments
Labels
bug Something isn't working

Comments

@yurivict
Copy link

Describe the bug

108/123 Test #108: step_callback ....................***Failed    0.63 sec

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
step_callback is a Catch v2.13.10 host application.
Run with -? for options

-------------------------------------------------------------------------------
step_callback basics
-------------------------------------------------------------------------------
/usr/ports/math/heyoka/work/heyoka-1.0.0/test/step_callback.cpp:49
...............................................................................

/usr/ports/math/heyoka/work/heyoka-1.0.0/test/step_callback.cpp:58: FAILED:
  REQUIRE_THROWS_AS( step_cb(ta), std::bad_function_call )
due to unexpected exception with message:
  std::exception

===============================================================================
test cases:  3 |  2 passed | 1 failed
assertions: 31 | 30 passed | 1 failed

Environment (please complete the following information):

  • OS: FreeBSD 13.2
  • Installation method: port
  • Version: 1.0.0
@yurivict yurivict added the bug Something isn't working label Aug 11, 2023
@bluescarni
Copy link
Owner

bluescarni commented Aug 11, 2023

@yurivict the test is complaining that a generic std::exception is thrown instead of the more specific std::bad_function_call (which does inherit from std::exception):

https://en.cppreference.com/w/cpp/utility/functional/bad_function_call

I don't understand how this is possible, since the code explicitly throws std::bad_function_call:

https://github.com/bluescarni/heyoka/blob/master/src/step_callback.cpp#L74

I can amend the test to just check for something to be thrown, but I don't understand why this is failing only on FreeBSD.

If you replace the failing line with:

REQUIRE_THROWS_AS( step_cb(ta), std::exception );

and equivalently for the next line:

REQUIRE_THROWS_AS(step_cb.pre_hook(ta), std::exception);

Does this fix the failure?

@yurivict
Copy link
Author

I can amend the test to just check for something to be thrown, but I don't understand why this is failing only on FreeBSD.

It's better to understand why this is failing exactly.
I'll do some experiments too.

@yurivict
Copy link
Author

yurivict commented Aug 11, 2023

This code catches std::bad_function_call as thrown on FreeBSD:

#include <exception>
#include <iostream>

int main() {
        try {
                throw std::bad_function_call(); 
        } catch (std::bad_function_call e) {
                std::cout << "caught bad_function_call" << std::endl;
        } catch (std::exception e) {
                std::cout << "caught exception" << std::endl;
        }
}

The order of catch instructions is important.

@bluescarni
Copy link
Owner

This code catches std::bad_function_call as thrown on FreeBSD:

#include <exception>
#include <iostream>

int main() {
        try {
                throw std::bad_function_call(); 
        } catch (std::bad_function_call e) {
                std::cout << "caught bad_function_call" << std::endl;
        } catch (std::exception e) {
                std::cout << "caught exception" << std::endl;
        }
}

The order of catch instructions is important.

Thanks for checking! So it looks like the problem is not std::bad_function_call per se.

I just noticed that there is a similar usage of std::bad_function_call in the callable class. E.g., see this unit test:

https://github.com/bluescarni/heyoka/blob/master/test/callable.cpp#L154

Does this test pass fine on your setup?

@yurivict
Copy link
Author

Does this test pass fine on your setup?

All other tests pass.

@bluescarni
Copy link
Owner

@yurivict would you mind checking if the attached patch makes any difference?

https://gist.github.com/bluescarni/67b13d5959535ae2f58754741b1f8a73

@yurivict
Copy link
Author

The same test failure happens with this patch.

@bluescarni
Copy link
Owner

Ok, thanks for checking.

Under the assumption that FreeBSD is using libc++ as its C++ standard library... (otherwise, disregard everything I am writing here).

I noticed there is a difference in the implementation of exceptions classes in my local copy of libc++ (16.0.4). Specifically, an exception like std::invalid_argument is implemented as this (from the <stdexcept> header file):

class _LIBCPP_EXCEPTION_ABI invalid_argument
    : public logic_error
{
...

Whereas std::bad_function_call is implemented like this (from the <functional> header):

class bad_function_call
    : public exception
{
...

The important difference is the lack of _LIBCPP_EXCEPTION_ABI macro in the implementation of std::bad_function_call. This macro eventually expands to __declspec(dllexport) or __attribute__((__visibility__(vis))), depending on compiler/platform. These attribute are used to set the visibility of symbols across DLLs. In particular, exceptions classes should always be marked as visible otherwise there could be issues catching exceptions across DLL boundaries. See the discussion here:

https://gcc.gnu.org/wiki/Visibility

(in particular the "Problems with C++ exceptions" section).

So, could this be a bug in libc++? Do you have any way of finding out?

@bluescarni
Copy link
Owner

bluescarni commented Aug 11, 2023

@yurivict sorry disregard the above post, it turns out I was not looking at the correct file... bad_function_call does have the correct attribute set, at least on my local copy...

Which version of libc++ are you using?

@bluescarni
Copy link
Owner

@yurivict see also this report: llvm/llvm-project#54863 (comment)

@yurivict
Copy link
Author

Hi @bluescarni ,

Do you have a C++ testcase that fails?

Yuri

@bluescarni
Copy link
Owner

@yurivict could you tell me if the libc++ version you are using contains the symbol for std::bad_function_call? I.e., does something like

$ readelf -s -C --wide /usr/lib/libc++.so.1.0 |grep -i bad_function

return something?

@yurivict
Copy link
Author

$ readelf -s  --wide /usr/lib/libc++.so.1 |grep -i bad_function
   514: 00000000000fcb68    24 OBJECT  GLOBAL DEFAULT   22 _ZTINSt3__117bad_function_callE
  1776: 00000000000484c6    28 OBJECT  GLOBAL DEFAULT   10 _ZTSNSt3__117bad_function_callE
  2150: 00000000000fcb40    40 OBJECT  GLOBAL DEFAULT   22 _ZTVNSt3__117bad_function_callE
  2199: 00000000000a2420    10 FUNC    GLOBAL DEFAULT   14 _ZNSt3__117bad_function_callD2Ev
  2275: 00000000000a2420    10 FUNC    GLOBAL DEFAULT   14 _ZNSt3__117bad_function_callD1Ev
  2348: 00000000000a2430    28 FUNC    GLOBAL DEFAULT   14 _ZNSt3__117bad_function_callD0Ev

@bluescarni
Copy link
Owner

@yurivict would you mind checking also if libheyoka.so contains the symbol for bad_function_call? I.e., something like

$ readelf -s -C --wide libheyoka.so|grep -i bad_func

executed from the build directory of heyoka?

@yurivict
Copy link
Author

A weak symbol with this name is present:

$ readelf -a libheyoka.so | grep -i bad_func
000017f22720 02b800000001 R_X86_64_64         0000000017f22700 _ZTINSt3__117bad_function_callE + 0
000017f52030 02b800000006 R_X86_64_GLOB_DAT   0000000017f22700 _ZTINSt3__117bad_function_callE + 0
000017f52028 03d500000006 R_X86_64_GLOB_DAT   0000000017f22718 _ZTVNSt3__117bad_function_callE + 0
000017f22708 071200000001 R_X86_64_64         000000000012567a _ZTSNSt3__117bad_function_callE + 0
   696: 0000000017f22700    24 OBJECT  WEAK   DEFAULT   23 _ZTINSt3__117bad_function_callE
   981: 0000000017f22718    40 OBJECT  WEAK   DEFAULT   23 _ZTVNSt3__117bad_function_callE
  1810: 000000000012567a    28 OBJECT  WEAK   DEFAULT   11 _ZTSNSt3__117bad_function_callE
  2908: 0000000017c9d3d0    28 FUNC    LOCAL  HIDDEN    14 _ZNSt3__117bad_function_callD0Ev
  6312: 0000000017d22490    50 FUNC    LOCAL  HIDDEN    14 _ZNSt3__125__throw_bad_function_callB6v15007Ev
 29177: 0000000017f22718    40 OBJECT  WEAK   DEFAULT   23 _ZTVNSt3__117bad_function_callE
 29178: 0000000017f22700    24 OBJECT  WEAK   DEFAULT   23 _ZTINSt3__117bad_function_callE
 29861: 000000000012567a    28 OBJECT  WEAK   DEFAULT   11 _ZTSNSt3__117bad_function_callE
$ nm libheyoka.so | grep -i bad_func
0000000017c9d3d0 t _ZNSt3__117bad_function_callD0Ev
0000000017d22490 t _ZNSt3__125__throw_bad_function_callB6v15007Ev
0000000017f22700 V _ZTINSt3__117bad_function_callE
000000000012567a V _ZTSNSt3__117bad_function_callE
0000000017f22718 V _ZTVNSt3__117bad_function_callE

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants