Segmentierungsfehler beim Zugriff auf eine funktionsstatische Struktur über den zurückgegebenen Zeiger

9

Ich habe folgende Struktur:

%Vor%

Ich habe auch eine Funktion in einer statischen Bibliothek definiert (nennen wir es A.lib):

%Vor%

Ich habe dann ein Programm (nennen wir es B) und eine dynamische Bibliothek (nennen wir es C). Sowohl B als auch C verbinden sich mit A.lib. Zur Laufzeit öffnet B C über dlopen() und erhält dann über einen Aufruf von func() eine Adresse an die C-Funktion dlsym() .

%Vor%

Der obige Code ist der Körper von Cs func() -Funktion und erzeugt einen Segmentierungsfehler, wenn er erreicht wird. Der Segfault tritt nur auf, wenn er außerhalb von gdb ausgeführt wird.

Warum passiert das?

BEARBEITEN: sys_config_t config eine globale Variable zu machen, hilft nicht.

    
MasterM 12.09.2011, 16:10
quelle

2 Antworten

1

Die Lösung ist trivial. Irgendwie wurde die PATH_MAX-Konstante bei einer Header-Fehlübereinstimmung in den Kompilierungseinheiten von B und C anders definiert. Ich muss in Zukunft vorsichtiger sein. ( facepalms )

    
MasterM 12.09.2011, 19:12
quelle
0

Es gibt keinen Unterschied zwischen der Variablen, die eine statisch-lokale oder eine statisch-globale Variable ist. Eine statische Variable ist STATIC, das heißt, sie wird bei Funktionsaufrufanforderung nicht auf dem Stapel innerhalb des aktuellen Funktionsrahmens zugewiesen, sondern wird in einem der bereits vorhandenen Segmente des Speichers zugewiesen, die in den Binärkopfzeilen der ausführbaren Datei definiert sind.

Darauf bin ich 100% sicher. Die Frage, wo und in welchem ​​Segment sie genau platziert sind, ist ein weiteres Problem. Ich habe ähnliche Probleme beim Teilen von globalen / statischen Variablen zwischen Modulen gesehen, aber normalerweise war der Kern des Problems sehr spezifisch für das genaue Setup.

Bitte beachten Sie, dass das Codebeispiel klein ist und ich vor langer Zeit an diesen Plattformen gearbeitet habe. Was ich oben geschrieben habe, könnte an einigen Stellen falsch formuliert sein oder sogar falsch sein!

Ich denke, dass es wichtig ist, dass Sie diesen Segmentfehler in C bekommen, wenn Sie diese Linie berühren. Das Setzen eines Integer-Feldes auf eine Konstante konnte niemals fehlgeschlagen sein, vorausgesetzt, die Zieladresse ist gültig und nicht schreibgeschützt. Das lässt zwei Optionen übrig: - Entweder ist Ihre Funktion sys_get_config () abgestürzt - oder es hat einen ungültigen Zeiger zurückgegeben.

Da Sie sagen, dass der segfault hier, nicht in sys_get_config, ausgelöst wird, bleibt nur der letzte Punkt übrig: unterbrochener Zeiger.

Fügen Sie der sys_get_config einige triviale printf hinzu, die die zurückzugebende Adresse ausgeben, und machen Sie das selbe in der aufrufenden Funktion "func". Überprüfen Sie, ob es not-null ist, und prüfen Sie, ob es innerhalb von sys_get_config dasselbe ist wie nach der Rückgabe, um sicher zu gehen, dass die Aufrufkonventionen korrekt sind. Eine gute Idee für eine Doppel / Dreifach-Prüfung ist es auch innerhalb des Modul "A" eine Kopie der Funktion sys_get_config (mit natürlichem Namen), und um zu überprüfen, ob die aus sys_get_config zurückgegebenen Adressen und ihre Kopie identisch sind. Wenn sie nicht sind - etwas ist während der Verlinkung sehr schief gelaufen

Es gibt auch eine sehr sehr kleine Chance, dass das Laden des Moduls verschoben wurde und Sie versuchen, auf einen Speicher eines Moduls zu verweisen, das noch nicht vollständig initialisiert wurde. Ich habe vor sehr langer Zeit an Linux gearbeitet, aber ich erinnere mich Das dlopen hat verschiedene Ladeoptionen. Aber du hast geschrieben, dass du die Adresse mit dlsym bekommen hast, also nehme ich an, dass das Modul geladen wurde, da du die letzte Adresse des Symbols hast.

    
quetzalcoatl 12.09.2011 18:11
quelle