Thread-spezifische Daten von linux core dump
Wie bekomme ich die pointer für thread-lokalen Speicher oder thread-spezifische Daten, während die Analyse von core-dump für linux ?
benutze ich pthread_setspecific speichern einige Daten in der pthread lokalen stoare.
meine multi-threaded-Programm unter linux ist abgestürzt, und ich möchte sehen, was gespeichert ist, in einen Laufenden thread local storage.
Wenn ich die pointer für thread-lokalen Speicher kann ich verwenden-Taste, um die gespeicherten Daten.
Gibt es einen Befehl in gdb, um die Zeiger auf thread-lokalen Speicher?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie Debuggen eine live-Sendung, können Sie:
Wenn Sie Zugang zu den pthread_t des Threads, Sie können:
wo ich in der index, den Sie möchten, und pth ist der pthread_t. Sehen nptl/pthread_getspecific.c in der glibc-Quellen.
Dies zu tun, ohne eine Funktion aufrufen, müssen Sie die Struktur pthread. Auf x86-64, es ist gespeichert in der fs-Basis, die mithilfe arch_prctl(ARCH_SET_FS_BASE, ...). Ich weiß nicht, wie Zugriff auf diese vom gdb, aber man kann es mit der eu-readelf. Führen Sie
eu-readelf --notes core_file
und schauen Sie durch die Datensätze fürfs.base
. Diese Zahl ist der pthread_t Wert. (Um herauszufinden, welches es ist, Sie können match diepid
Feld in den gleichen Datensatz mit der LWP gezeigt, in der gdb -info threads
Befehl.)Glück!
Soweit ich weiß, gibt es keinen Befehl in der gdb um einen Zeiger auf den gespeicherten Daten über
pthread_setspecific()
. Allerdings gibt es ein paar Optionen zu erhalten, wird die Speicher-Adresse:pthread_getspecific()
immer noch auf dem Stapel.pthread_getspecific()
.Unten ist ein Demo mit einem einfachen Programm auf einem 32-bit-Maschine:
Mit Adressen noch auf dem Stapel:
Mit Adressen gedruckt von stdout:
Suchen Sie die thread-spezifische Daten Liste innerhalb des threads interne Daten:
Dieser Ansatz ist viel einfacher, wenn Sie den Wert
key
undpthread_t
.Stelle ich details über die pthread-Implementierung, die ich verwende, sobald Sie benötigt werden:
pthread
struct thread-descriptor-Struktur, die intern von pthread.pthread_create()
zurückpthread_t
eineunsigned int
enthält die Adresse des zugehörigenpthread
struct.Suchen Sie zuerst den
pthread
struct für den thread.Ignoriert viele der Felder, die
pthread
struct-definition sieht wie folgt aus:pthread_key_data.seq
: enthält die laufende Nummer, die sollte relativ niedrig und entsprechen__pthread_keys[key].seq
.pthread_key_data.data
: enthält den Wert zur Verfügung gestelltpthread_setspecific()
pthread.specific_1stblock
ist ein block, der verwendet wird zum speichern von thread-spezifischen Daten, bevor Sie versuchen, um dynamisch die Zuweisung von mehr Blöcke.pthread
ist ein zwei-Ebenen-array für thread-spezifische Daten. Index0
enthält die Speicheradresse despthread.specific_1stblock
.PTHREAD_KEY_2NDLEVEL_SIZE
hat eine Größe von 32.Die definition gibt eine ziemlich gute Vorstellung davon, was Sie suchen in Speicher:
pthread
Speicher-Adresse (tid
), gefolgt von einem integer mit der Prozess-id (pid
). Dies ist hilfreich um anzuzeigen, ob der Speicher geprüft ist einpthread
struct.cancelhandling
undflags
sind Fahnen. Die spezifischen Werte sind nicht wichtig. Diese Felder können hilfreich sein, da Ihre Werte sind potenziell sichtlich unterscheidbar von anderen Bereichen, wie zum Beispiel solche mit Speicher-Adressen oder Zähler.specific_1stblock
ist ein array der Größe 32. Wenn diepthread
struct hat null initialisiert, dann sollte es wiederholen0
s für 62~ Worte, weil der Beispiel-code hat nur eine thread-spezifische Datenposition_key
mit einer Größe von zwei Wörtern.specific
ist ein array von Speicher-Adressen. Wenn diepthread
struct hat null initialisiert, dann sollte es wiederholen0
s, aber der erste Wert sollte die Speicher-Adresse vonspecific_1stblock
.Print ein Stück
pthread
's Speicher:Durch analyizing Muster in den Speicher, einige Worte zu guten Kandidaten für eine bestimmte pthread-Felder:
Etwas Licht-Gewicht-Plausibilitätsprüfungen können durchgeführt werden, wie etwa die überprüfung, ob
pthread.specific[0]
enthält die Adresse despthread.specific_1stblock
:Nun, dass
pthread.specific
identifiziert wurde, erhalten Sie Ihre memory-Adresse durch das zählen der Wort-offset von&pthread
. In diesem Fall ist es 90:Berechnen Sie die erste und zweite index über
position_key
:key /PTHREAD_KEY_2NDLEVEL_SIZE
.Index in der zweiten Reihe ist
key % PTHREAD_KEY_2NDLEVEL_SIZE
.Suchen Sie die
pthread_key_data
fürposition_key
:Also:
pthread_key_data.seq = 1
pthread_key_data.data = 0x9a350b0
Das erste Wort ist das
seq
die sollten übereinstimmenpthread_key_struct[position_key].seq
. Durch den Umgang mit raw-Speicher,__pthread_keys
wird gegossen, umint*
- und Zeiger-Arithmetik wird erfolgen müssen, um eine Rechnung für den sizeof -pthread_key_struct
:Also:
pthread_key_struct[position_key].seq = 1
pthread_key_struct[position_key].destr = NULL
Den
seq
zahlen übereinstimmen, also alles sieht gut aus.pthread_key_data.data
enthält den Wert, der zurückgegeben werden vonpthread_getspecific( position_key )
.Ist es technisch immer noch möglich ist, suchen Sie thread-spezifische Daten, ohne Kenntnis der
key
undpthread_t
Werte:Wenn eine Destruktor-Funktion wurde bereitgestellt, um
pthread_key_create()
dann seine Speicher-Adresse möglicherweise gespeichert wird innerhalb der__pthread_keys
array. Untersuchen Sie den Speicher, und berechnen Sie den offset und dividieren durch den sizeof -pthread_key_struct
. Das Ergebnis ist der index, der zufällig auch der Schlüssel:Wenn die
pthread_t
unbekannt ist, kann es existiert innerhalb eines Registers auf den Stapel des Threads. Dies kann erfordern, die Prüfung der verschiedenen Speicher-Adressen, die versuchen, suchen Sie einen Abschnitt im Speicher, enthält diepthread
struct.In diesem Fall, die
edi
- register enthält die Adresse despthread
struct.Referenzen: descr.h, pthread_key_create.c, pthread_setspecific.c, pthreadP.h, internaltypes.h
example.cpp
. Auch im Auge behalten, dass das Register möglicherweise ungültig aufgrund von Beschädigung von stapeln.Thread -1219535984
Ausgabe ist bereits die Adresse des pthread_t