Voici le noyau du noyau de ma réponse: écris du code.
Le noyau de ma réponse est: Si votre compilateur attribue la population locale sur la pile toujours, alors ...
Ajouter blobs à la pile à chaque entrée de fonction qui enregistre le nom de la fonction, jeter dans la magie des nombres pour peut-être attraper des cassures de pile.
typedef struct stack_debug_blob_ {
int magic1;
const char * function_name;
int magic2;
struct stack_debug_blob_ * called_by;
int magic3;
} stack_debug_blob;
stack_debug_blob * top_of_stack_debug_blobs = 0;
Créez une macro ENTRÉE (f) en prenant le nom de la fonction. La macro devrait être sur la première ligne de code dans chaque fonction après l'ouverture {. Il ajoute une structure avec un pointeur sur le nom de la fonction (const) char *, un pointeur vers la structure précédente sur la pile, et peut-être quelques nombres magiques pour vérifier la santé mentale. Faire le haut du pointeur de pile de blob à cette nouvelle structure. Pour que les choses restent aussi portables que possible, tout ce que peut faire ENTER est de déclarer et d'initialiser les variables. D'où le evil_hack pour faire un peu plus de calculs que juste initialiser une variable.
Créez une fonction pour parcourir la liste des pointeurs de vérification des blobs et des nombres magiques. Il devrait signaler une erreur (peut-être imprimer sur stderr, peut-être bloquer le cpu avec while (1) {/ * nada * /}, peut-être entrer dans le débogueur ... dépend de votre matériel) s'il trouve des choses foirées.
Créez une macro EXIT() qui vérifie votre pile de blobs, puis désolidarise le plus haut de la liste chaînée. Il doit être placé aux points de sortie de toutes vos fonctions.
#define EXIT() do { \
check_debug_blobs(); \
top_of_stack_debug_blobs = new_stack_debug_blob.called_by; \
new_stack_debug_blob.magic1 -= 1; /* paranoia */ \
} while (0)
sera probablement aussi besoin de remplacer par des appels de macro RETURN de tous retour, la macro RETURN est comme EXIT, mais il a un retour avant la} while (0).
Créez une fonction pour parcourir la liste des blobs en imprimant les noms des fonctions, appelez-la quelque chose comme stacktrace ou backtrace.
Écrivez un programme pour instrumenter votre code C avec des appels à ENTER (f) et EXIT() et RETURN (x).
Gauche quelques détails pour vous permettre de vous amuser avec elle ...
Voir aussi Any porting available of backtrace for uclibc?
Bien! Cela va dans ma liste de signets. – jsl4tv
@ jsl4tv - J'ai utilisé une implémentation il y a des années, ça fonctionnait même sur K & R C, mais ce n'était pas open-source ... par conséquent "le chien a mangé le code source!" – NevilleDNZ
La seule chose qui me manque dans le code rosetta, une chose importante qui manque, c'est le code pour instrumentaliser/décorer votre source automagiquement. Bien sûr, ma prochaine demande de fonctionnalité serait la plus difficile "... et les paramètres aussi". Je * pense * que vous pourriez obtenir cela d'une manière portable en faisant toutes les fonctions varargs et en utilisant l'accès poli/standard aux args. Grand article à faire! – jsl4tv