dimanche 14 juillet 2019

Segmentation fault smart pointers

I get an error of" Segmentation fault while accessing address 0x0000000000000078 " when I run my code.

While debugging it shows an error in the line in function Family::Add(const std::map& labels, Args&&... args) in the line->

auto metrics_iter = metrics_.find(hash);

The error says SIGSEV, Gegmentation fault 0x00007fffcfa29ac1 in std::detail::_Hash_code_base>>,std::_detail::_Select1st,std::hash,std::_detail::_Mod_range_hashing,std::detail::_Default_ranged_hash,false>::_M_bucket_index (this=0x86a5878, _p=0x70,_n=1)include/c++/6.3.1/bits/hashtable_policy.h

The code is below->

GaugeFamilyCopy::Add() function

   //namespace prometheus
   GaugeCopy* GaugeFamilyCopy::Add()
  { GaugeCopy* ge = new GaugeCopy(gauge_family->Add(mp));
    return ge;
  }

Family::Add function

 //namespace prometheus
T& Family<T>::Add(const std::map<std::string, std::string>& labels,
              Args&&... args) {
auto hash = detail::hash_labels(labels);
std::lock_guard<std::mutex> lock{mutex_};
auto metrics_iter = metrics_.find(hash);

if (metrics_iter != metrics_.end()) {
  #ifndef NDEBUG
  auto labels_iter = labels_.find(hash);
  assert(labels_iter != labels_.end());
  const auto& old_labels = labels_iter->second;
  assert(labels == old_labels);
  #endif
  return *metrics_iter->second;
} else {
  #ifndef NDEBUG
  for (auto& label_pair : labels) {
    auto& label_name = label_pair.first;
    assert(CheckLabelName(label_name));
  }
  #endif

  auto metric =
    metrics_.insert(std::make_pair(hash, detail::make_unique<T> 
  (args...)));
  assert(metric.second);
  labels_.insert({hash, labels});
  labels_reverse_lookup_.insert({metric.first->second.get(), hash});
  return *(metric.first->second);
 }
}

hash_labels function

 //namespace detail which is inside prometheus namespace
std::size_t hash_labels(const std::map<std::string, std::string>& labels) 
{
  size_t seed = 0;
  for (auto& label : labels) {
  hash_combine(&seed, label.first, label.second);
  }

  return seed;
 }

Also I had assigned gauge_family it's value in this function ->

 //namespace MySpace
 void GaugeFamilyCopy::MakeGauge2(std::string s1, std::string s2, const 
 std::map<string,string>& labels, MyExposer* ex)
 {   auto registry = make_shared<prometheus::Registry>();
   gauge_family = & (prometheus::BuildGauge().Name(s1).Help(s2).Labels(labels).Register(*registry));
  ex->register(registry); 
 }

where Register function is given below->

 //namespace detail nested inside namespace prometheus
 Family<Gauge>& GaugeBuilder::Register(Registry& registry) {
   return registry.Add<Gauge>(name_, help_, labels_);
 }

Add function has been given above. Below are the classes for reference-

GaugeFamilyCopy class

 //namespace MySpace
 class GaugeFamilyCopy
 { void MakeGauge2(std::string s1,std::string s2,const 
   std::map<std::string,std::string>& labels);
   GaugeCopy* Add(const std::map<std::string,std::string>& mp);
   private:
   prometheus::Family<prometheus::Gauge>* gauge_family;

 }

GaugeCopy class

  //namespace MySpace
 class GaugeCopy
{ GaugeCopy()
  {}
  explicit GaugeCopy(prometheus::Gauge& gauge):
  g(&gauge)
  {}

  private:
  prometheus::Gauge* g;
 }

Gauge class

 //namespace prometheus
 class Gauge {
  public:
  static const MetricType metric_type{MetricType::Gauge};

  Gauge() = default;

  Gauge(double);

  void Increment();

  void Increment(double);

  void Decrement();

  void Decrement(double);

  void Set(double);

  void SetToCurrentTime();

  double Value() const;

  ClientMetric Collect() const;

  private:
  void Change(double);
  std::atomic<double> value_{0.0};
  };

Family class

  //namespace prometheus
 template <typename T>
 class Family : public Collectable {
 public:

 Family(const std::string& name, const std::string& help,
     const std::map<std::string, std::string>& constant_labels);

 void Remove(T* metric);

 std::vector<MetricFamily> Collect() override;

 private:
 std::unordered_map<std::size_t, std::unique_ptr<T>> metrics_;
 std::unordered_map<std::size_t, std::map<std::string, std::string>> 
 labels_;
 std::unordered_map<T*, std::size_t> labels_reverse_lookup_;

 const std::string name_;
 const std::string help_;
 const std::map<std::string, std::string> constant_labels_;
 std::mutex mutex_;

  ClientMetric CollectMetric(std::size_t hash, T* metric);
 };

Aucun commentaire:

Enregistrer un commentaire