boost::program_options 在 Klocwork 中生成 MLK.MUST
boost::program_options generating MLK.MUST in Klocwork
我基于 Boost 库编写了以下 C++ 代码以从命令行获取输入。
#include <iostream>
#include <boost/program_options.hpp>
#include <boost/format.hpp>
using namespace std;
namespace po = boost::program_options;
int main(int argc, char** argv) {
int party = 2, port = 9999;
string server_ip;
po::options_description desc{"Allowed options"};
desc.add_options() //
("help,h", "produce help message") //
("party,k", po::value<int>(&party)->default_value(1), "party id: 1 for server, 2 for client") //
("port,p", po::value<int>(&port)->default_value(1234), "socket port") //
("server_ip,s", po::value<string>(&server_ip)->default_value("localhost"), "server's IP.");
po::variables_map vm;
try {
po::parsed_options parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run();
po::store(parsed, vm);
if (vm.count("help")) {
cout << desc << endl;
return 0;
}
po::notify(vm);
}catch (po::error& e) {
cout << "ERROR: " << e.what() << endl << endl;
cout << desc << endl;
return -1;
}
cout << party << endl;
cout << port << endl;
cout << server_ip << endl;
}
它按预期工作。但是,Klocwork 报了如下错误(我已经调整了这段代码的行号):
main.cpp:16 MLK.MUST (2:Error) Analyze
Memory leak. Dynamic memory stored in 'po::value<int> ( &party)' allocated through function 'value<int>' at line 14 is lost at line 16
* main.cpp:14: Dynamic memory stored in 'po::value<int> ( &party)' is allocated by calling function 'value<int>'.
* value_semantic.hpp:198: 'r' is allocated by function 'new'.
* main.cpp:16: Dynamic memory stored in 'po::value<int> ( &party)' is lost.
Current status 'Analyze'
我找到了这个旧的 post boost program_options generating a Klocwork MLK.MUST。但是看了答案,还是不知道怎么解决这个问题。
Klocwork 报告的另一个问题是 'port' is used uninitialized in this function
。它特别提到 passing '&port' to 'po::value<int>' does not initialize 'port'
。但是,在 运行 代码之后,我看到它确实初始化了端口,因为端口值打印为 1234 而不是 9999。
有没有办法编写可以解决上述问题的代码?
Another issue reported by Klocwork is 'port' is used uninitialized in this function. It specifically mentions that passing '&port' to 'po::value'
这是误报:port
在初始化之前没有使用它的值(我检查过)。但是,实际初始化 port
以使消息静音应该就足够了。奇怪的是它仍然会触发,因为你已经拥有了。
vaglrind 和 ASAN+UBSAN 都没有发现我的代码有任何问题。这是一个尝试各种选项组合(包括未注册和错误的)的蛮力测试:
#!/bin/bash
set -e -u
opts=( '' '-k two' '-k 2' '-p 2345' '-s 127.0.0.88' 'bogus' '--more-bogus');
for a in "${opts[@]}"
do
for b in "${opts[@]}"
do
for c in "${opts[@]}"
do
valgrind ./sotest "$a" "$b" "$c"
done
done
done
最终 运行 程序的 343 次不同调用最终打印出预期的输出:
69x 2
69x 2345
69x 127.0.0.88
99x 1
99x 1234
99x localhost
预期的诊断:
17x option '--port' cannot be specified more than once
17x option '--server_ip' cannot be specified more than once
34x option '--party' cannot be specified more than once
107x the argument ('two') for option '--party' is invalid
最重要的是,一致的 leak-free 报告:
343 All heap blocks were freed -- no leaks are possible
TL;DR
我不知道为什么您的工具报告泄漏。至少,"'port' used uninitialized" 问题在仔细检查时似乎是错误的。
我使用 Boost 1.73.0 在 GCC 10 上进行了测试,-std=c++17 -O3,您的源代码 1--% 未更改。
我希望这能给你更多的想法,或许还能给你一些安慰。
我基于 Boost 库编写了以下 C++ 代码以从命令行获取输入。
#include <iostream>
#include <boost/program_options.hpp>
#include <boost/format.hpp>
using namespace std;
namespace po = boost::program_options;
int main(int argc, char** argv) {
int party = 2, port = 9999;
string server_ip;
po::options_description desc{"Allowed options"};
desc.add_options() //
("help,h", "produce help message") //
("party,k", po::value<int>(&party)->default_value(1), "party id: 1 for server, 2 for client") //
("port,p", po::value<int>(&port)->default_value(1234), "socket port") //
("server_ip,s", po::value<string>(&server_ip)->default_value("localhost"), "server's IP.");
po::variables_map vm;
try {
po::parsed_options parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run();
po::store(parsed, vm);
if (vm.count("help")) {
cout << desc << endl;
return 0;
}
po::notify(vm);
}catch (po::error& e) {
cout << "ERROR: " << e.what() << endl << endl;
cout << desc << endl;
return -1;
}
cout << party << endl;
cout << port << endl;
cout << server_ip << endl;
}
它按预期工作。但是,Klocwork 报了如下错误(我已经调整了这段代码的行号):
main.cpp:16 MLK.MUST (2:Error) Analyze
Memory leak. Dynamic memory stored in 'po::value<int> ( &party)' allocated through function 'value<int>' at line 14 is lost at line 16
* main.cpp:14: Dynamic memory stored in 'po::value<int> ( &party)' is allocated by calling function 'value<int>'.
* value_semantic.hpp:198: 'r' is allocated by function 'new'.
* main.cpp:16: Dynamic memory stored in 'po::value<int> ( &party)' is lost.
Current status 'Analyze'
我找到了这个旧的 post boost program_options generating a Klocwork MLK.MUST。但是看了答案,还是不知道怎么解决这个问题。
Klocwork 报告的另一个问题是 'port' is used uninitialized in this function
。它特别提到 passing '&port' to 'po::value<int>' does not initialize 'port'
。但是,在 运行 代码之后,我看到它确实初始化了端口,因为端口值打印为 1234 而不是 9999。
有没有办法编写可以解决上述问题的代码?
Another issue reported by Klocwork is 'port' is used uninitialized in this function. It specifically mentions that passing '&port' to 'po::value'
这是误报:port
在初始化之前没有使用它的值(我检查过)。但是,实际初始化 port
以使消息静音应该就足够了。奇怪的是它仍然会触发,因为你已经拥有了。
vaglrind 和 ASAN+UBSAN 都没有发现我的代码有任何问题。这是一个尝试各种选项组合(包括未注册和错误的)的蛮力测试:
#!/bin/bash
set -e -u
opts=( '' '-k two' '-k 2' '-p 2345' '-s 127.0.0.88' 'bogus' '--more-bogus');
for a in "${opts[@]}"
do
for b in "${opts[@]}"
do
for c in "${opts[@]}"
do
valgrind ./sotest "$a" "$b" "$c"
done
done
done
最终 运行 程序的 343 次不同调用最终打印出预期的输出:
69x 2
69x 2345
69x 127.0.0.88
99x 1
99x 1234
99x localhost
预期的诊断:
17x option '--port' cannot be specified more than once
17x option '--server_ip' cannot be specified more than once
34x option '--party' cannot be specified more than once
107x the argument ('two') for option '--party' is invalid
最重要的是,一致的 leak-free 报告:
343 All heap blocks were freed -- no leaks are possible
TL;DR
我不知道为什么您的工具报告泄漏。至少,"'port' used uninitialized" 问题在仔细检查时似乎是错误的。
我使用 Boost 1.73.0 在 GCC 10 上进行了测试,-std=c++17 -O3,您的源代码 1--% 未更改。
我希望这能给你更多的想法,或许还能给你一些安慰。