Valgrind Недопустимое чтение и запись для всех переменных экземпляра класса.C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Valgrind Недопустимое чтение и запись для всех переменных экземпляра класса.

Сообщение Anonymous »

У меня есть класс, который имеет определенные переменные экземпляра. У меня возникают случайные сбои при запуске приложения. Думая о повреждении памяти, я запустил приложение под управлением 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
Код, вызывающий конструктор GRETunnelInterface(). Мое приложение имеет интерфейс CLI. Итак, эта fn вызывается через CLI.

Код: Выделить всё

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==
E3

Подробнее здесь: https://stackoverflow.com/questions/791 ... -the-class
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»