I was getting intermittently weird results with running stat()
(perror(): "Bad address") on a filename that comes from a commandline argument in my project:
// mz.h
class MzImage {
private:
/* ... */
struct Segment {
Dword start, stop, length;
std::string name, type;
Segment(Dword start, Dword stop, Dword length, const std::string &name, const std::string &type) :
start(start), stop(stop), length(length), name(name), type(type) {}
};
std::vector<Segment> segs_;
public:
MzImage(const std::string &path);
// ...
};
// mz.cpp
MzImage::MzImage(const std::string &path) {
cout << "path = " << path << endl;
// ... later, path.c_str() used in stat(), turned out to be NULL
}
// mztool.cpp
int main(int argc, char* argv[]) {
const char* mzfile = argv[1];
cout << "Filename: " << mzfile << endl;
try {
MzImage mz{string(mzfile)};
// ...
}
catch (Error &e) {
cout << "Exception: " << e.what() << endl;
}
return 0;
}
I am noticing the filename argument is fine in main()
but empty in the constructor of MzImage
:
ninja@desktop:~/eaglestrike/mztools$ ./mztool a.exe
Filename: a.exe
path =
Under the debugger, the value of the string seems to disappear when entering the function:
ninja@desktop:~/eaglestrike/mztools$ gdb ./mztool
(gdb) b MzImage::MzImage
Breakpoint 1 at 0x6512: file mz.cpp, line 43.
(gdb) set args a.exe
(gdb) run
Starting program: /mnt/d/code/EagleStrike/mztools/mztool a.exe
Filename: a.exe
Breakpoint 1, MzImage::MzImage (this=0x7ffffffee100, path="a.exe") at mz.cpp:43
43 MzImage::MzImage(const std::string &path) {
(gdb) p path
$1 = "a.exe"
(gdb) n
44 cout << "path = " << path << endl;
(gdb) p path
$2 = ""
Decided to place a watch on the string, it seems to be obliterated by the vector constructor?
Breakpoint 1, MzImage::MzImage (this=0x7ffffffee100, path="a.exe") at mz.cpp:43
43 MzImage::MzImage(const std::string &path) {
(gdb) watch -l path
Watchpoint 3: -location path
(gdb) c
Continuing.
Watchpoint 3: -location path
Old value = "a.exe"
New value = <error reading variable: Cannot create a lazy string with address 0x0, and a non-zero length.>
0x000000000800bc8d in std::_Vector_base<MzImage::Segment, std::allocator<MzImage::Segment> >::_Vector_impl::_Vector_impl (this=0x7ffffffee138) at /usr/include/c++/7/bits/ stl_vector.h:89
89 : _Tp_alloc_type(), _M_start(), _M_finish(), _M_end_of_storage()
(gdb) bt
#0 0x000000000800bc8d in std::_Vector_base<MzImage::Segment, std::allocator<MzImage::Segment> >::_Vector_impl::_Vector_impl (this=0x7ffffffee138) at /usr/include/c++/7/bits/ stl_vector.h:89
#1 0x000000000800aba8 in std::_Vector_base<MzImage::Segment, std::allocator<MzImage::Segment> >::_Vector_base (this=0x7ffffffee138) at /usr/include/c++/7/bits/stl_vector.h:127
#2 0x000000000800a228 in std::vector<MzImage::Segment, std::allocator<MzImage::Segment> >::vector (this=0x7ffffffee138) at /usr/include/c++/7/bits/stl_vector.h:263
#3 0x0000000008006547 in MzImage::MzImage (this=0x7ffffffee100, path=<error reading variable: Cannot create a lazy string with address 0x0, and a non-zero length.>) at mz.cpp:43
#4 0x0000000008005d19 in main (argc=2, argv=0x7ffffffee268) at mztool.cpp:22
Any idea on what might be happenning? This is g++ 7.5.0 on Ubuntu 18.04 running under WSL.