operator<<(std::ostream, global_ptr<T>) does not match spec
From the spec for operator<<(std::ostream, global_ptr<T>)
: (emphasis added)
Inserts an implementation-defined character representation of ptr into the output stream os. > The textual representation of two objects of type global_ptr<T, Kind> is identical if and only if the two global pointers compare equal.
This is currently broken for global_ptr<char>
, as demonstrated by the following program:
#include <upcxx/upcxx.hpp>
#include <iostream>
using namespace std;
using namespace upcxx;
int main() {
upcxx::init();
std::ostringstream oss1, oss2;
global_ptr<int> gpi = new_<int>(42);
global_ptr<char> gpc = new_array<char>(80);
strcpy(gpc.local(), "hello world");
cout << gpi << endl;
cout << gpc << endl;
oss1 << gpc;
strcpy(gpc.local(), "uh, oh.");
oss2 << gpc;
if (!rank_me()) {
if (oss1.str() != oss2.str()) {
cout << "ERROR: '" << oss1.str() << "' != '" << oss2.str() << "'" << endl;
}
}
upcxx::barrier();
gpc = NULL;
cout << gpc << endl;
upcxx::barrier();
if (!rank_me()) cout << "done." << endl;
upcxx::finalize();
return 0;
}
Example output with 2019.3.2 release:
gp: 0, 0x6ffd7fa03c0, dev=-1)
(gp: 1, 0x6ffd7fa03c0, dev=-1)
(gp: 0, hello world, dev=-1)
(gp: 1, hello world, dev=-1)
ERROR: '(gp: 0, hello world, dev=-1)' != '(gp: 0, uh, oh., dev=-1)'
(gp: 0, (gp: 0,
<crash>
The problem is the implementation of operator<<(std::ostream, global_ptr<T>)
is assuming that naively stringifying the T*
rawptr always generates a representation of the pointer value. This works when T=int
, but when T=char
the result is actually dereferencing the pointer and treating it as a C string. This breaks the output contract of the method, but more importantly actually leads to crashes when the char *
rawptr is NULL or remote.
The likely fix is to reinterpret cast to a void *
or similar before stringifying rawptr.
Comments (3)
-
reporter -
reporter - changed status to resolved
Fix issue
#223: operator<<(std::ostream, global_ptr<T>) does not match spec→ <<cset 6bdcd733d14b>>
-
reporter Merge pull request #223 into develop
- gptr-oss:
issue
#223: Update ChangeLog and add test Fix issue#223: operator<<(std::ostream, global_ptr<T>) does not match spec
→ <<cset eaba120eafad>>
- gptr-oss:
issue
- Log in to comment
Proposed fix in pull request #223
Resulting test output now looks like: