我有一个具有某些实例变量的类。当我运行我的应用程序时,我遇到随机崩溃。考虑到内存损坏,我在 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
您需要使用更多信息编辑您的帖子才能获得正确的答案。向我们展示分配对象的代码。特别向我们展示您使用
--track-origins=yes
时遇到的错误。
只有少数事情可能会出错。
new
表达式和第二个较小的类定义的源文件。我觉得这个可能性最大。operator new
和构造函数之间的第二个线程上的内存被删除。不太可能。