2016-06-27 23 views
0

In einigen seltenen Fällen (in der Tat auf einem einzelnen Client-Computer) zu schaffen Code unten löst eine Ausnahme "library_error":boost :: interprocess_exception - library_error Ausnahme, wenn shared_memory_object

namespace ipc = boost::interprocess; 
ipc::shared_memory_object m_shm; 
... 
bool initAsServer(size_t sharedMemSize) 
{ 
    ipc::permissions perm; 
    perm.set_unrestricted(); 

    try 
    { 
     m_shm = ipc::shared_memory_object(
      ipc::create_only, 
      CNameGenHelper::genUniqueNameUtf8().c_str(), // static std::string genUniqueNameUtf8() 
      ipc::read_write, perm); 
    } 
    catch(const ipc::interprocess_exception& ex) 
    { 
     logError("failed with exception \"%s\"", ex.what()); 
     return false; 
    } 
    ... 
} 

In Protokolldatei: [ERR] ist mit der Ausnahme "boost :: interprocess_exception :: library_error"

fehlgeschlagen Boost v1.58, Plattform win32, vs13.


werde ich sehr dankbar, wenn Sie mir helfen, dieses Problem zu lösen. Vielen Dank im Voraus!

+0

Prüfen Sie, ob das Shared Memory-Segment bereits im System vorhanden ist? – Arunmu

+0

Nein, dies ist nicht notwendig, da die Funktion CNameGenHelper :: genUniqueNameUtf8() einen eindeutigen Namen basierend auf der GUID generiert. Ich fügte der Protokolldatei hinzu, Fehlercodes über ex.get_error_code() und ex.get_native_error() für zusätzliche Ausnahmeinformationen zu erhalten. Jetzt warte ich auf Log-Dateien von der Client-Seite ... Vielen Dank für Ihr Interesse an diesem Problem! – Oleg

+0

für aktualisierte Zeile in Catch: logError ("fehlgeschlagen mit Ausnahme"% s ", Fehler% d, nativer Fehler% d", ex.what(), ex.get_error_code(), ex.get_native_error()); --- In Protokolldatei: [ERR] fehlgeschlagen mit Ausnahme "boost :: interprocess_exception :: library_error" Fehler 1, nativen Fehler 0. --- Fehler 1 - system_error (von Enum error_code_t) Helfen Sie mir bitte ... – Oleg

Antwort

1

Ursache des Problems sind Ereignisse mit Event ID = "6005" und Quellenname ist "EventLog" in "System" Windows-Protokoll. Event Viewer - Windows Logs - System. Wenn das Systemprotokoll enthält nicht mindestens ein solches Ereignis, dann Methode boost :: inter :: winapi :: get_last_bootup_time() kehrt falsche und boost :: inter :: ipcdetail :: windows_bootstamp Konstruktor löst Ausnahme aus. (define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME wird verwendet).

Es scheint also, dass es ausreicht, das Windows-Ereignisprotokoll "System" zu löschen, und jede Anwendung, die den freigegebenen Boost-Speicher verwendet, wird nicht mehr funktionieren.

Was für eine schreckliche Logik: Verwenden Sie den Inhalt des Windows-Ereignisprotokolls. Es scheint, dass dieser boost ipc-Implementierung Bug, der noch nicht behoben wurde (boost_1_61_0).

Meine vorübergehende Lösung für diesen Fall (w/o Neustart des Computers):

bool fixBoostIpcSharedMem6005issue() const 
{ 
    bool result = false; 

    HANDLE hEventLog = ::RegisterEventSourceA(NULL, "EventLog"); 
    if(hEventLog) 
    { 
     const char* msg = "simple boost shared memory fix for 6005"; 

     if(::ReportEventA(hEventLog, EVENTLOG_INFORMATION_TYPE, 0, 6005, NULL, 1, 0, &msg, NULL)) 
      result = true; 

     ::DeregisterEventSource(hEventLog); 
    } 

    return result; 
} 

es verwenden und versuchen ipc :: shared_memory_object wieder zu verwenden :)

1

Viele detaillierte Erläuterungen durch das Problem , von einem der Autoren der Bibliothek: Boost interprocess: Getting boot-up time is unreliable on Windows und hier: Interprocess get_last_bootup_time use of Event Log on Windows is completely unreliable

Offenbar eine zuverlässige Lösung ist es, die Präprozessorkonstante BOOST_INTERPROCESS_SHARED_DIR_PATH zu einem Funktionsaufruf zu definieren, die immer retur ns den gleichen Verzeichnispfad wie eine Zeichenfolge, sobald der Computer gebootet wird. Zum Beispiel durch Formatierung des Aktualisierungszeitstempels einer Datei, in die beim Start geschrieben wird.