Valgrind对该类的所有实例变量的读写无效

问题描述 投票:0回答:1

我有一个具有某些实例变量的类。当我运行我的应用程序时,我遇到随机崩溃。考虑到内存损坏,我在 valgrind 下运行了该应用程序,并且能够将问题范围缩小到一类。

该类称为

GRETunnelInterface
,它继承自基类,如下所示:
GRETunnelInterface --> VirtualInterface --> Interface

我分离了重现问题的步骤,并注意到在实例化 GRETunnelInterface 类时,valgrind 显示我在类本身初始化期间尝试读取或写入的所有实例变量的读/写无效。 类定义如下。

我交叉检查的事情: 基类的所有实例变量都在构造函数中初始化。

class GRETunnelInterface : public VirtualInterface {

private:
protected:
public:

uint32_t tunnel_id;
Interface *tunnel_src_intf;
uint32_t tunnel_src_ip;
uint32_t tunnel_dst_ip;
uint32_t lcl_ip;
uint8_t mask;
VirtualPort *virtual_port_intf;

enum GreTunnelConfigEnum
{
    GRE_TUNNEL_TUNNEL_ID_SET = 1,
    GRE_TUNNEL_SRC_INTF_SET = 2,
    GRE_TUNNEL_SRC_ADDR_SET = 4,
    GRE_TUNNEL_DST_ADDR_SET = 8,
    GRE_TUNNEL_OVLAY_IP_SET = 16,
    GRE_TUNNEL_ADMIN_SHUT_SET = 32
};

uint16_t config_flags;
GRETunnelInterface(uint32_t tunnel_id);
virtual ~GRETunnelInterface();
... other methods....
}

Valgrind 错误:

==906104== Invalid write of size 2
==906104==    at 0x144F68: GRETunnelInterface::GRETunnelInterface(unsigned int) (Interface.cpp:961)
==906104==    by 0x129007: gre_tunnel_create(node_*, unsigned short) (gre.cpp:39)
==906104==    by 0x1287F7: gre_tunnel_config_handler(int, stack*, op_mode) (grecli.cpp:56)

==906104== Invalid read of size 2
==906104==    at 0x144F70: GRETunnelInterface::GRETunnelInterface(unsigned int) (Interface.cpp:962)
==906104==    by 0x129007: gre_tunnel_create(node_*, unsigned short) (gre.cpp:39)
==906104==    by 0x1287F7: gre_tunnel_config_handler(int, stack*, op_mode) (grecli.cpp:56)

==906104== Invalid write of size 2
==906104==    at 0x144F80: GRETunnelInterface::GRETunnelInterface(unsigned int) (Interface.cpp:962)
==906104==    by 0x129007: gre_tunnel_create(node_*, unsigned short) (gre.cpp:39)

. . . . 

您可以看到所有 valgrind 错误最终都出现在类的构造函数中。

粘贴类的构造函数初始化代码。看起来很简单,为什么会导致无效的读/写呢?

GRETunnelInterface::GRETunnelInterface(uint32_t tunnel_id)

: VirtualInterface(std::string("tunnel") + std::to_string(tunnel_id), INTF_TYPE_GRE_TUNNEL)
{

this->tunnel_id = tunnel_id;
this->config_flags = 0;
this->config_flags |= GRE_TUNNEL_TUNNEL_ID_SET;
this->tunnel_src_intf = NULL;
this->tunnel_src_ip = 0;
this->tunnel_dst_ip = 0;
this->lcl_ip = 0;
this->mask = 0;
this->virtual_port_intf = NULL;

}


VirtualInterface::VirtualInterface(std::string ifname, InterfaceType_t iftype)
: Interface(ifname, iftype)
{
}


Interface::Interface(std::string if_name, InterfaceType_t iftype)
{

this->if_name = if_name;
this->iftype = iftype;
this->config_ref_count = 0;
this->dynamic_ref_count = 0;
this->att_node = NULL;
memset(&this->log_info, 0, sizeof(this->log_info));
this->link = NULL;
this->is_up = true;
this->ifindex = get_new_ifindex();
this->cost = INTF_METRIC_DEFAULT;

this->pkt_recv = 0;
this->pkt_sent = 0;
this->xmit_pkt_dropped = 0;
this->recvd_pkt_dropped = 0;

this->l2_egress_acc_lst = NULL;
this->l2_ingress_acc_lst = NULL;

this->l3_ingress_acc_lst2 = NULL;
this->l3_egress_acc_lst2 = NULL;

this->isis_intf_info = NULL;
}

请帮忙,这些 valgrind 错误的可能原因是什么。每次我对应用程序执行涉及读/写 GRETunnelInterface 类的实例变量的操作时,都会显示更多无效的读/写错误,随后会导致随机应用程序崩溃。

我希望 C++ 类可以嵌入 C 结构,但反之亦然。 请运行,当我运行应用程序时,除非我实例化

GRETunnelInterface
类,否则不会看到 valgrind 错误。所以,我相信问题不在项目的其他地方。

asagar@lima-default:~/tcpip_stack$ g++ --version
g++ (Ubuntu 13.2.0-23ubuntu4) 13.2.0
c++ heap-memory valgrind heap-corruption
1个回答
0
投票

您需要使用更多信息编辑您的帖子才能获得正确的答案。向我们展示分配对象的代码。特别向我们展示您使用

--track-origins=yes
时遇到的错误。

只有少数事情可能会出错。

  1. 事实并非如此。您可以使用放置新的内存块,该内存块小于类的大小。
  2. 您可能违反“单一定义规则”(ODR)。这意味着您的类有多个定义。如果您有一个包含构造函数和类的完整定义的源文件,那么还有第二个包含
    new
    表达式和第二个较小的类定义的源文件。我觉得这个可能性最大。
  3. 您遇到线程问题,并且第一个线程的
    operator new
    和构造函数之间的第二个线程上的内存被删除。不太可能。
© www.soinside.com 2019 - 2024. All rights reserved.