Re: [Boost-users] boost filesystem
I'm running on WinXP with VS7.1 and Boost v1.33.1. I compiled and tried
it and was able to reproduce the error. Whenever you open a file, you
should always do a check on file.fail() to make sure it opened
successfully. You didn't, so you didn't realize the error happened
earlier. Boost correctly threw an exception when you tried to check the
size of the file.
#include
Replies are at the end of this message: Aubrey, Jason wrote:
Hi,
When I run the following program it runs successfully but throws an exception during shutdown. I don't know why, but it seems that the call to boost::filesystem::file_size() is corrupting memory somehow. This example only shows the call to file_size() but I think I've seen similar trouble with other calls within boost::filesystem.
Am I doing something wrong here or is this a bug?
Regards, Jason Aubrey
----------------------
Environment: OS: Win2k Compiler: VS7.1 Boost: v1.33.1
----------------------
#include
#include <fstream> int main(int, char**) { // Create a file using namespace std; const string fileName("/temp/test.txt"); ofstream file; file.open(fileName.c_str()); const string message("this is a test"); file << message; file.close();
const boost::intmax_t fileSize = boost::filesystem::file_size(fileName);
if( fileSize != message.size() ) throw std::exception("Bad result");
return 0; }
Either I'm missing something, or...
file_size takes a path reference as its calling argument. You're
passing
a string. How does this even compile?
- Rush _______________________________________________
Thanks for the Reply Rush.
If I modify the above code to contain the following I still see the same behavior: const boost::filesystem::path filePath(fileName); const boost::intmax_t fileSize = boost::filesystem::file_size(filePath);
Regards, Jason Aubrey _______________________________________________
Would you be able to print out what the values of message.size() and fileSize are, right before you do that comparison?
Thanks, Lawrence Spector _______________________________________________
Both fileSize and message.size() are 14. The exception thrown is not a result of the if-block, but the result of a check by the runtime when it does its cleanup during program shutdown.
Hi Jason, Well, it's too bad that the Easy Answer wasn't the correct answer. :-) I made a console app using VS2005 and Boost 1.33.1, and used your exact code as my main routine. It just works. I also tried setting things up so that my debug build would link against the release version of the library, because the last person that was having filesystem problems had done that, but it just works in that case too. So I'm afraid that I can't reproduce your problem with my Windows setup. If you run your app under the debugger and break when it gets the error, can you tell what sort of object it's trying to delete by backtracking up the stack? That might give some hint about what's happening. Best regards, Rush _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Thanks for your suggestion Lawrence but I don't think it's related to
the problem.
I added the following after opening the file but it doesn't throw (since
the file is valid):
if( !file.is_open() )
throw std::exception("Unable to open file");
To prove that the file is valid:
1) I verified that the program creates the file
2) main() completes as expected.
The following is in regard to Rush's comment:
The call stack when trouble occurs is as follows:
msvcr71d.dll!operator delete(void * pUserData=0x00343418)
msvcp71d.dll!std::allocator<char>::deallocate(char *
_Ptr=0x00343418, unsigned int __formal=48)
msvcp71d.dll!std::string::_Tidy(bool _Built=true, unsigned int
_Newsize=0)
msvcp71d.dll!std::string::~string()
TestsD.exe!$E2()
msvcr71d.dll!doexit(int code=0, int quick=0, int retcaller=0)
msvcr71d.dll!exit(int code=0)
TestsD.exe!mainCRTStartup()
kernel32.dll!7c816d4f()
ntdll.dll!7c915b4f()
kernel32.dll!7c8399f3()
The offending code within delete() is:
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
Unfortunately, I couldn't make any sense of the data in or near the bad
block.
Regards,
Jason
----------------------
Environment:
OS: Win2k
Compiler: VS7.1
Boost: v1.33.1
----------------------
#include
Aubrey, Jason wrote:
Thanks for your suggestion Lawrence but I don't think it's related to the problem.
I added the following after opening the file but it doesn't throw (since the file is valid): if( !file.is_open() ) throw std::exception("Unable to open file");
To prove that the file is valid: 1) I verified that the program creates the file 2) main() completes as expected.
The following is in regard to Rush's comment:
The call stack when trouble occurs is as follows: msvcr71d.dll!operator delete(void * pUserData=0x00343418) msvcp71d.dll!std::allocator<char>::deallocate(char * _Ptr=0x00343418, unsigned int __formal=48) msvcp71d.dll!std::string::_Tidy(bool _Built=true, unsigned int _Newsize=0) msvcp71d.dll!std::string::~string() TestsD.exe!$E2() msvcr71d.dll!doexit(int code=0, int quick=0, int retcaller=0) msvcr71d.dll!exit(int code=0) TestsD.exe!mainCRTStartup() kernel32.dll!7c816d4f() ntdll.dll!7c915b4f() kernel32.dll!7c8399f3()
The offending code within delete() is: _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
Unfortunately, I couldn't make any sense of the data in or near the bad block.
Regards, Jason
----------------------
Environment: OS: Win2k Compiler: VS7.1 Boost: v1.33.1
----------------------
#include
#include <fstream> // Contrary to simplicity I've enhanced the following to satisfy suggestions int main(int, char**) { // Create a file using namespace std; const string fileName("/temp/test.txt"); ofstream file; file.open(fileName.c_str()); if( !file.is_open() ) throw std::exception("Unable to open file"); const string message("this is a test"); file << message; file.close(); const boost::filesystem::path filePath(fileName); const boost::intmax_t fileSize = boost::filesystem::file_size(filePath);
if( fileSize != message.size() ) throw std::exception("Bad result");
return 0; // This line is reached without trouble }
I'm sorry if this sounds like a stupid question Jason, but sometimes asking stupid questions helps. If you change the line that calls file_size to: const boost::intmax_t fileSize = static_castboost::intmax_t(message.size()); then the program runs and exits cleanly? What happens if you change the fileSize check line to this: size_t fileSize = (size_t)(boost::filesystem::file_size(filePath)); (Granted, this is a shot in the dark, but I can only think that this is some sort of mixup in a typedef that messes up the stack frame. I looked at the source for file_size() and it doesn't look like it could cause any sort of corruption problem.) You could also print out the addresses of all the strings, including the one contained within the path, to try and find out which one is being destroyed when the error occurs. I expect that the one contained in the path is on the heap, while fileName and message are on the stack. Oh, BTW, my OS is also Win XP, not 2K. - Rush
participants (3)
-
Aubrey, Jason
-
Lawrence Spector
-
Rush Manbert