[interprocess] garbage chars when extending interprocess strings?
I'm having a peculiar problem with interprocess strings. 0. Create the shared string type. typedef boost::interprocess::managed_shared_memory ShmManagerType; typedef char ShmCharType; typedef boost::interprocess::allocator< ShmCharType, ShmManagerType::segment_manager > ShmCharAllocatorType; typedef boost::interprocess::basic_string< ShmCharType, std::char_traits< ShmCharType >, ShmCharAllocatorType > ShmStringType; 1. Initial write succeeds. ShmStringType val; val = "x"; cout << quoteString( x ) << endl; // prints "x" as expected 2. When I overwrite the value with a longer value, the longer value is stored and the length is updated -- but a null character (\0) is inserted at the *old* length. ShmStringType x3( "xxx" ); val = x3; cout << quoteString( val ) << endl; // prints "x\0x" !!! 3. When I write the longer value again, it is stored correctly and there is no \0 in the middle of the string. val = x3; cout << quoteString( val ) << endl; // prints "xxx" as expected 4. The same thing happens if we try a longer value again: ShmStringType x5( "xxxxx" ); val = x5; cout << quoteString( val ) << endl; // prints "xxx\0x" val = x5 cout << quoteString( val ) << endl; // prints "xxxxx" Does this ring bells for anyone? On my embedded platform, I'm using: powerpc e300c3 Linux 2.6.36 eglibc 2.13 boost 1_44_0 g++ 4.5.1 And on my development workstation: intel x86-64 Linux 2.6.35.13-92.fc14 glibc 2.13-1 boost 1.44.0-8.fc14 gcc 4.5.1-4.fc14 Testing this on my development workstation, I see similar issues (although it's not always \0; in this case, I'm getting \xC0 junk characters. Odd!) Test case at: http://foiani.com/cpp/boost/InterProcStringTest.cpp Sample output: http://foiani.com/cpp/boost/ipst-out-ppc32.txt http://foiani.com/cpp/boost/ipst-out-x86_64.txt The output isn't the same: some cases work on one platform but not the other, and the garbage character introduced isn't always \0. Any ideas would be welcome. Testing with a more current boost is a bit problematic; if someone believes that it's been fixed in the mean time, I'll do my best to try with a modern boost. In the mean time, I'll just write the values twice, I guess. :) Thanks for your time and attention! Best regards, Tony
On 7/31/2011 1:39 AM, Anthony Foiani wrote:
typedef boost::interprocess::basic_string< ShmCharType, std::char_traits< ShmCharType>, ShmCharAllocatorType > ShmStringType;
A string allocator will affect the storage of the stored characters, but doesn't affect the structure that is the body of the basic_string instance itself. Perhaps the actual string instance is not being shared? The other process has its own version and doesn't see the change to length.
"John M. Dlugosz"
On 7/31/2011 1:39 AM, Anthony Foiani wrote:
typedef boost::interprocess::basic_string< ShmCharType, std::char_traits< ShmCharType>, ShmCharAllocatorType > ShmStringType;
A string allocator will affect the storage of the stored characters, but doesn't affect the structure that is the body of the basic_string instance itself.
I'm pretty sure that's why I'm using the basic_string template from interprocess in the first place, instead of std::basic_string. But I initially wrote that code a long time ago, and now it seems to be freaking out on me, so.
Perhaps the actual string instance is not being shared? The other process has its own version and doesn't see the change to length.
Hm. In this case, I'm seeing corruption even within a single process, so I don't *think* this is the problem. Either way, thanks for taking a look! I'm sure I'm just doing something extra stupid. Thanks again, Tony p.s. I created an updated version that doesn't rely on Linux's /dev/shm: http://foiani.com/cpp/boost/InterProcStringTest2.cpp
Ion Gaztañaga
El 31/07/2011 8:39, Anthony Foiani escribió:
Your latest test seems to work fine with trunk/release branch Interprocess version in Windows and Linux (GCC 4.5), can you try this version in your platform?
It looks like it's triggered by -O2, which I didn't have in the test case compile string, but I *do* use it when building my project. I hate it when I do stupid things like that... I'm testing with a more current version of Boost now. (Going to a more current Boost would help me in other ways, too. When I started this project, I had to disable GCC's C++0x support because it triggered errors in Boost -- but that was back in version 1.37 or something.) Thanks very much for the testing and suggestions! I'll let you and the list know how things work out. Best regards, Tony
Anthony Foiani
I'm having a peculiar problem with interprocess strings.
Argh. It looks like it's the "-O2" setting, at least for GCC 4.5.1 + boost 1_44_0: $ g++ -o InterProcStringTest InterProcStringTest.cpp -lpthread -lrt $ ./InterProcStringTest **** no errors detected $ g++ -O2 -o InterProcStringTest InterProcStringTest.cpp -lpthread -lrt $ ./InterProcStringTest InterProcStringTest.cpp(217): test i->second == val2 failed in function: 'int test_main(int, char**)' i->second="x\0x", val2="xxx" InterProcStringTest.cpp(228): test i->second == val3 failed in function: 'int test_main(int, char**)' i->second="xxx\0xxxxxxxxxxxx", val3="xxxxxxxxxxxxxxxx" InterProcStringTest.cpp(240): test sv1 == sv3 failed in function: 'int test_main(int, char**)' sv1="y\0y", sv3="yyy" InterProcStringTest.cpp(252): test sv1 == sv5 failed in function: 'int test_main(int, char**)' sv1="yyy\0yy", sv5="yyyyyy" **** 4 errors detected I'm testing with a more recent boost now. Thanks again for all the eyes and suggestions, both here and on freenet #boost! Best regards, Tony
Anthony Foiani
Anthony Foiani
writes: I'm having a peculiar problem with interprocess strings.
Argh. It looks like it's the "-O2" setting, at least for GCC 4.5.1 + boost 1_44_0:
The plot thickens. GCC 4.5.1 (stock) + Boost 1_44_0 (stock) on Fedora 14 x86-64: garbage GCC 4.5.1 (stock) + Boost 1_47_0 (custom) on Fedora 14 x86-64: garbage GCC 4.6.0 (stock) + Boost 1_46_1 (stock) on Fedora 15 x86-64: works GCC 4.5.1 (custom) + Boost 1_44_0 (custom) on [custom] ppc-32: garbage And a few other data points I had handy: GCC 4.4.4 (stock) + Boost 1_39_0 (stock) on Fedora 12 ppc-32: works GCC 4.5.1 (stock) + Boost 1_44_0 (stock) on Fedora 14 x86-32: garbage So it looks like 4.5.1 does not play well with this code, at least not under -O2. Smaller test case available here: http://foiani.com/cpp/boost/InterProcStringTest3.cpp For now, it looks like my workaround is to use the later compiler. Not a huge deal, but if someone happens to be poking in the depths of Boost.Interprocess and sees what's going on, I'd love to hear about it. Thanks again for everyone's time and suggestions. Best Regards, Tony
El 01/08/2011 2:54, Anthony Foiani escribió:
Anthony Foiani
writes: Anthony Foiani
writes: I'm having a peculiar problem with interprocess strings.
Argh. It looks like it's the "-O2" setting, at least for GCC 4.5.1 + boost 1_44_0:
The plot thickens.
Please try SVN trunk code, I think it contains fixes for GCC optimizations. Best, Ion
Ion Gaztañaga
Please try SVN trunk code, I think it contains fixes for GCC optimizations.
Sure enough, it looks like this fixes it. Stock GCC and Boost are 4.5.1 and 1.44.0, respectively: $ rpm -q gcc boost gcc-4.5.1-4.fc14.x86_64 boost-1.44.0-8.fc14.x86_64 Updated versions are GCC 4.6.0 and trunk r73469: $ /usr/local/gcc/bin/g++ --version g++ (GCC) 4.6.0 Copyright (C) 2011 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ ( cd ~/Source/boost/trunk ; svn info ) Path: . URL: http://svn.boost.org/svn/boost/trunk Repository Root: http://svn.boost.org/svn/boost Repository UUID: b8fc166d-592f-0410-95f2-cb63ce0dd405 Revision: 73469 Node Kind: directory Schedule: normal Last Changed Author: artyom Last Changed Rev: 73469 Last Changed Date: 2011-08-01 02:04:27 -0600 (Mon, 01 Aug 2011) Binaries: $ g++ -O2 InterProcStringTest3.cpp -o InterProcStringTest3-gcc_4.5.1-boost_1.44.0-O2 -lpthread -lrt $ g++ -isystem ~/Source/boost/trunk -O2 InterProcStringTest3.cpp -o InterProcStringTest3-gcc_4.5.1-boost_r73469-O2 -lpthread -lrt $ /usr/local/gcc/bin/g++ -O2 InterProcStringTest3.cpp -o InterProcStringTest3-gcc_4.6.0-boost_1.44.0-O2 -lpthread -lrt $ /usr/local/gcc/bin/g++ -isystem ~/Source/boost/trunk -O2 InterProcStringTest3.cpp -o InterProcStringTest3-gcc_4.6.0-boost_r73469-O2 -lpthread -lrt Results: $ for i in InterProcStringTest3-* ; do echo "=== $i ===" ; ./$i ; echo ; done === InterProcStringTest3-gcc_4.5.1-boost_1.44.0-O2 === InterProcStringTest3.cpp(150): test sv1 == sv3 failed in function: 'int test_main(int, char**)' sv1="y\xffffffe2y", sv3="yyy" InterProcStringTest3.cpp(162): test sv1 == sv5 failed in function: 'int test_main(int, char**)' sv1="yyy\xffffffe2yy", sv5="yyyyyy" **** 2 errors detected === InterProcStringTest3-gcc_4.5.1-boost_r73469-O2 === **** no errors detected === InterProcStringTest3-gcc_4.6.0-boost_1.44.0-O2 === InterProcStringTest3.cpp(150): test sv1 == sv3 failed in function: 'int test_main(int, char**)' sv1="y\x03y", sv3="yyy" InterProcStringTest3.cpp(162): test sv1 == sv5 failed in function: 'int test_main(int, char**)' sv1="yyy\x03yy", sv5="yyyyyy" **** 2 errors detected === InterProcStringTest3-gcc_4.6.0-boost_r73469-O2 === **** no errors detected I'm actually somewhat surprised; I thought that 4.6.0 did the right thing even with 1.44.0, but apparently not. Either way, I think that I'm past this particular problem. Thanks yet again for all the suggestions and other input. Best regards, Tony
participants (3)
-
Anthony Foiani
-
Ion Gaztañaga
-
John M. Dlugosz