Класс называется GRETunnelInterface, который наследуется от базового класса как следует:
Код: Выделить всё
GRETunnelInterface --> VirtualInterface --> Interface
Определение класса приведено ниже.
Вещи, которые я перепроверил:
Все переменные экземпляра базовых классов инициализируются в конструкторы.
Код: Выделить всё
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....
}
Код: Выделить всё
==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)
. . . .
Вставка кода инициализации конструктора класса. Выглядит довольно тривиально, почему это может привести к недопустимым операциям чтения/записи.
Код: Выделить всё
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;
}
Я надеюсь, что классы C++ можно встраивать C-структуры, но наоборот — неверно.
Когда я запускаю приложение, если я не создаю экземпляр класса GRETunnelInterface, никаких ошибок valgrind не наблюдается. Итак, я считаю, что проблема не где-то еще в проекте.
Код: Выделить всё
asagar@lima-default:~/tcpip_stack$ g++ --version
g++ (Ubuntu 13.2.0-23ubuntu4) 13.2.0
Код: Выделить всё
bool
gre_tunnel_create (node_t *node, uint16_t tunnel_id) {
Interface *tunnel;
byte intf_name[IF_NAME_SIZE];
snprintf ((char *)intf_name, IF_NAME_SIZE, "tunnel%d", tunnel_id);
tunnel = node_get_intf_by_name(node, (const char *)intf_name);
if (tunnel) {
return false;
}
int empty_intf_slot = node_get_intf_available_slot(node);
if (empty_intf_slot < 0) {
cprintf ("Error : No NIC slot available in a device\n");
return false;
}
tunnel = new GRETunnelInterface(tunnel_id);
if (!tunnel ) {
cprintf ("Error : GRE Tunnel creation failed\n");
return false;
}
node->intf[empty_intf_slot] = tunnel;
tunnel->att_node = node;
tunnel->InterfaceLockStatic();
return true;
}
Журналы Valgrind:
Код: Выделить всё
==30892== Thread 2:
==30892== Invalid write of size 2
==30892== at 0x143E70: GRETunnelInterface::GRETunnelInterface(unsigned int) (Interface.cpp:961)
==30892== by 0x126FB3: gre_tunnel_create(node_*, unsigned short) (gre.cpp:39)
==30892== by 0x1267A3: gre_tunnel_config_handler(int, stack*, op_mode) (grecli.cpp:56)
==30892== by 0x1135FB: task_cbk_handler_internal(event_dispatcher_*, void*, unsigned int) (cli_interface.c:47)
==30892== by 0x13982F: event_dispatcher_thread(void*) (event_dispatcher.c:219)
==30892== by 0x4D3597B: start_thread (pthread_create.c:447)
==30892== by 0x4D9B7DB: thread_start (clone.S:79)
==30892== Address 0xad6d288 is 12 bytes after a block of size 188 alloc'd
==30892== at 0x48859FC: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==30892== by 0x126F9B: gre_tunnel_create(node_*, unsigned short) (gre.cpp:39)
==30892== by 0x1267A3: gre_tunnel_config_handler(int, stack*, op_mode) (grecli.cpp:56)
==30892== by 0x1135FB: task_cbk_handler_internal(event_dispatcher_*, void*, unsigned int) (cli_interface.c:47)
==30892== by 0x13982F: event_dispatcher_thread(void*) (event_dispatcher.c:219)
==30892== by 0x4D3597B: start_thread (pthread_create.c:447)
==30892== by 0x4D9B7DB: thread_start (clone.S:79)
==30892==
==30892== Invalid read of size 2
==30892== at 0x143E78: GRETunnelInterface::GRETunnelInterface(unsigned int) (Interface.cpp:962)
==30892== by 0x126FB3: gre_tunnel_create(node_*, unsigned short) (gre.cpp:39)
==30892== by 0x1267A3: gre_tunnel_config_handler(int, stack*, op_mode) (grecli.cpp:56)
==30892== by 0x1135FB: task_cbk_handler_internal(event_dispatcher_*, void*, unsigned int) (cli_interface.c:47)
==30892== by 0x13982F: event_dispatcher_thread(void*) (event_dispatcher.c:219)
==30892== by 0x4D3597B: start_thread (pthread_create.c:447)
==30892== by 0x4D9B7DB: thread_start (clone.S:79)
==30892== Address 0xad6d288 is 12 bytes after a block of size 188 alloc'd
==30892== at 0x48859FC: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==30892== by 0x126F9B: gre_tunnel_create(node_*, unsigned short) (gre.cpp:39)
==30892== by 0x1267A3: gre_tunnel_config_handler(int, stack*, op_mode) (grecli.cpp:56)
==30892== by 0x1135FB: task_cbk_handler_internal(event_dispatcher_*, void*, unsigned int) (cli_interface.c:47)
==30892== by 0x13982F: event_dispatcher_thread(void*) (event_dispatcher.c:219)
==30892== by 0x4D3597B: start_thread (pthread_create.c:447)
==30892== by 0x4D9B7DB: thread_start (clone.S:79)
==30892==
==30892== Invalid write of size 2
==30892== at 0x143E88: GRETunnelInterface::GRETunnelInterface(unsigned int) (Interface.cpp:962)
==30892== by 0x126FB3: gre_tunnel_create(node_*, unsigned short) (gre.cpp:39)
==30892== by 0x1267A3: gre_tunnel_config_handler(int, stack*, op_mode) (grecli.cpp:56)
==30892== by 0x1135FB: task_cbk_handler_internal(event_dispatcher_*, void*, unsigned int) (cli_interface.c:47)
==30892== by 0x13982F: event_dispatcher_thread(void*) (event_dispatcher.c:219)
==30892== by 0x4D3597B: start_thread (pthread_create.c:447)
==30892== by 0x4D9B7DB: thread_start (clone.S:79)
==30892== Address 0xad6d288 is 12 bytes after a block of size 188 alloc'd
==30892== at 0x48859FC: operator new(unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-arm64-linux.so)
==30892== by 0x126F9B: gre_tunnel_create(node_*, unsigned short) (gre.cpp:39)
==30892== by 0x1267A3: gre_tunnel_config_handler(int, stack*, op_mode) (grecli.cpp:56)
==30892== by 0x1135FB: task_cbk_handler_internal(event_dispatcher_*, void*, unsigned int) (cli_interface.c:47)
==30892== by 0x13982F: event_dispatcher_thread(void*) (event_dispatcher.c:219)
==30892== by 0x4D3597B: start_thread (pthread_create.c:447)
==30892== by 0x4D9B7DB: thread_start (clone.S:79)
==30892==
Подробнее здесь: https://stackoverflow.com/questions/791 ... -the-class