我面临一个奇怪的问题。我编写了一个命令行实用程序,它调用第三方库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调用。即使我从守护进程调用包装器shell脚本,它仍然会崩溃。我不理解被执行的进程与其父进程的关系,它可能导致崩溃。我知道api正试图用空指针创建一个字符串,但是,令我感到困惑的是,当我直接从命令行或我编写的一个简单的c ++程序调用cli时,它不会发生。操作系统是linux。 要调试,我试过
答案 0 :(得分:0)
我弄清楚问题是什么。第三方库试图访问未定义的环境变量。库代码没有处理这个并且崩溃了。问题出在第三方图书馆,他们同意修复。 为了他人的利益,我通过上面提到的大量调试发现了这一点。最后我对环境持怀疑态度。所以我用这样的“env -i”来运行cli,
<?php
$num = $con->query("SELECT gcm_regid from gcm_users")->rowCount();
$current_num = 0;
$message = $_POST["message"];
for ($i = 0; $i < $num / 999; $i++) {
$query = $con->query("SELECT gcm_regid from gcm_users LIMIT $current_num, 999");
foreach ($query as $data) {
$row[] = $data["gcm_regid"];
}
$pushStatus = send_notification($con, $row, $message);
$current_num += 999;
}
?>
清除环境变量。它崩溃了!然后我通过对运行cli时设置的所有环境变量进行二进制搜索来找出哪个环境变量。