web-dev-qa-db-fra.com

Comment déboguer 'Détraction de pile détectée'?

J'ai un code c ++ complexe.

C'est un programme FastCGI, utilisant http://althenia.net/fcgicc

Quand je lui demande une URL looooong, je reçois

*** stack smashing detected ***: ./tileserve terminated
Erreur de segmentation

Pour la vraie vie, ce n'est pas un problème car je n'utilise jamais des URL aussi longues, mais cela signifie que n'importe qui peut mettre fin à mon serveur ... Je n'aime pas ça.

Existe-t-il un outil (et comment l'utiliser?) Pour savoir où le problème apparaît?

EDIT: RESOLU

Ok résolu.

Je faisais

int len;
char uri[200];

len = strlen(request.params[std::string("REQUEST_URI")].c_str());
printf("%d\n", len);

if (len > 200) return 1;

strcpy(uri, request.params[std::string("REQUEST_URI")].c_str());

On dirait que 200 était trop haut pour le test len. Il échoue en fait à 194.

J'ai donc fait:

if (len > 190) return 1;

Maintenant ça va.

19
user1219721

Si vous lisez le site Web, vous vous rendrez compte qu'il s'agit d'un simple wrapper C++ sur une bibliothèque C.

Un problème typique avec la bibliothèque C sont les dépassements de tampon:

#include <cstring>
#include <cstdio>

int main(int argc, char* argv[]) {
  char buffer[16]; // ought to be sufficient

  strcpy(buffer, argv[1]);
  printf("%s", buffer);
}

Essayez ce programme:

> ./test "a"
a
> ./test "abcdefghijklmnoprqstuvwxyz"
???

Étant donné que le tampon ne peut contenir que 16 caractères, les caractères restants seront écrits après sa fin. Il s'agit d'un écrasement de pile , et comportement indéfini.

Un certain nombre d'implémentations de la bibliothèque d'exécution ou de votre système d'exploitation peuvent détecter cette situation dans certaines conditions et terminer le programme.

Soit vous faites quelque chose de mal ou la bibliothèque l'est.

Pour localiser le problème, vous pouvez utiliser Valgrind ou exécuter votre programme dans un débogueur. Alternativement, si votre système le permet, vous pourriez avoir un vidage de mémoire au moment où le programme a été tué. Vous pouvez également afficher ce vidage de mémoire dans un débogueur.

17
Matthieu M.

Vous pouvez utiliser quelque chose comme valgrind, ou votre compilateur peut avoir une analyse statique qui peut trouver des endroits où vous pourriez dépasser les tampons.

Vous pouvez également simplement auditer votre code pour des utilisations de fonctions sujettes aux erreurs comme strcpy et les remplacer par des fonctions sûres comme strncpy, ou mieux encore utiliser simplement des objets qui gèrent leur propre mémoire comme std :: string.

1
bames53