Meta plugin Linux: All operator<< acting on a stream fail when writing a number
AnsweredHi.
There's something wrong with a meta plugin built in Linux ubuntu 18, and any attempts to write numbers to a stream. I've called functions within the plugin, and the write works fine; it's broken when loaded into the nxwitness server.
I did the following:
Using the sample analytics code from the metadata SDK, the makefile is updated to link to -static-libstdc++, or the plugin won't load.
The device_agent.cpp file has the following line added to the generateObjectMetadataPacket() function:
objectMetadata->addAttribute(nx::sdk::makePtr<Attribute>(IAttribute::Type::string, "trackid", UuidHelper::toStdString(m_trackId)));
The project is built using build_samples.sh script, the output .so is copied to the plugins folder, and the service is restarted.
The following image shows that the track string is not created, and is just "{". All operator<< acting on a stream (e.g. ofstream, ostringstream, etc.) fail when writing a number. This includes the UuidHelper::toStdString() function provided in the meta SDK.
Is this a known issue? Is there a known fix?
Thanks!
-
Hi Andrey,
Thanks for the reply. Sorry, I should have included those details before. And it's ubuntu 20, not 18.
The changes to the device_agent.cpp (line 151), and the CMakeLists.txt can be seen here: https://imgur.com/a/SLDLJic and the whole files are available as text here: https://file-store.surge.sh/linuxcode.zip
OS: Ubuntu 20.04.4 LTS 64-bit running in VirtualBox
NxWitness server: nxwitness-server-4.2.0.32840-linux64.deb
NxWitness client: windows 4.2.0.32840
Cmake version 3.16.3
G++:
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.4.0-1ubuntu1~20.04.1' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-Av3uEd/gcc-9-9.4.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1) -
I'd like to reiterate that loading the library using dlopen/dlsym and calling a test function gives the expected behaviour (i.e. can write number to stream), whereas when loaded by nx mediaserver will give the truncated result.
Code change to test this can be seen here: https://imgur.com/a/yMCpFtF
Output when calling the runtests() directly (using dlopen/dlsym) vs via nx mediaserver which calls runtests() from createNxPlugin() is:
user@user-VirtualBox:~/metavms-metadata_sdk-4.2.0.32836-universal/metadata_sdk$ cat /tmp/crud
cat: /tmp/crud: No such file or directory
user@user-VirtualBox:~/metavms-metadata_sdk-4.2.0.32836-universal/metadata_sdk$ sudo sudo systemctl restart networkoptix-mediaserver.service
user@user-VirtualBox:~/metavms-metadata_sdk-4.2.0.32836-universal/metadata_sdk$ cat /tmp/crud
runTests() enter
uuid test out: {
runTests() exit
user@user-VirtualBox:~/metavms-metadata_sdk-4.2.0.32836-universal/metadata_sdk$ sudo chown user /tmp/crud
user@user-VirtualBox:~/metavms-metadata_sdk-4.2.0.32836-universal/metadata_sdk$ ./runTests.sh
rm: cannot remove './__runTests.out': No such file or directory
runTests() enter
uuid test out: {4B75A74C-5D3A-4E95-BF39-0DA05520EDE1}
runTests() exit
user@user-VirtualBox:~/metavms-metadata_sdk-4.2.0.32836-universal/metadata_sdk$ cat /tmp/crud
runTests() enter
uuid test out: {
runTests() exit
runTests() enter
uuid test out: {4B75A74C-5D3A-4E95-BF39-0DA05520EDE1}
runTests() exit
user@user-VirtualBox:~/metavms-metadata_sdk-4.2.0.32836-universal/metadata_sdk$ -
Hi Andrey,
Thanks for taking the time to test this. Unfortunately the issue will not show up if only the .cpp file is copied; the CMakeLists.txt file also needs modifying.
Without statically linking libstdc++, the result is as you have shown in your image. With static linking, as per my post, the trackid attribute is shown as: "trackid: {".
I just tried with a fresh install of ubuntu 20, gcc/g++ 10, nx witness 5 server, and the result is as I described.
Regards
-
Hello David,
Sorry for the late response.
I've taken version 5.0.0.35270 (release) and corresponding Metadata SDK.
Have modified the CMakeLists.txt of the sample analytics plugin like this:
add_library(sample_analytics_plugin SHARED ${SAMPLE_ANALYTICS_PLUGIN_SRC})
target_include_directories(sample_analytics_plugin PRIVATE ${SAMPLE_ANALYTICS_PLUGIN_SRC_DIR})
set(CMAKE_LINK_LIBRARY_FLAG " --static")
target_link_libraries(sample_analytics_plugin PRIVATE
nx_kit
nx_sdk
-static-libgcc
-static-libstdc++)as well as device_agent.cpp, i.e. put this line to the DeviceAgent::generateObjectMetadataPacket()
objectMetadata->addAttribute(nx::sdk::makePtr<Attribute>(IAttribute::Type::string, "trackid", UuidHelper::toStdString(m_trackId)));
It works. See the result on the screenshot attached.
-
Hi Andrey,
Thanks for the response. I just tested by copy/pasting the CMakelists.txt excerpt you provided, but unfortunately it breaks the display of the uuid, as before. Removing the static linkage allows the track ID to be displayed.
I wonder what the differences are between our linux environments to make this happen.
Regards,
-
Hi,
I just tried with a fresh install of ubuntu 20, gcc/g++ 10, nx witness 5 server, and the result is as I described.
Here is the environment I'm testing in
Linux atp 5.15.0-46-generic #49~20.04.1-Ubuntu SMP Thu Aug 4 19:15:44 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
cmake version 3.20.5
Nx Witness 5.0.0.35270, Metadata SDK 5.0.0.35270
Could you share the code of your project, once again?
-
Hi Andrey,
I just spun up a new ubuntu 20 VM. Details are:
Linux fresh-VirtualBox 5.15.0-46-generic #49~20.04.1-Ubuntu SMP Thu Aug 4 19:15:44 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
cmake version 3.16.3
metavms-metadata_sdk-5.0.0.35269-universal
server: 5.0.0.35270 (linux)
client: 5.0.0.35270 (windows)
Also tried cmake version 3.20.0, with no changeThe code is straight from the zip file, with the following diff:
fresh@fresh-VirtualBox:~/metavms/metadata_sdk$ git diff
diff --git a/samples/sample_analytics_plugin/CMakeLists.txt b/samples/sample_analytics_plugin/CMakeLists.txt
index 1c09838..f66a71a 100755
--- a/samples/sample_analytics_plugin/CMakeLists.txt
+++ b/samples/sample_analytics_plugin/CMakeLists.txt
@@ -67,7 +67,13 @@ file(GLOB_RECURSE SAMPLE_ANALYTICS_PLUGIN_SRC CONFIGURE_DEPENDS
add_library(sample_analytics_plugin SHARED ${SAMPLE_ANALYTICS_PLUGIN_SRC})
target_include_directories(sample_analytics_plugin PRIVATE ${SAMPLE_ANALYTICS_PLUGIN_SRC_DIR})
-target_link_libraries(sample_analytics_plugin PRIVATE nx_kit nx_sdk)
+
+set(CMAKE_LINK_LIBRARY_FLAG " --static")
+target_link_libraries(sample_analytics_plugin PRIVATE
+ nx_kit
+ nx_sdk
+ -static-libgcc
+ -static-libstdc++)
target_compile_definitions(sample_analytics_plugin
PRIVATE NX_PLUGIN_API=${API_EXPORT_MACRO}
diff --git a/samples/sample_analytics_plugin/src/nx/vms_server_plugins/analytics/sample/device_agent.cpp b/samples/sample_analytics_plugin/src/nx/vms_server_plugins/analytics/sample/device_agent.cpp
index f139e28..b8f93e8 100755
--- a/samples/sample_analytics_plugin/src/nx/vms_server_plugins/analytics/sample/device_agent.cpp
+++ b/samples/sample_analytics_plugin/src/nx/vms_server_plugins/analytics/sample/device_agent.cpp
@@ -148,6 +148,7 @@ Ptr<IMetadataPacket> DeviceAgent::generateObjectMetadataPacket()
// Set all required fields.
objectMetadata->setTypeId(kHelloWorldObjectType);
objectMetadata->setTrackId(m_trackId);
+ objectMetadata->addAttribute(nx::sdk::makePtr<Attribute>(IAttribute::Type::string, "trackid", UuidHelper::toStdString(m_trackId)));
// Calculate bounding box coordinates each frame so that it moves from the top left corner
// to the bottom right corner during kTrackFrameCount frames.The built .so files can be seen here: https://file-store.surge.sh/nx-sample-plugin.7z
-
Hello David,
Our devs have investigated the issue and found the root cause. It's about the specifics of how Linux and gcc organizes function exporting in binaries with static linking.
The solution from now further for version 5.0 is to compile the plugin with dynamic linking and with gcc version less than 10.2.
For the third party libraries used by a plugin, they should not depend on the version libstdc++.so.6 or less.
We are going to update the code in all the public examples as well as readme files.
Most probably, for further version of the Server, we'll need to freeze another version of gcc as a reference.
We're aware this is not a consistent solution, and we are going to maintain it this way for a while.
We have an idea how to make life easier in this context, but that requires massive development and hopefully will be implemented in the future.
-
Hi Andrey,
Thanks for looking into this, and for your feedback.
Presumably the requirement of using gcc<10.2 also applies to all dependencies of the plugin, as they may otherwise try to load libstdc++ at a version higher than Nx Witness has available.
Presumably any plugin using ffmpeg libs will also suffer if its version isn't in line with those included with Nx Witness.
If Nx Witness used the system-installed libraries, it might be possible that some of these problems would disappear.
-
Hello,
Presumably the requirement of using gcc<10.2 also applies to all dependencies of the plugin, as they may otherwise try to load libstdc++ at a version higher than Nx Witness has available.
that's correct.
Presumably any plugin using ffmpeg libs will also suffer if its version isn't in line with those included with Nx Witness.
Since the Server is supplied with ffmpeg libs, we encourage using them.
If Nx Witness used the system-installed libraries, it might be possible that some of these problems would disappear.
Our architects and devs considered this option too, and have decided not to do that.
Please sign in to leave a comment.
Comments
14 comments