2016-07-16 10 views
0

Ich bin mit dem einfachstenen Interprozess-Kommunikation Programm Setup boost::interprocess mit:C++ Segmentation fault wenn try-catch eingeführt wird

#include <boost/interprocess/managed_shared_memory.hpp> 
#include <cstdlib> //system 
#include <iostream> 

using namespace std; 
using namespace boost::interprocess; 
typedef pair<double, int> MyType; 

int main(int argc, char *argv[]) { 

    if (argc==1) { //Parent process 

     struct shm_remove { 
      shm_remove() {shared_memory_object::remove("MySharedMemory");} 
      ~shm_remove() {shared_memory_object::remove("MySharedMemory");} 
     } remover; 

     managed_shared_memory segment(create_only,"MySharedMemory",65536); 
     MyType* instance=segment.construct<MyType>("MyType instance")(0.5,2); 
     string s(argv[0]); 
     s+=" child "; 
     if(system(s.c_str())!=0) { 
      cout<<"Parent: Child process returned non-zero"<<endl; 
      return 1; 
     } 
     cout<<"Parent: Child process finished successfully"<<endl; 
     segment.destroy<MyType>("MyType instance"); 

    } else { //Child process 

     pair<MyType*, managed_shared_memory::size_type> res; 
//  try { 
      managed_shared_memory segment(open_only, "MySharedMemory"); 
      res=segment.find<MyType>("MyType instance"); 
//  } catch (interprocess_exception &e) { 
//   cerr<<"Error while opening the segment"<<endl; 
//   return 1; 
//  } 
     cout<<"Child: Segment of length "<<res.second<<" is found at "<<res.first<<endl; 
     cout<<"Child: "<<res.first->first<<", "<<res.first->second<<endl; 

    } 

    return 0; 
} 

Dies funktioniert, und ich sehe:

Child: Segment of length 1 is found at 0x106a15148 
Child: 0.5, 2 
Parent: Child process finished successfully 

Allerdings, wenn ich Kommentar- der try-catch Block, sehe ich folgendes:

Child: Segment of length 1 is found at 0x10a8fd148 
Parent: Child process returned non-zero 

Wenn ich die binäre in zwei (Segment erzeugenden und für immer schlafend Eltern und Segment-Lese Kind) zu brechen, es funktioniert wieder ohne try-cacth, aber damit das Kind stürzt mit

Segmentation fault: 11 

Daher habe ich zwei Fragen:

  1. Was verursacht die Einführung der try-catch Ursache? Es verhält sich so, als hätte der Block seinen eigenen Adressraum. Aber warum sollte es?
  2. Wie sicher nach dem Vorhandensein des erforderlichen Segments zu überprüfen und eine Fehlermeldung generieren, die nicht gefunden wird?

EDIT:

if (1) { 
    managed_shared_memory segment(open_only, "MySharedMemory"); 
    res=segment.find<MyType>("MyType instance"); 
    cout<<"Child: Segment of length "<<res.second<<" is found at "<<res.first<<endl; 
    cout<<"Child: "<<res.first->first<<", "<<res.first->second<<endl; 
} 

Ich bekomme den gleichen Fehler:

Child: Segment of length 1 is found at 0x108c15148 
Child: 0.5, 2 
Child: Segment of length 1 is found at 0x108c15148 
Parent: Child process returned non-zero 

Daher ist das Verhalten in der Tat durch, verursacht wird

ich den Block geändert haben {}, vermutlich aufgrund der Zerstörung von . Aber warum wäre es wichtig, wenn res.first bereits mit dem richtigen Zeiger gefüllt ist?

+0

Was tut 'segment' destructor? Es scheint, als ob es etwas freigibt, auf das du später zugreifen willst. – lapk

Antwort

1

Das Problem scheint zu sein, dass der Destruktor von managed_shared_memory aufgerufen wird, aber Sie weiterhin auf Zustand oder Zuweisung von ihm nach dem try catch-Block gehalten werden.

managed_shared_memory segment; 

Daran erinnern, dass Destruktoren wird immer am Ende eines Bereichs (im Grunde jede Schließung }) genannt, und das gilt für auch try-Blöcke.

Wenn dies nicht die `` main` Funktion, wäre es wahrscheinlich besser, die Ausnahme Flucht mit dem Anrufer zu lassen (kein Try-Catch), oder wieder wirft sie (oder eine andere Ausnahme):

try { 
     managed_shared_memory segment(open_only, "MySharedMemory"); 
     res=segment.find<MyType>("MyType instance"); 
     cout<<"Child: Segment of length "<<res.second<<" is found at "<<res.first<<endl; 
     cout<<"Child: "<<res.first->first<<", "<<res.first->second<<endl; 

    } catch (interprocess_exception &e) { 
     cerr<<"Error while opening the segment"<<endl; 
     throw; 
    } 

der Tat haben einen Blick auf the documentation

The most important services of a managed memory segment are:

  • Dynamic allocation of portions of a memory the segment.

  • Construction of C++ objects in the memory segment. These objects can be anonymous or we can associate a name to them.

  • Searching capabilities for named objects.

  • Customization of many features: memory allocation algorithm, index types or character types.

  • Atomic constructions and destructions so that if the segment is shared between two processes it's impossible to create two objects
    associated with the same name, simplifying synchronization.

+0

Also die Rolle von "Segment" ist nicht nur den richtigen Zeiger auf das zugrunde liegende Array? Entfernt der Destruktor die Adresse selbst aus dem Prozessadressraum? – Roman

+0

@Roman, Ja - nach meinem Zitat gibt es frei. –