Project

General

Profile

Actions

Bug #4769

closed

Segfault in InMemoryStorage insert after capacity becomes zero

Added by Ashlesh Gawande about 6 years ago. Updated almost 6 years ago.

Status:
Closed
Priority:
Normal
Category:
Utils
Target version:
Start date:
Due date:
% Done:

100%

Estimated time:

Description

Trying to test PSync change which has a SegmentPublisher that is using IMSFifo, a Segfault was observed.
(https://gerrit.named-data.net/c/PSync/+/4892/9/src/segment-publisher.cpp)
Should we not erase content from the IMS?

To reproduce:

// g++ -std=c++14 test-ims.cpp $(pkg-config --libs libndn-cxx)
#include <ndn-cxx/ims/in-memory-storage-fifo.hpp>
#include <ndn-cxx/util/scheduler.hpp>
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <iostream>

ndn::Face m_face;
ndn::util::Scheduler m_scheduler(m_face.getIoService());
ndn::InMemoryStorageFifo m_ims(100);
ndn::time::milliseconds freshness(1600);
ndn::KeyChain m_keyChain;

void
publishDummy(ndn::Name name, int segmentNum) {
  ndn::Name segment(name);
  segment.appendSegment(0);
  std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(segment);
  m_keyChain.sign(*data);

  std::cout << "Insert into ims: " << *data << std::endl;
  m_ims.insert(*data, freshness);

  m_scheduler.scheduleEvent(freshness,
                            [segment] {
                              std::cout << "Removing " << segment << std::endl;
                              m_ims.erase(segment);
                            });
}

int
main() {
  publishDummy(ndn::Name("test/1"), 0);

  m_scheduler.scheduleEvent(ndn::time::milliseconds(94),
                           [] {
                             publishDummy(ndn::Name("test/2"), 0);
                           });

  m_scheduler.scheduleEvent(ndn::time::milliseconds(5354),
                           [] {
                             publishDummy(ndn::Name("test/3"), 0);
                           });

  m_scheduler.scheduleEvent(ndn::time::milliseconds(7429),
                           [] {
                             publishDummy(ndn::Name("test/4"), 0);
                           });

  m_scheduler.scheduleEvent(ndn::time::milliseconds(9828),
                           [] {
                             publishDummy(ndn::Name("test/5"), 0);
                           });

  m_face.processEvents();

  return 0;
}

Happens here, when m_freeEntries.size() is 1 and size() is zero:

  if (m_freeEntries.size() > (2 * size()))
     setCapacity(getCapacity() / 2);

A solution could be not allowing to set capacity as zero.

Actions #1

Updated by Davide Pesavento about 6 years ago

  • Category set to Utils

A solution could be not allowing to set capacity as zero.

Yes, that should clearly be disallowed. However, I don't see in your code snippet where the capacity is set to zero.

Actions #2

Updated by Davide Pesavento about 6 years ago

  • Subject changed from Segfault in IMS insert after capacity becomes zero to Segfault in InMemoryStorage insert after capacity becomes zero
Actions #3

Updated by Ashlesh Gawande about 6 years ago

Davide Pesavento wrote:

A solution could be not allowing to set capacity as zero.

Yes, that should clearly be disallowed. However, I don't see in your code snippet where the capacity is set to zero.

Every erase halves the capacity.

Actions #4

Updated by Ashlesh Gawande about 6 years ago

  • Status changed from New to Code review
Actions #5

Updated by Davide Pesavento about 6 years ago

  • Assignee set to Ashlesh Gawande
  • Target version set to v0.7
Actions #6

Updated by Ashlesh Gawande about 6 years ago

  • % Done changed from 0 to 100
Actions #7

Updated by Davide Pesavento almost 6 years ago

  • Status changed from Code review to Closed
Actions

Also available in: Atom PDF