Quel est le bon moyen de vider un fichier core Linux depuis un processus?

Nous avons un serveur (écrit en C et C ++) qui détecte actuellement un SEGV et envoie des informations internes à un fichier. Je voudrais générer un fichier de base et l’écrire sur le disque au moment où nous récupérons le SEGV, afin que nos représentants et clients ne soient pas obligés de manipuler ulimit, puis d’attendre que le crash se reproduise pour obtenir un kernel fichier. Nous avons utilisé la fonction d’abandon dans le passé, mais elle est soumise aux règles ulimit et n’aide pas.

Nous avons du code hérité qui lit / proc / pid / map et génère manuellement un fichier core, mais il est obsolète et ne semble pas très portable (par exemple, je suppose que cela ne fonctionnerait pas dans notre version 64 bits). construit). Quelle est la meilleure façon de générer et de sauvegarder un fichier core dans un processus Linux?

Google dispose d’une bibliothèque pour générer des coredumps à partir d’un processus en cours appelé google-coredumper . Cela devrait ignorer ulimit et d’autres mécanismes.

La documentation de l’appel qui génère le fichier principal est ici . Selon la documentation, il semble possible de générer un fichier core dans un gestionnaire de signal, bien qu’il ne soit pas garanti qu’il fonctionne toujours.

J’ai vu le post de pmbrett et j’ai pensé “hé, c’est cool” mais je n’ai pas trouvé cet utilitaire sur mon système (Gentoo).

J’ai donc fait un peu de recherche, et j’ai découvert que GDB avait cette option.

gdb --pid=4049 --batch -ex gcore 

Semblait fonctionner correctement pour moi.

Ce n’est cependant pas très utile car il piège la fonction la plus basse qui était utilisée à l’époque, mais il fait toujours du bon travail en dehors de cela (sans limitations de mémoire, instantané 350M d’un processus firefox)

Essayez d’utiliser la commande Linux gcore

utilisation: gcore [-o filename] pid

Vous devrez utiliser system (ou exec) et getpid () pour créer la ligne de commande appropriée pour l’appeler depuis votre processus.

Quelques solutions possibles ^ W façons de gérer cette situation:

  1. Réparez le ulimit !!!
  2. Acceptez le fait que vous n’obtenez pas un fichier de base et que vous exécutiez gdb, scripté pour faire un “thread all apply bt” sur SIGSEGV
  3. Acceptez le fait que vous n’obtenez pas un fichier de base et que vous ayez acquis une trace de stack dans l’application. L’article de Stack Backtracing Inside Your Program est assez ancien, mais il devrait être possible ces jours-ci.

Vous pouvez également modifier le fichier ulimit () depuis votre programme avec setrlimit (2). Comme pour la commande shell ulimit, cela peut réduire les limites ou les augmenter autant que le permet la limite ssortingcte. Au démarrage, setrlimit () pour permettre le dumping de base, et vous allez bien.

Je suppose que vous avez un gestionnaire de signal qui attrape SEGV, par exemple, et fait quelque chose comme imprimer un message et appeler _exit (). (Sinon, vous auriez un fichier de base en premier lieu!) Vous pourriez faire quelque chose comme ceci.

 void my_handler(int sig) { ... if (wantCore_ && !fork()) { setrlimit(...); // ulimit -Sc unlimited sigset(sig, SIG_DFL); // reset default handler raise(sig); // doesn't return, generates a core file } _exit(1); } 

système (“kill -6”)

Je vais essayer si vous cherchez toujours quelque chose

utilisez backtrace et backtrace_symbols les appels glibc pour obtenir la trace, gardez simplement à l’esprit que backtrace_symbols utilise malloc en interne et qu’en cas de corruption du tas, il risque d’échouer.