0

I have the next experimental code. That code fail with segmentation fault on the labeled line.

If I take out the str2MxfKey function from anonymous namespace or give a some name to namespace, code will run without any problem.

That strange behavior reproduced only on the release build. Could someone explain me root cause of that problem?

Ubuntu 22.04, cmake 3.22.1, gcc 11.3.0

struct mxfKey
{
    uint8_t octet0;
    uint8_t octet1;
    uint8_t octet2;
    uint8_t octet3;
    uint8_t octet4;
    uint8_t octet5;
    uint8_t octet6;
    uint8_t octet7;
    uint8_t octet8;
    uint8_t octet9;
    uint8_t octet10;
    uint8_t octet11;
    uint8_t octet12;
    uint8_t octet13;
    uint8_t octet14;
    uint8_t octet15;
};

namespace {
    mxfKey str2MxfKey(const std::wstring &str) {
        mxfKey k;

        int rc = swscanf(str.c_str(),
                         L"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", // mxfkey
                         &k.octet0, &k.octet1, &k.octet2, &k.octet3,
                         &k.octet4, &k.octet5, &k.octet6, &k.octet7,
                         &k.octet8, &k.octet9, &k.octet10, &k.octet11,
                         &k.octet12, &k.octet13, &k.octet14, &k.octet15);
        if (rc != 16) {
            throw std::runtime_error("Error in str2MxfKey");
        }
        return k;
    }
}

void someExperiments() {
    std::wstring wstr = L"8c2197ad00e9476b8213b367123e506e";

    std::wcout << "Start" << std::endl;
    str2MxfKey(wstr);
    std::wcout << wstr << std::endl; // <----  Segmentation fault (core dumped)
    std::wcout << "End" << std::endl;
}

int main(int argc, char* argv[]) {
    someExperiments();
    ...
}
  • 1
    the cause for a segfault is often not where the segfault happens. Also changing seemingly unrelated parts of the code having impact on what the code does is a good indication for undefined behavior. – 463035818_is_not_an_ai Jan 12 '23 at 20:41
  • 1
    [works without problems for me](https://godbolt.org/z/3fx534xqv) please show a [mre] – Alan Birtles Jan 12 '23 at 20:45
  • 1
    @AlanBirtles You should have compiled this with -Wpedantic or something similar. VS2022 gives this warning explaining the problem: rning C4477: 'swscanf' : format string '%02x' requires an argument of type 'unsigned int *', but variadic argument 16 has type 'uint8_t *' – Gunther Jan 12 '23 at 20:50
  • @Gunther weird, can't get gcc or clang to complain about this code https://godbolt.org/z/5Td44G8Kd – Alan Birtles Jan 12 '23 at 20:55
  • Looks like clang and gcc don't crash if the with of the bytes is short enough: https://godbolt.org/z/K1fKzh3nz – Alan Birtles Jan 12 '23 at 21:01

1 Answers1

2

The swscanf format string is wrong. %02x expects an unsigned int and not uint8_t.

Try this instead:

    int rc = swscanf(str.c_str(),
        L"%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", // mxfkey
        &k.octet0, &k.octet1, &k.octet2, &k.octet3,
        &k.octet4, &k.octet5, &k.octet6, &k.octet7,
        &k.octet8, &k.octet9, &k.octet10, &k.octet11,
        &k.octet12, &k.octet13, &k.octet14, &k.octet15);
Gunther
  • 374
  • 2
  • 10