Können Sie einen Absturz erzwingen, wenn ein Schreib mit feiner als Seitengranularität zu einem bestimmten Speicherplatz auftritt?

StackOverflow https://stackoverflow.com/questions/2484959

Frage

Ich schreibe ein Programm, dass der Speicher aus Performance-Gründen Anwendungen gemeinsam genutzt (Steckdosen und Leitungen als Alternativen bewertet wurden, und sie sind nicht schnell genug für meine Aufgabe, in der Regel jedes IPC-Verfahren gesprochen, die Kopien beinhaltet ist zu langsam). Im gemeinsam genutzten Speicherbereich schreibe ich viele structs einer festen Größe. Es gibt ein Programm für die structs in den gemeinsamen Speicher zu schreiben, und viele Kunden, die von ihm lesen. Allerdings gibt es ein Mitglied jeder Struktur, dass die Kunden zu schreiben, um (einen Referenzzähler, die sie aktualisieren atomar) benötigen. Alle anderen Mitglieder zu den Kunden nur gelesen werden sollen.

Da Clients, dass ein Mitglied ändern müssen, können sie den gemeinsam genutzten Speicherbereich nicht abbilden, da nur lesen. Aber sie sollten auch nicht mit den anderen Mitgliedern werden basteln, und da diese Programme geschrieben in C ++, Speicherbeschädigung möglich. Im Idealfall sollte es so schwer wie möglich sein, für einen Kunden eines anderen zum Absturz bringen. Ich bin nur über Buggy Kunden besorgt, nicht bösartige, so unvollkommene Lösungen erlaubt sind.

kann ich versuchen, Kunden daran zu hindern, das Überschreiben durch die Mitglieder im Header deklarieren sie als const verwenden, aber das wird nicht Speicherbeschädigung (Pufferüberlauf, schlechte Würfe, etc.) vor dem Überschreiben verhindern. Ich kann Kanarienvögel , aber dann immer wieder die Kosten für die ich zahlen sie zu überprüfen.

Statt die Referenzzähler Mitglied direkt zu speichern, kann ich einen Zeiger auf die tatsächlichen Daten in einem separaten abgebildet Schreib speichert nur Seite, während die Strukturen in nur lesen kartiert Seiten zu halten. Dies funktioniert, wird das O meiner Anwendung zwingen, zum Absturz bringen, wenn ich zu schreiben an den spitzen zu Daten versuchen, aber indirekte Lagerung kann unerwünscht sein, wenn zu schreiben sperren frei Algorithmen , denn um einen anderen Dereferenzierungsebene folgen kann, ob können atomar getan werden, um etwas ändern.

Gibt es eine Möglichkeit kleinere Bereiche wie der Speicher zu markieren, dass das Schreiben sie Ihre App zu sprengen verursachen? Einige Plattformen haben Hardware Beobachtungspunkte, und vielleicht könnte ich mit Inline-Assembler einen von denen aktivieren, aber ich würde nur 4 zu einer Zeit auf 32-Bit-x86 begrenzt und jeder kann nur einen Teil der Struktur abdecken, weil sie begrenzt sind bis 4 Byte. Es wäre auch mein Programm schmerzhaft zu debuggen machen;)

Edit: Ich fand dieses eher Auge popping Papier , aber es erfordert Verwendung von ECC-Speicher und einen modifizierten Linux-Kernel leider.

War es hilfreich?

Lösung

Ich glaube nicht, seine möglich wenige Bits wie das nur zu machen lesen auf OS-Ebene.

Eine Sache, die gerade jetzt fiel mir ein, dass Sie die Referenzzähler in einer anderen Seite setzen könnte, wie Sie vorgeschlagen. Wenn die Strukturen eine gemeinsame Größe sind, und alle sind in aufeinanderfolgenden Speicherplatz Sie Zeigerarithmetik verwenden könnten einen Referenzzähler von den Strukturen Zeigern, anstatt einen Zeiger innerhalb der Struktur zu lokalisieren. Dies könnte besser sein, als einen Zeiger für Ihren Anwendungsfall ist.

long *refCountersBase;//The start address of the ref counters page
MyStruct *structsBase;//The start address of your structures page

//get address to reference counter
long *getRefCounter(MyStruct *myStruct )
{
    size_t n = myStruct - structsBase;
    long *ref = refCountersBase + n;
    return ref;
}

Andere Tipps

Sie müßten einen Signal-Handler für SIGSEGV hinzuzufügen, die von der Ausnahme erholt, aber nur für bestimmte Adressen. Ein Ausgangspunkt könnte sein, http://www.opengroup.org/onlinepubs /009695399/basedefs/signal.h.html und die entsprechende Dokumentation für Ihr Betriebssystem.

Edit: Ich glaube, was Sie wollen, ist die Schreib- und Rückkehr auszuführen, wenn die Schreibadresse tatsächlich in Ordnung ist, und Schwanz rufen Sie die vorherige Exception-Handler (den Zeiger erhalten Sie, wenn Sie Ihre Ausnahme installieren Handler), wenn Sie die Ausnahme propagieren wollen. Ich bin allerdings nicht in diesen Dingen erfahren.

Ich habe noch nie von ihnen Geltung schreibgeschützt auf weniger als eine Seitengranularität gehört, so dass Sie in dieser Richtung Glück heraus könnte, es sei denn Sie jede Struktur auf zwei Seiten setzen. Wenn Sie zwei Seiten pro Struktur leisten können, können Sie den Verweiszähler auf einer der Seiten setzen und die andere schreibgeschützte machen.

Sie können eine API anstatt nur Gebrauch Header schreiben. Erzwingen Kunden die API zu verwenden, würden die meisten Fragen der Korruption entfernen.

mit dem Referenzzähler die Daten zu halten, anstatt auf einer anderen Seite mit Lokalität von Daten helfen und so Cache-Leistung zu verbessern.

Sie müssen bedenken, dass ein Leser ein Problem hat und nicht mehr ordnungsgemäß seine Verweiszähler aktualisieren. Auch, dass der Schriftsteller kann fehlschlagen, ein Update zu vervollständigen. Der Umgang mit diesen Dingen erfordert zusätzliche Kontrollen. Sie können solche Kontrollen mit dem API kombinieren. Es kann sich lohnen, zu experimentieren, die Auswirkungen auf die Leistung von irgendeiner Art von Integritätsprüfung zu messen. Es kann schnell genug sein, um eine Prüfsumme zu halten, etwas so einfaches wie adler32.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top