我正在使用valgrind查找并关闭应用程序中潜在的内存问题,并防止未定义的行为。我的valgrind电话看起来像这样
valgrind --leak-check=full --track-origins=yes -v ./app
我无法修复的部分代码是这个:
int App::initSignalHandler(bool dfl)
{
for(size_t sigidx =0; sigidx < sigcount; sigidx++ )
{
int signal = stopSignals[sigidx];
const char *signalName = stopSignalNames[sigidx]; // change signal handler
struct sigaction new_action;
sigemptyset (&new_action.sa_mask);
if(dfl)
new_action.sa_handler = SIG_DFL;
else
new_action.sa_handler = App::stopSignalHandler;
new_action.sa_flags |= SA_RESTART;
if(sigaction (signal,&new_action,NULL)!=0)
qWarning() << Q_FUNC_INFO << "error setting signal handler for : " << signalName;
}
}
Valgrinds输出:
==22462== Conditional jump or move depends on uninitialised value(s)
==22462== at 0x527427C: __libc_sigaction (sigaction.c:53)
==22462== by 0x117B83: App::initSignalHandler(bool) (app.cpp:127)
==22462== by 0x116DD7: main (main.cpp:21)
==22462== Uninitialised value was created by a stack allocation
==22462== at 0x117B04: App::initSignalHandler(bool) (app.cpp:88)
app.cpp:88指向带有函数initSignalHandler的左括号的行。我看着这个函数的每个调用。我正在[[always传递布尔值,并且该参数还具有默认的false值,因此无法避免这是未定义的行为。
app.cpp:127指向 if(sigaction (signal,&new_action,NULL)!=0)
我认为此错误是由于new_actions结构未完全初始化引起的。我试图纠正的事情:memset(&new_action, 0, sizeof(new_action));
但这不做任何事情在某些地方我也找到了建议
struct sigaction new_action = {0};
,但是这会导致我不希望看到编译器警告-Wmissing-field-initializers
。所以问题是我应该如何正确初始化sigaction结构。我假设此错误app.cpp:88的假定来源也将得到解决?
new_object
初始化为零的正确方法是struct sigaction new_action{};
// ^^ Note the brackets here
注意,由于类struct
和函数sigaction
之间的名称冲突,仅在此处需要sigaction
关键字。
您应该解决的功能还有另一个明显的问题:initSignalHandler
被声明返回一个int
,但是它不返回任何东西。非void
函数的末尾掉落会导致未定义的行为。您的编译器应该使用类似的警告您:
warning: no return statement in function returning non-void [-Wreturn-type]
如果没有,那么您应该确保已启用足够的警告。