std::string destructor crashing in Release when using ::toStdString methods
-
Hi @DRoscoe,
- Did you run your RELEASE program inside the IDE, or by double-clicking the executable?
- Could you post the contents of your PATH?
QString temp("blah"); string temp_str = temp.toStdString(); std::cout << temp_str << std::endl; std::cout << "blah2" << std::endl; string temp_str2 = temp_str; temp_str2.append("a"); std::cout << temp_str2 << std::endl;
The output:
£♫ â─♦â° un §$
blah2
£♫ â─♦â° un §$aThere's something very wrong indeed. What happens when you:
- Print through qDebug() instead of std::cout?
- Print the QString itself?
- Do an indirect conversion that bypasses QString::toStdString()?
QString temp; QByteArray arr = temp.toUtf8(); std::string temp_str(arr.data()); qDebug() << temp; qDebug() << arr; qDebug() << temp_str.c_str();
At this point, I'll try anything!
One other thing I can think of is to install the MinGW version of Qt and use that to build you project. The binaries are very different, and might free you from the strange string issue.
-
I modified the code as suggested:
{ QString temp("blah"); qDebug() << "QString: " << temp; string temp_str = temp.toStdString(); qDebug() << "TEMP_STR: " << temp_str.c_str(); qDebug() << "blah2"; string temp_str2 = temp_str; temp_str2.append("a"); qDebug() << temp_str2.c_str(); }
In this case, the copy from
temp_str
totemp_str2
caused the crash. The output from what did execute:QString: "blah" TEMP_STR: blah2
In both tests, I ran from the IDE, since the behavior is easily reproducible. However, I also ran it from the command line with the same results. Here is the contents of my PATH variable:
C:\Users\roscoe.NASALAB>echo %PATH% C:\Python27\;C:\Python27\Scripts;C:\Perl64\site\bin;C:\Perl64\bin;C:\Program Fil es (x86)\IBM\RationalSDLC\common;C:\Program Files (x86)\Intel\iCLS Client\;C:\Pr ogram Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System3 2\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Intel\Intel( R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Manage ment Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Com ponents\IPT;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\I PT;c:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\ Microsoft SQL Server\100\Tools\Binn\;c:\Program Files\Microsoft SQL Server\100\D TS\Binn\;C:\Program Files (x86)\IBM\RationalSDLC\ClearCase\bin;C:\Program Files\ SourceGear\Common\DiffMerge\;C:\Program Files\Microsoft Windows Performance Tool kit\;C:\Program Files (x86)\Common Files\Plantronics\;C:\Program Files (x86)\Pla ntronics\MyHeadsetUpdater\;C:\Program Files (x86)\Plantronics\VoyagerEdge\;C:\Pr ogram Files\IBM\RationalPurifyPlus;C:\Ruby21\bin;%APPDATA%\Python\Scripts
Using an indirect conversion as you suggest would not be convenient, thus I've avoided it, but may be my only option. I implemented the following:
{ QString temp("blah"); QByteArray arr = temp.toUtf8(); std::string temp_str(arr.data()); qDebug() << temp; qDebug() << arr; qDebug() << temp_str.c_str(); }
The program did not crash and the output:
"blah" "blah" blah
I could try the minGW version, but I have concerns. Our Visual Studio projects are generated using CMake. The CMake scripts generate our project files for Windows, Linux/Unix and MacOS. I am fairly certain it can handle an output compatible with MinGW, but may introduce difficulties if changes need to be made, as the ripples could cause us to rework the scripts to maintain the ability to generate project files for the other platforms. Again, I may have no other option, so I won't discount it.
Another thing I have not considered, we use the Adaptive Communications Environment (ACE) which is a public-domain, platform-independent middleware that abstracts our threading, networking and many other tasks. This requires that our executables have ACE_main as its entry point. Since its only an entry point to the main execution thread, I doubt it's implicated, but I do plan on trying a sample app without it to remove this variable to be certain. Nothing is making sense, so it's worth a shot. Without a fix for this problem our project is dead in the water with a deadline looming.
-
@DRoscoe said:
In this case, the copy from
temp_str
totemp_str2
caused the crash. The output from what did execute:QString: "blah" TEMP_STR: blah2
There's no doubt then that the std::string is being constructed with invalid data (possibly with an invalid char* pointer).
Here is the contents of my PATH variable:
I was looking for common crash culprits in Qt-based projects, but didn't find any in your PATH. I don't recognize a number of the tools you're using though.
Using an indirect conversion as you suggest would not be convenient, thus I've avoided it, but may be my only option.
...
The program did not crash and the output:"blah" "blah" blah
Ok, we now have one workaround, at least.
The implementation of QString::toStdString() is pretty straightforward:
- http://code.woboq.org/qt5/qtbase/src/corelib/tools/qstring.h.html#_ZNK7QString11toStdStringEv
- http://code.woboq.org/qt5/qtbase/src/corelib/tools/qbytearray.h.html#_ZNK10QByteArray11toStdStringEv
Maybe try
temp.toUtf8().toStdString()
and see if that avoids the crash. If so, perhaps you can do a find-and-replace.I could try the minGW version, but I have concerns.
Agreed; that is a drastic change. I would use the multi-step conversion, personally.
Another thing I have not considered, we use the Adaptive Communications Environment (ACE).... I do plan on trying a sample app without it to remove this variable to be certain.
Yes, do test it.
-
I tested the shorthand conversion you suggested with the same result. I have also confirmed that the ACE_main entry is not causing a problem. What I have done is implement a static function to do the conversion you gave me, that I've already confirmed works. I hate not having a proper solution for this, but at least I can move forward.
I'm not going to mark this one as solved, as it technically is not. I am planning on trying this on MSVC 2013 to see if it makes a difference.
Thanks!
-
You're welcome :)
I tested the shorthand conversion you suggested with the same result. I have also confirmed that the ACE_main entry is not causing a problem.
Very very strange. It appears that an
QByteArray::toStdString()
doesn't work on rvalues in your system. I've never seen this before.(For academic curiosity, I'm tempted to try
qDebug() << QByteArray("blah").toStdString();
)I am planning on trying this on MSVC 2013 to see if it makes a difference.
If you have time and a fresh PC, try the same compiler version and Qt version on the fresh PC. I'm curious to know if the corruption is due to your environment, or a long-standing and undetected bug.
But, I know you have a deadline to meet; these experiments aren't crucial. (I did try
string temp_str = temp.toStdString(); qDebug() << "TEMP_STR: " << temp_str.c_str();
on my machine (MSVC 2013 32-bit, Qt 5.4.1) but it was fine in both Debug and Release mode.)Anyway, all the best!
-
" (For academic curiosity, I'm tempted to try
qDebug() << QByteArray("blah").toStdString();
)"I tried this with the same result. I had to add
.c_str()
as QDebug does not supportstd::string
"If you have time and a fresh PC, try the same compiler version and Qt version on the fresh PC. I'm curious to know if the corruption is due to your environment, or a long-standing and undetected bug."
I probably won't have time to try this fully, but I do know other developers in our group are experiencing the same problem
UPDATE: I created an empty MSVC2010 console application project that does nothing but bring in QT5Core and a few other Qt support libraries and tried it from there. Same behavior. It's something very basic and fundamental. I'd say it was a Qt bug, but that wouldn't explain why more people aren't having the same problem. With the simpler project, its even crashing in DEBUG
-
UPDATE2:
I have found two more workarounds for this problem:
QString temp("blah"); std::string temp_str(std::string(temp.toLatin1().data()));
and
QString temp("blah"); std::string temp_str = temp.toLatin1();
Both of these result in valid strings which do not crash. I have now tried my original problem on several different systems at two different facilities with the same result. Either there is something lacking in the documentation for the MSVC10 build of Qt or its an outright bug. Why more people haven't reported this still baffles me.
I am going to label this as SOLVED, though its a bit of a stretch. Thanks to all for your help!
-
@DRoscoe said:
Why more people haven't reported this still baffles me
Personally, I haven't reported it because it has always worked perfectly, in Qt4, all Qt5 versions and with all MSVC versions I've used. I suspect it's the same for most people.
It is also tested in the Qt5 test suite, so I doubt Qt would be released with this failing.
Sorry, there is something with your configuration that you haven't told us (unintentionally, for sure) and we haven't guess.
Out of curiosity, what version of Qt and Windows ? (you left that out, we only know it's Qt5). And what configure command do you use to compile it.
-
Thanks for posting your updates, @DRoscoe.
Either there is something lacking in the documentation for the MSVC10 build of Qt or its an outright bug. Why more people haven't reported this still baffles me.
It definitely doesn't belong in the documentation, as the crash should not happen. Like @sandy.martel23, I believe it hasn't been reported much because very few people are affected by it -- I tried to reproduce it on my system but couldn't (not that I have MSVC 2010 anymore).
Anyway, I'm glad you can get on with your project.
-
@JKSH It can't just be a local problem either. Several other developers at my location are having the same problem. I created a very simple Win32 console app that reproduces the problem, eliminating all of the third-party libraries we use. I sent the project to another group down in Virginia and all who tried it had the same problem (our group is standardized on MSVC 2010, but we are moving to 2015 when available). What I failed to realized was that the basic console app also crashed in DEBUG, whereas our main project crashes only in RELEASE. I now believe that its a problem with MSVC 2010 only, as my MSVC 2013 project doesn't have the problem. I think the problem occurred when Qt went to UTF8 which would explain why toLatin1() and toLocal8Bit() work.
-
LAST UPDATE
The problem is solved! Prior to installing Qt 5.4, I had been running Qt 4.8.6. This was installed with a binary installer package (not web installer). When I installed Qt 5.4, I used the web installer. It ended up installing several earlier versions of Qt as well. There were also some VC redistributables in the Qt folder. I gutted the whole thing and re-installed only Qt 5.4 clean. I installed no other versions. I rebuilt my project and ran the test again, and voila! The problem disappeared.
The one thing in common in my case, our other internal developers and the group in Virginia is that we all started fro Qt 4.8.6 using the same installer package and upgraded via web-installer.
-
A configuration issue ? I can't say that I'm shocked...
I have several Qt versions installed on Windows, version 4, version 5, for 64 & 32 bits and for different VS (2010 and 2013). I would suspect those VC redistributables, if they were ot in sync with the compiler used.
On the other hand, I only use Qts that I compile myself, so I keep a close control on access paths and get a "clean" dev install for each, no upgrades, maybe the (web) installer is mixing up versions.
Glad you found it.
-
@sandy.martel23 When you build your Qt sources for VS2010 can you tell me how you do it? When I did it, I ended up having the same problem. Do you specify any special compiler settings?
-
OK, this time, I have nailed down the specific line in our projects that are causing the problem:
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D \"_ITERATOR_DEBUG_LEVEL=1\"")
Turning on STL iterator debugging is not compatible with Qt libraries. I suspect that turning this feature on when compiling Qt would solve the problem, but for now it's easier to turn it off in my own projects. It is only marginally useful.
-
9 days ago, @sandy.martel23 said:
But it seems that your still mixing debug and release STL objects
told you :-)
As for building Qt, I do nothing special.
-
I was recently working with Qt, overridden new/delete operator, and got the similar issue.
It caused a problem that QByteArray::toStdString() made a std::string which avoided calling the overridden version of new.
However, when the std::string was destructed in my program, it called the overridden version of delete. Bomb!
Maybe it is a reasonable practice to avoid using std::string returned by Qt or other 3rd party library. Or you should rebuild all of them with the exactly same environment.
-
@Hudson said:
Maybe it is a reasonable practice to avoid using std::string returned by Qt or other 3rd party library.
Actually in your case, forgive me for being so blunt, I'd say it would be a reasonable practice to avoid writing new/delete operators for classes you don't own (i.e. such that are not written by you). And as a side note creating
std::string
s in the heap is a bit questionable.Also I don't see how Qt could have called an overloaded
new
so you can calldelete
on it. There's nonew
inQByteArray::toStdString
,