Bug 1988 - Coojaloader gives unexpected output in case of using istringstream in C++
Coojaloader gives unexpected output in case of using istringstream in C++
Status: CONFIRMED
Product: dce
Classification: Unclassified
Component: other
unspecified
PC Linux
: P5 major
Assigned To: Hajime Tazaki
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2014-09-18 03:14 EDT by Hans van den Bogert
Modified: 2014-11-12 10:05 EST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Hans van den Bogert 2014-09-18 03:14:00 EDT
Using the following example code makes gives different output when comparing the natively run executable and when run under DCE (Cooja, DLM gives expected output)

[code]
#include <sstream>
#include <iostream>


main(int argc, char**  argv) {
  using std::istringstream;
  using std::string;
  istringstream is;

  int port;
  string s("3000");
  is.str(s);
  is.clear();
  is >> port;

  std::cout << port << std::endl;
}
[/code]

The expected output is 3000, the gotten output is 1.

Debugging this issue we can pinpoint to at least one position in the standard c++ library where something odd is happening when run under DCE:

[output]
std::locale::locale (this=0x7ffff7fb9dd0) at ../../../../../src/libstdc++-v3/src/c++98/locale_init.cc:221
221         _M_impl = _S_global;
(gdb)
222         if (_M_impl == _S_classic)
(gdb)
221         _M_impl = _S_global;
(gdb)
222         if (_M_impl == _S_classic)
(gdb) print _M_impl
$1 = (std::locale::_Impl *) 0x7fffefb5ae00 <(anonymous namespace)::c_locale_impl>
(gdb) print _S_global
$2 = (std::locale::_Impl *) 0x7ffff53f5e00 <(anonymous namespace)::c_locale_impl>
(gdb)
[/output]

We'd expect _M_impl and _S_classic to point to the same memory address after line 221, however this is not the case. The rest of the program's flow seems logical in the sense that pointing to a wrong locale object results in a failed parsing of the string to int.
Comment 1 Hans van den Bogert 2014-09-30 08:50:57 EDT
in the bug description there is an error:

> We'd expect _M_impl and _S_classic to point to the same memory address after line 221, however this is not the case.

Should be:

"We'd expect _M_impl and *_S_global* to point to the same memory address after line 221, however this is not the case."
Comment 2 Hans van den Bogert 2014-10-23 10:58:22 EDT
Further investigation shows that during static initialization (so even before the main function of the virtualized executable is run) the C++ library makes a wrong default locale. The locale is filled with facets, which handle aspects of a locale. However during the init-phase of this default locale one facet -- codecvt_w -- seems to get a wrong 'id'. That id is used as an index for a facet-vector inside the default locale. By having a wrong id, the standard library does not check this, it overwrites our num_get facet, which is responsible for converting input (character)streams to numbers and so the wrong behaviour arises.

I do not know how this wrong 'id' is given to the facet but I suspect wrong use of statics from the non-virtualized stdlibc++. The addition of thread-safety constructs in the stdlibc++ and GDB not showing addresses correctly (I suspect), for static variables when introspected makes this extremely difficult to debug.

I hope this helps.
Comment 3 Hajime Tazaki 2014-11-06 08:51:20 EST
(In reply to Hans van den Bogert from comment #2)
> Further investigation shows that during static initialization (so even
> before the main function of the virtualized executable is run) the C++
> library makes a wrong default locale. The locale is filled with facets,
> which handle aspects of a locale. However during the init-phase of this
> default locale one facet -- codecvt_w -- seems to get a wrong 'id'. That id
> is used as an index for a facet-vector inside the default locale. By having
> a wrong id, the standard library does not check this, it overwrites our
> num_get facet, which is responsible for converting input (character)streams
> to numbers and so the wrong behaviour arises.
> 
> I do not know how this wrong 'id' is given to the facet but I suspect wrong
> use of statics from the non-virtualized stdlibc++. The addition of
> thread-safety constructs in the stdlibc++ and GDB not showing addresses
> correctly (I suspect), for static variables when introspected makes this
> extremely difficult to debug.
> 
> I hope this helps.

I believe locale-related symbols are not appropriately handled by DCE: these should be handled manually which are done by following codes.

http://code.nsnam.org/ns-3-dce/file/579cac731917/model/libc-global-variables.cc
http://code.nsnam.org/ns-3-dce/file/579cac731917/model/libc-setup.cc

I couldn't allocate my time to investigate it, but hope this helps a bit for you.
Comment 4 Hans van den Bogert 2014-11-12 09:55:54 EST
You mean to say that those 2 files are examples of how other globals are handled, or should those 2 files fix my issue?
Comment 5 Hajime Tazaki 2014-11-12 10:05:40 EST
(In reply to Hans van den Bogert from comment #4)
> You mean to say that those 2 files are examples of how other globals are
> handled, or should those 2 files fix my issue?

Yes, but with a quick look and code changes didn't give me a direction how it should handle (that's why I mentioned I need more time).