Heim >Backend-Entwicklung >Golang >Mysteriöser Fehler: „Go-Zeiger auf CGO-Argument zeigt auf nicht angehefteten Go-Zeiger'

Mysteriöser Fehler: „Go-Zeiger auf CGO-Argument zeigt auf nicht angehefteten Go-Zeiger'

PHPz
PHPznach vorne
2024-02-06 10:48:04662Durchsuche

神秘错误:“cgo 参数的 Go 指针指向未固定的 Go 指针”

Frageninhalt

Ich erhalte diese Fehlermeldung und selbst nachdem ich die Dokumentation gelesen habe, verstehe ich nicht, was sie bedeutet. Tatsächlich dachte ich, ich hätte es verstanden, aber es passte einfach nicht so, wie es mir passierte. An anderer Stelle im Internet scheint es zu diesem speziellen Thema keine weiteren Informationen zu geben.

Bei mir ist es in dieser Funktion passiert (nicht in meiner Bibliothek, die an vielen Stellen gut zu funktionieren scheint, daher ist das seltsamer).

Um den Fehler besser zu verstehen, habe ich ihn lokal geändert, sodass jeder Parameter der C-Funktion separat erstellt wird, und sehen, welcher Teil den Fehler ausgelöst hat:

Aber es stellt sich heraus, dass der Fehler in der Zeile unter dem Cursor auftritt, also denke ich, dass er ausschließlich mit dem C.lmdbgo_mdb_cursor_get1()-Aufruf zusammenhängt.

Ich dachte, der Fehler bedeute, dass ich einen Go-Zeiger an eine C-Funktion übergebe und dass ich ihn beheben könnte, indem ich den Go-Zeiger mit einem unsafe.Pointer()-Aufruf umschließe, aber das ist nicht möglich, weil es bereits erledigt ist und alle Argumente an die entsprechende C-Funktion übergeben wurden sind bereits C-Typen, keine Go-Typen.

UPDATE: Nach etwas mehr Recherche habe ich herausgefunden, dass Zeile 689 des aktuellen panic() 是在 /src/runtime/cgocall.go ausgegeben wird:

Deshalb gibt cgoIsGoPointer() 返回 trueisPinned() false zurück.

Wie um alles in der Welt kann ich einen Go-Zeiger „anpinnen“? Oder ist das die falsche Frage?

Update: Nach weiteren Recherchen habe ich herausgefunden, dass der Parameter, der das Problem verursacht, c.txn.key ist, der außerhalb meiner Kontrolle liegt und auf new(C.) gesetzt zu sein scheint. MDB_val) . c.txn.key,它超出了我的控制范围,似乎被设置为 new(C. MDB_val)


正确答案


根据https://github.com/PowerDNS/lmdb-go/issues /28 这个问题实际上是由使用 Go new() 构造函数创建 C 指针然后传递给 C 函数引起的。这些应该是使用 C.malloc()

Richtige Antwort

Basierend auf https:// github .com/PowerDNS/lmdb-go/issues /28 Dieses Problem wird tatsächlich dadurch verursacht, dass der Go-Konstruktor new() verwendet wird, um einen C-Zeiger zu erstellen und ihn dann an eine C-Funktion zu übergeben . Diese sollten mit C.malloc() erstellt werden.

Anscheinend ist dieses Problem noch nie jemandem aufgetreten, da niemand den gleichen Fehler gemacht hat, den ich bei der Verwendung dieser Bibliothek gemacht habe: die Verwendung derselben Transaktion aus mehreren Goroutinen, was von LMDB ausdrücklich verboten ist (naja, LMDB sagt Threads, aber vielleicht meine Goroutine bringt neue Threads hervor). Laut 🎜wojas🎜: 🎜

Das obige ist der detaillierte Inhalt vonMysteriöser Fehler: „Go-Zeiger auf CGO-Argument zeigt auf nicht angehefteten Go-Zeiger'. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen