在c++中使用popen调用cli实用程序时崩溃.适用于shell或fork、exec等
cli utility crashing while invoked using popen in c++. Works fine in shell or fork, exec etc
我面临一个奇怪的问题。我编写了一个命令行实用程序,它调用第三方库api来完成第三方设备的一些管理任务。我已经彻底测试了这个实用程序,它运行良好。我有自己的守护进程(用c++编写),它根据收到的请求,使用popen调用这个命令行实用程序。如果我这样做,该实用程序会在库api中崩溃,给出类似的错误
terminate called after throwing an instance of
'std::logic_error' what(): basic_string::_S_construct null not valid
我的cli实用程序调用方式如下
./cli --host hostname --command cmd --other otheropts etc etc.
它是使用c++字符串从守护进程调用的,守护进程根据收到的请求构建参数。它最终像这样调用我的cli
setenv("LOGIN", login_.c_str(), 1);
setenv("PASSWORD", password_.c_str(), 1);
std::string complete = cli_path_ + " ";
complete += formatString("--host %s --command ", host_);
complete += cmd;
complete += " 2>&1"; // get stderr as well
FILE *f = popen(complete.c_str(), "r");
然后读取生成的文件指针并解析输出。崩溃只发生在从守护进程调用时,而不是从shell调用时。即使我从守护进程调用了一个包装外壳脚本,它仍然会崩溃。我不了解execed进程与其父进程的关系,它可能会导致崩溃。我知道在某个地方,api试图用空指针创建一个字符串,然而,让我困惑的是,当我直接从命令行或我编写的一个简单的c++程序中调用cli时,这不会发生。操作系统是linux。为了调试,我尝试了
- 使用fork和exec而不是popen调用它。(崩溃)
- 调用调用此cli的shell脚本。(崩溃)
- 直接调用,如上所示。(作品)
- 使用c++简单程序作为包装器从shell调用(有效)
- 介入gdb直到第三方api。(从守护进程调用时api崩溃)
我发现了问题所在。第三方库试图访问未定义的环境变量。库代码无法处理此问题并崩溃。所以问题出在第三方图书馆,他们已经同意修复。为了其他人的利益,我通过如上所述的大量调试发现了这一点。最后我对环境产生了怀疑。所以我用这样的"env-I"运行cli,
env -i ./cli --args <args>
其清除环境变量。它坠毁了!。然后,我通过对运行cli时设置的所有环境变量进行二进制搜索,找出了哪个环境变量。
相关文章:
- FLTK 2.0构建和演示,适用于VS2019的2011年左右的代码库
- C++17 - 使用自定义分配器的节点提取/重新插入 - 适用于 clang++/libc++,但不适用于 libstd
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- 适用于 WebView2 旧版本的示例应用程序
- 在 NVIDIA GEFORCE GTX 1050 上下载适用于 Windows 10 的 openCL 1.2
- __attribute__(优化(0))) 是否适用于"recursively"?
- 为什么 std::erase(std::erase_if) 不是适用于<algorithm>任何容器的模板?
- 使用一个参数的模板函数时出错(适用于 2)
- 使用 适用于 Android 和 iOS 的 tf-lite C++ API
- 为什么这适用于 G++ 而不是 CLANG?
- 适用于 macOS 的 Xcode 应用程序。这就是我设置从USB麦克风输入获取音频的方式。一年前工作,现在没有了。为什么
- 适用于 Linux 的 c++ 上的代理脚本
- 为什么我的 SFINAE 表达式不再适用于 GCC 8.2?
- 使输出流式处理运算符适用于 boost::variant<std::vector<int>、int、double 的正确方法是什么>
- 有没有适用于Windows.lib文件的GNU二进制文件描述符(BFD)
- 模板函数仅适用于VS
- 如何在cmake中包含适用于g++或viceversa的库
- 适用于win32、linux、mac的POSIX C包装器
- WinDBG适用于从Visual Studio 2015保存的转储,但不适用于任务管理器。显示异常代码"not found"
- 在c++中使用popen调用cli实用程序时崩溃.适用于shell或fork、exec等