4

File h.cpp

#include "yaml-cpp/yaml.h"
#include <iostream>
int main() {
    YAML::Node node = YAML::Load("[1, 2, 3]");
    std::cout << node << "\n";
    std::cout << node.Type() << "\n";
    std::cout << node.IsSequence() << "\n";
}

compiled and executed with

g++ -lyaml-cpp h.cpp && ./a.out

yields

[1, 2, 3]
3
1

on my desktop, but

[1, 2, 3]
1
0

on my laptop. The last line of laptop output is wrong: For sure, the given YAML string is a sequence.

Same results when g++ is replaced by clang++. Both machines run the same Debian 4.18.10-2, both are x86_64, both run Linux 4.18.0-2-amd64, both have same versions of g++ and clang++. Both have the same yaml-cpp library versions, freshly reinstalled:

$ locate libyaml-cpp.
/usr/lib/x86_64-linux-gnu/libyaml-cpp.a
/usr/lib/x86_64-linux-gnu/libyaml-cpp.so
/usr/lib/x86_64-linux-gnu/libyaml-cpp.so.0.5
/usr/lib/x86_64-linux-gnu/libyaml-cpp.so.0.5.2

$ dpkg -S /usr/lib/x86_64-linux-gnu/libyaml-cpp.a
libyaml-cpp-dev: /usr/lib/x86_64-linux-gnu/libyaml-cpp.a
$ dpkg -S /usr/lib/x86_64-linux-gnu/libyaml-cpp.so.0.5.2
libyaml-cpp0.5v5:amd64: /usr/lib/x86_64-linux-gnu/libyaml-cpp.so.0.5.2

$ apt-cache show libyaml-cpp-dev
Package: libyaml-cpp-dev
Source: yaml-cpp
Version: 0.5.2-4
$ apt-cache show libyaml-cpp0.5v5
Package: libyaml-cpp0.5v5
Source: yaml-cpp
Version: 0.5.2-4

Output from ldd is identical except for the hex addresses in parentheses:

$ ldd a.out
    linux-vdso.so.1 (0x00007ffd0d5f0000)
    libyaml-cpp.so.0.5 => /usr/lib/x86_64-linux-gnu/libyaml-cpp.so.0.5 (0x00007f1e9fcd8000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1e9fb55000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1e9f9c1000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1e9f9a7000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1e9f7ea000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f1e9ff79000)

What possible explanations remain in such a situation?

Joachim W
  • 7,290
  • 5
  • 31
  • 59
  • 2
    You may not be running the `a.out` you think you are running in one or both environments, especially if the `PATH` differs between the two. Avoid this risk by specifically executing `./a.out` instead of relying on a path lookup to find the executable. – John Bollinger Nov 09 '18 at 22:46
  • Valid point, but not the explanation here. I'll edit the question to rule out this possibility. – Joachim W Nov 09 '18 at 23:05
  • 2
    The most reasonable explanation is the YAML library is having undefined behavior. You can try running it under sanitizers or manually check the code. – Daniel Nov 09 '18 at 23:09
  • It might be helpful to see what this outputs: `std::cout << node.Type() << " : " << YAML::NodeType::Sequence << "\n";` – David Schwartz Nov 10 '18 at 00:04
  • `node.Type()` output also differs, `3` vs `1` – Joachim W Nov 10 '18 at 06:16
  • Edited question to include `node.Type()`. – Joachim W Nov 10 '18 at 21:29
  • The bug disappears if I replace libyaml-cpp-0.5 from Debian by the current master branch (post 0.6.2) from the libyaml-cpp git repository. This supports @Dani's suggestion, right? – Joachim W Nov 10 '18 at 21:31

1 Answers1

1

The bug disappears if I replace libyaml-cpp-0.5 from Debian by the current master branch (post 0.6.2) from the libyaml-cpp git repository. This strongly supports the hypothesis that the cause of the bug is undefined behavior in libyaml-cpp.

I won't investigate further. For the time being, I'll use version 0.6. In the long run, I will migrate to the C library libyaml, which is much more stable than libyaml-cpp.

Joachim W
  • 7,290
  • 5
  • 31
  • 59
  • Unless the bug has been specifically identified the idea of "no need to investigate further" seems quite questionable. When are you going to investigate? after the airplane exploded? If it was for example a consequence of uninitialized variable or undefined behavior in the code may be that now the code "works" by accidente, ready to bite harder later. – 6502 Dec 01 '18 at 21:36
  • Interesting question though: how probable is it that an unmature library like libyaml-cpp makes it into airplane software? – Joachim W Dec 01 '18 at 21:46
  • 1
    Zero, I hope, but that's not my decision. I didn't know the library but after taking a look at a just one file (binary.cpp, the first in alphabetical order, handling base64) I can already see a couple of problems (it uses `std::isspace(input[i])` forgetting the mandatory cast to `(unsigned char)` and also whitespace is skipped over, but this is not considered when checking if the "previous" char at `input[i-1]` is an equal sign or not... what if the previous char was skipped over?). – 6502 Dec 01 '18 at 22:55