Skip to content

Possible bug in os/posix/osapi.c when running osal-core-test / BSEM tests. #337

@stanislaw

Description

@stanislaw

Describe the bug

I apologize in advance in case the issue I am reporting is caused by my misunderstanding of the OSAL POSIX code and the problem is rather somewhere on my end.

I am trying to port the POSIX OSAL code to macOS. It is a rather long adventure but it looks like there can be a happy end. By now I am going through all of the unit and integration tests in this repository in order to see which things have to be changed in order to run on macOS.

This issue I have first reported on StackOverflow because I thought the problem was on the macOS side: Calling pthread_cond_destroy results in “Function not implemented” ENOSYS on macOS.

if (pthread_cond_destroy(&(sem->cv)) != 0) {
    printf("pthread_cond_destroy %d %s\n", errno, strerror(errno)); // my addition
    ...
}

results in pthread_cond_destroy 78 Function not implemented as I am running it on macOS.

Looking at the code further I have found that there might be a bug in the OS_BinSemCreate_Impl function along these lines:

        /*
         ** Initialize the condition variable
         */
        ret = pthread_cond_init(&(sem->cv), NULL);
        if (ret != 0)
        {
            OS_DEBUG("Error: pthread_cond_init failed: %s\n",strerror(ret));
            return_code = OS_SEM_FAILURE;
            break;
        }

        cond_created = 1;

        /*
         ** fill out the proper OSAL table fields
         */

        memset(sem, 0, sizeof (*sem));
        sem->current_value = initial_value;

        return_code = OS_SUCCESS;

I would like to highlight that the memset(sem, 0, sizeof (*sem)); happens AFTER the ret = pthread_cond_init(&(sem->cv), NULL); line which means that memset corrupts the work that is done by pthread_cond_init.

If I put the memset string BEFORE the pthread_cond_init line, the BSEM test passes.

To Reproduce

I am reproducing this on a private fork of nasa/osal and it is a very hacky branch to make it work on macOS. At the moment I can only suggest to do a mental reasoning about the critical lines: memset... and pthread_cond_init... lines as I described above.

Expected behavior

This is how the test log looks like with my change above and this is what I expect to always happen:

/Users/stanislaw/workspace/code/cfs-osal-posix-mac/cmake-build-debug/tests/osal-core-test

[BEGIN] PC-LINUX UNIT TEST

[BEGIN] 01 BSEM
[ PASS] 01.001 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.002 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.003 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.004 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.005 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.006 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.007 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.008 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.009 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.010 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.011 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.012 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.013 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.014 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.015 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.016 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.017 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.018 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.019 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.020 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.021 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.022 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.023 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.024 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.025 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.026 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.027 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.028 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.029 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.030 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.031 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.032 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.033 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.034 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.035 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.036 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.037 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.038 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.039 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.040 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.041 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.042 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.043 osal-core-test.c:334 - OS_BinSemCreate, recreate 0
[ PASS] 01.044 osal-core-test.c:338 - OS_BinSemCreate, dupe name 0
[ PASS] 01.045 osal-core-test.c:342 - OS_BinSemCreate, recreate 2
[ PASS] 01.046 osal-core-test.c:346 - OS_BinSemCreate, recreate 3
[ PASS] 01.047 osal-core-test.c:353 - OS_BinSemGetIdByName, Bin 0
[ PASS] 01.048 osal-core-test.c:357 - OS_BinSemGetIdByName, Bin 1
[ PASS] 01.049 osal-core-test.c:361 - OS_BinSemGetIdByName, Bin 2
[ PASS] 01.050 osal-core-test.c:365 - OS_BinSemGetIdByName, Bin 3
[ PASS] 01.051 osal-core-test.c:371 - OS_BinSemDelete, Old ID
[ PASS] 01.052 osal-core-test.c:375 - OS_BinSemDelete, Bin 0
[ PASS] 01.053 osal-core-test.c:380 - OS_BinSemDelete, Bin 1
[ PASS] 01.054 osal-core-test.c:383 - OS_BinSemDelete, Bin 2
[ PASS] 01.055 osal-core-test.c:386 - OS_BinSemDelete, Bin 3
[  END] 01 BSEM                 TOTAL::55    PASS::55    FAIL::0      MIR::0      TSF::0      N/A::0   

COMPLETE: 1 tests Segment(s) executed


Process finished with exit code 0

Code snips
If applicable, add references to the software.

System observed on:

  • MacBook Pro (13-inch, 2017, Four Thunderbolt 3 Ports)
  • OS: macOS Mojave 10.14.6 (18G87)
  • Versions OSAL repository build from this commit:
commit 155e9ebcd6d1930890231a44237e6883d229d22c
Author: Jake Hageman <[email protected]>
Date:   Sat Nov 30 13:47:11 2019 -0500

    Update version and README

Additional context

This is how the issue manifests itself (I am only running the related tests).

/Users/stanislaw/workspace/code/cfs-osal-posix-mac/cmake-build-debug/tests/osal-core-test

[BEGIN] PC-LINUX UNIT TEST

[BEGIN] 01 BSEM
[ PASS] 01.001 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.002 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.003 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.004 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.005 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.006 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.007 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.008 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.009 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.010 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.011 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.012 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.013 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.014 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.015 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.016 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.017 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.018 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.019 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.020 osal-core-test.c:312 - OS_BinSemCreate, nominal
[ PASS] 01.021 osal-core-test.c:312 - OS_BinSemCreate, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.022 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.023 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.024 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.025 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.026 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.027 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.028 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.029 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.030 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.031 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.032 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.033 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.034 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.035 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.036 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.037 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.038 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.039 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.040 osal-core-test.c:323 - OS_BinSemDelete, nominal
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.041 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ PASS] 01.042 osal-core-test.c:323 - OS_BinSemDelete, nominal
[ FAIL] 01.043 osal-core-test.c:334 - OS_BinSemCreate, recreate 0
[ PASS] 01.044 osal-core-test.c:338 - OS_BinSemCreate, dupe name 0
[ FAIL] 01.045 osal-core-test.c:342 - OS_BinSemCreate, recreate 2
[ FAIL] 01.046 osal-core-test.c:346 - OS_BinSemCreate, recreate 3
[ PASS] 01.047 osal-core-test.c:353 - OS_BinSemGetIdByName, Bin 0
[ FAIL] 01.048 osal-core-test.c:357 - OS_BinSemGetIdByName, Bin 1
[ PASS] 01.049 osal-core-test.c:361 - OS_BinSemGetIdByName, Bin 2
[ PASS] 01.050 osal-core-test.c:365 - OS_BinSemGetIdByName, Bin 3
pthread_cond_destroy 78 Function not implemented
[ PASS] 01.051 osal-core-test.c:371 - OS_BinSemDelete, Old ID
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.052 osal-core-test.c:375 - OS_BinSemDelete, Bin 0
pthread_cond_destroy 78 Function not implemented
[ PASS] 01.053 osal-core-test.c:380 - OS_BinSemDelete, Bin 1
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.054 osal-core-test.c:383 - OS_BinSemDelete, Bin 2
pthread_cond_destroy 78 Function not implemented
[ FAIL] 01.055 osal-core-test.c:386 - OS_BinSemDelete, Bin 3
[  END] 01 BSEM                 TOTAL::55    PASS::28    FAIL::27     MIR::0      TSF::0      N/A::0   

COMPLETE: 1 tests Segment(s) executed


Process finished with exit code 2

This is the original StackOverflow report:

I am trying to make some Linux-based code run on macOS. It is the POSIX OSAL layer for NASA Core Flight System as found here: https://github.com/nasa/osal.

I am observing that the code uses POSIX conditions and in particular, there is a call like the following:

    if (pthread_cond_destroy(&(sem->cv)) != 0) {
        printf("pthread_cond_destroy %d %s\n", errno, strerror(errno)); // my addition
        ...
    }

On macOS, the tests related to this code provided in the OSAL repository always fail because the call to `pthread_cond_destroy` always results in:

    pthread_cond_destroy 78 Function not implemented

I have found an example in the Apple documentation which shows an example of [Using Conditions](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html#//apple_ref/doc/uid/10000057i-CH8-SW4) (Threading Programming Guide / Synchronization / Using Conditions) and in that example there is no call to `pthread_cond_destroy` but I cannot make any conclusions on whether that call should be there or not because the example is simplified.

This is how the header looks like on my machine:

    __API_AVAILABLE(macos(10.4), ios(2.0))
    int pthread_cond_destroy(pthread_cond_t *);


I am wondering if `pthread_cond_*` functionality is simply missing on macOS and I have to implement a replacement for it or there is some way to make it work.

EDIT: The minimal example is working fine for me. The problem should be somewhere around the problematic code. What I still don't understand is why I am getting ENOSYS/78 error code, for one thing it is not mentioned on the man page [man/3/pthread_cond_destroy](https://linux.die.net/man/3/pthread_cond_destroy): 

    #include <iostream>
    #include <pthread.h>

    int main() {
      pthread_cond_t condition;
      pthread_cond_init(&condition, NULL);
      int result = pthread_cond_destroy(&condition);
      assert(result == 0);
      assert(errno == 0);
      std::cout << "Hello, World!" << std::endl;
      return 0;
    }

Reporter Info
Stanislav Pankevich

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions