msys2 / msys2-runtime

Our friendly fork of Cygwin πŸ’– https://cygwin.org πŸ’– see the wiki for details
https://github.com/msys2/msys2-runtime/wiki
GNU General Public License v2.0
178 stars 39 forks source link

Standard C library function not linked correctly in simple tests project #90

Open sport-climber opened 2 years ago

sport-climber commented 2 years ago

The problem I'm having is building and linking against a library that I'm doing unit test on. This previously worked in msys2 for many years (though a previous release broke it in the same way and was subsequently fixed). The problem I'm observing is that some standard lib functions are not linking correctly into my application if used in the library under test. However, if the unit tests use that same function then it links correctly. The failure is repeatable on multiple computer.

The following tools are used:

  1. Windows 10+
  2. Msys2 - Installer build date - Feb 10, 2022
  3. Gcc v11.2.0
  4. binutils v2.37
  5. Cmake v3.22.1
  6. Cmocka v1.1.5
  7. lcov v1.13 (not used due to crash but would run and generate coverage report)

I've attached a simple project to illustrate the issue. The interesting thing is that the linking fails when the strncpy() call is in the library being unit tested. However, if we add a call to strncpy() to the unit test then the linker finds it in the library and correctly links the test.

The code under tests is located in the source files of relevance are: ./msys2_gcc_v11_bug.c //Source below:

void msys2_gcc_v11_string_linker_bug(char * folderPath, size_t folderPathLen, const char  * fname)
{
        folderPath[folderPathLen] = '/';
        strncpy(&folderPath[folderPathLen + 1], fname, strlen(fname));
}

./unit_test/test-msys2_gcc_v11_bug.c // Test function - note #if 0 which allows the linking to operate correct if enabled

static void msys2_gcc_v11_bug_test(void ** state)
{
        #define TEST_BASE_PATH_STR "LOGS/Example"
        const char * test_basePathStr = TEST_BASE_PATH_STR;

        /* Allocate a buffer big enough to contain the path plus the largest file name. */
        char nodePathStr[64];
        strcpy(nodePathStr, TEST_BASE_PATH_STR);

        /* Enable a use of strncpy() in the test and the function is correctly link
         * to the application. Leave this disabled and the application segfaults
         * when the call to strncpy in the msys_gcc_v11_bug.c code is made. */
        #if 0

        char temp[64];
        strncpy(temp, "FORCED string", 64);
        printf(temp);
        #endif

        const size_t nodePathStrLen = strlen(nodePathStr);
        msys2_gcc_v11_string_linker_bug(nodePathStr, nodePathStrLen, "test_file");

        #undef TEST_BASE_PATH_STR

}

msys2_gcc_v11_bug.zip

So far I have traced the symbols using objdump at each stage of the compilation and noted that the symbols present and weak after the initial compile of the library under test. I've also recompiled and reinstalled CMake using the msys2 gcc v11 tool chain to see if that made any difference and it did not.

masta99wrfvsHsa commented 2 years ago

possibly related or similar to https://github.com/msys2/MSYS2-packages/issues/2966

sport-climber commented 1 year ago

possibly related or similar to msys2/MSYS2-packages#2966

I don't think so, the linked issue fails during the linking process.

My issue is a little different in that the code compiles and links successfully but crashes with a segfault when the code is run on the line for strncpy.