Maison >développement back-end >Golang >Erreur mystérieuse : 'Le pointeur Go vers l'argument cgo pointe vers le pointeur Go non épinglé'

Erreur mystérieuse : 'Le pointeur Go vers l'argument cgo pointe vers le pointeur Go non épinglé'

PHPz
PHPzavant
2024-02-06 10:48:04664parcourir

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

Contenu de la question

Je reçois cette erreur et même après avoir lu la documentation, je ne comprends pas ce que cela signifie. En fait, je pensais l'avoir compris, mais cela ne correspondait tout simplement pas à la façon dont cela m'était arrivé. Il ne semble y avoir aucune autre information sur ce problème spécifique ailleurs sur Internet.

Pour moi, c'est arrivé dans cette fonction (pas dans ma bibliothèque, qui semble bien fonctionner dans de nombreux endroits, donc c'est plus bizarre).

Pour mieux comprendre l'erreur, je l'ai modifié localement pour que chaque paramètre de la fonction C soit construit séparément et voir quelle partie a déclenché l'erreur :

Mais il s'avère que l'erreur se produit sur la ligne sous le curseur, donc je pense que c'est entièrement lié à l'appel C.lmdbgo_mdb_cursor_get1().

Je pensais que l'erreur signifiait que je passais un pointeur Go vers une fonction C et que je pouvais la corriger en enveloppant le pointeur Go avec un appel unsafe.Pointer(), mais ce n'est pas possible puisque c'est déjà fait et tous les arguments vers le correspondant Les fonctions C sont déjà des types C, pas des types Go.

MISE À JOUR : Après quelques recherches supplémentaires, j'ai découvert que la ligne 689 de l'actuel panic() 是在 /src/runtime/cgocall.go est émise :

Donc cgoIsGoPointer() 返回 trueisPinned() renvoie faux.

Comment diable puis-je « épingler » un pointeur Go ? Ou est-ce une mauvaise question ?

Mise à jour : Après avoir creusé davantage, j'ai découvert que le paramètre à l'origine du problème est c.txn.key, qui est hors de mon contrôle et semble être défini sur new(C. MDB_val) . c.txn.key,它超出了我的控制范围,似乎被设置为 new(C. MDB_val)


正确答案


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

Bonne réponse

Basé sur https:// github .com/PowerDNS/lmdb-go/issues /28 Ce problème est en fait dû à l'utilisation du constructeur Go new() pour créer un pointeur C, puis à le transmettre à une fonction C. . Ceux-ci doivent être créés en utilisant C.malloc().

Apparemment, ce problème n'est jamais apparu à personne d'autre, car personne n'a fait la même erreur que moi en utilisant cette bibliothèque : utiliser la même transaction à partir de plusieurs goroutines, ce qui est explicitement interdit par LMDB (enfin, LMDB dit threads, mais peut-être que mon goroutine génère de nouveaux fils de discussion). Selon 🎜wojas🎜 : 🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer