Obtenir l'Adresse Mémoire de l' .NET Objet (C#)
Je suis en train de traquer un bug dans le mono d'exécution lorsqu'une variable semble être attribuée à un objet valide, puis attribué plus tard à un faux objet, plus précisément
//early in code I allocate, fine
var o = new object(); //valid allocation
//later in code this is called, not fine
lock(o) //<- is triggering bug due to "o" now referencing a nonsense memory location.
Je voudrais savoir quand la référence à "o" devient non-sens, et pour ce faire je suis à la recherche d'un moyen de déterminer l'adresse de "o" à divers intervalles dans le code C#. Je sais, c'est similaire à d'autres questions avec des réponses "ne fais pas ça il y a une table", mais le GC ne fonctionne pas donc j'ai besoin d'une solution de contournement.
Personne ne sait comment je peux déterminer l'adresse d'un mono objet en C#? Suis bien le lien dans le code non managé ou quoi que ce soit. (Toutes les autres indices moyens de diagnostiquer le problème principal apprécié pour).
- Quel est le message d'erreur exact? Est-il à propos de l'éliminer plutôt que "d'être non-sens"?
- Au lieu de verrouillage sur un
object
, pourriez-vous créer une classe jetables avec un finaliseur-mais pas de ressources réelles -- puis la verrouiller, et de définir les pauses dans le débogueur quand il est finalisé? - L'erreur complet est décrit ici, et qui se passe en aval: bugzilla.xamarin.com/show_bug.cgi?id=21939 Fondamentalement, le GC traite une mauvaise référence comme un objet, conduisant à un sigsegv
- Est-ce que tout dans la même méthode?
- malheureusement, le code est dans la classe runtime des bibliothèques (en particulier Paresseux.cs), donc je suis en train de corriger le bogue, plutôt que de changer le bon C#
- l'objet de l'allocation est dans le constructeur, le verrou est pris, plus en aval dans une méthode. Lignes 87 et 150 dans ce fichier (github.com/mono/mono/blob/master/mcs/class/corlib/System/...)
- C'est un undebuggable problème, l'adresse d'un objet change constamment, tandis que le GC compacte le tas. Vous avez besoin de poursuivre le type de bug, vous pouvez le fixer et à supposer que cela est causé par la corruption de segment. Le genre produit par débordement de mémoire tampon dans le code non managé.
- plus difficile bug que j'ai vu jusqu'à présent et semble certainement en raison d'une corruption de mémoire. Si l'adresse change à chaque GC, il semble que lorsque la modification de la mauvaise valeur, il est toujours affecté à l'exact même mauvais (et faux) de la valeur, je suis donc vérifier si c'est le cas. Mon espoir était de restreindre l'intervalle lorsque la corruption se produit en le faisant. Si vous savez de quoi que ce soit d'autre qui est utile pour le débogage mem corruption, serait heureux de l'entendre.
Vous devez vous connecter pour publier un commentaire.
Vous devriez être en mesure d'utiliser le GCHandle construire pour accomplir cette tâche.
Où 'obj' est l'objet dont l'adresse vous essayez d'obtenir.
S'avère que ce n'est pas possible .NET directement, mais peut être accompli en modifiant le mono d'exécution de code. Pour créer une méthode C# qui permet de lire l'adresse de la mémoire, apporter les modifications suivantes à la source mono code:
Modifier gc-interne.h pour ajouter
Modifier gc.c ajouter:
Modifier GCHandle.cs d'ajouter:
Modifier icall-def.h pour ajouter
Noter que ceux-ci doivent être dans l'ordre, donc de l'ajouter au-dessus de la GetAddrOfPinnedObject ligne
Reconstruire
Enfin, l'appeler à partir de C#
Vous ne pouvez pas obtenir l'adresse d'un manged objet en code managé, en général. Si l'objet a un champ comme un int, tu pourrais prendre d'adresse avec le fixe C#, instruction et alors vous auriez un pointeur à l'intérieur de l'objet. À des fins de débogage, vous pourriez faire quelques hypothèses et obtenir le décalage de la base de pointeur de l'objet (sur 32 bits plates-formes de l'objet taille d'en-tête sur la mono est de 8 octets 16 octets sur les architectures 64 bits, en ce moment).
Votre rapport de bogue déclare que vous êtes à l'aide de l'Boehm collector, bien que, et que collectionneur de ne pas déplacer les objets en mémoire, le bug pourrait être causé par certains indépendants de corruption de la mémoire, par l'objet à tort libéré ou d'une autre logique bug dans le GC (je ne suis pas sûr de la taille zéro vous l'avez souligné est importante, puisqu'un objet géré est au moins de 8 à 16 octets d'en-tête).
Ma alternatives... Aussi @ Cette question similaire