Erreur de segmentation avec ulimit défini correctement

J’ai essayé d’aider un PO sur cette question .

J’ai découvert qu’un code comme celui ci-dessous provoque une erreur de segmentation de manière aléatoire, même si la stack est définie sur 2000 Ko

int main () { int a[510000]; a[509999] = 1; printf("%d", a[509999]); return 0; } 

Comme vous pouvez le constater, le tableau correspond à 510000 x 4 octets = 2040000 octets.

La stack est définie sur 2000 Ko (2048000 octets) à l’aide de la commande ulimit:

  • ulimit -s 2000
  • ulimit -Ss 2000

Sur la base de ces chiffres, l’application peut stocker le tableau, mais renvoie au hasard une erreur de segmentation.

Des idées?

Il y a plusieurs raisons pour lesquelles vous ne pouvez pas faire cela. Il y a des choses qui utilisent déjà des parties de votre stack.

main n’est pas la première chose sur votre stack. Il y a des fonctions appelées par le point d’entrée réel, l’éditeur de liens dynamic, etc. qui sont avant main et qui utilisent probablement toutes une partie de la stack.

De plus, il peut y avoir des choses qui sont généralement placées en haut de la stack pour configurer l’exécution. De nombreux systèmes que je connais ont placé toutes les chaînes dans argv et toutes les variables d’environnement au-dessus de la stack (raison pour laquelle main n’est pas le point d’entrée, il existe en général un code qui s’exécute avant main qui définit les variables d’environnement et argv).

Et pour couronner le tout, une partie de la stack peut être délibérément gaspillée pour augmenter le caractère aléatoire de ASLR si votre système le fait.

Exécutez votre programme dans le débogueur, ajoutez un point d’arrêt au niveau de main, recherchez la valeur du registre de stack et examinez la mémoire située au-dessus de celui-ci (rappelez-vous que votre stack grandira probablement, sauf si vous êtes sur une architecture étrange). Je parie que vous y trouverez beaucoup de pointeurs et de chaînes. Je viens de faire cela sur un système Linux et comme je le soupçonnais, toutes mes variables d’environnement étaient présentes.

Le but des limites de ressources (ulimit) sur Unix n’a jamais vraiment été de microgérer un octet / microseconde, elles sont simplement là pour empêcher votre programme de devenir complètement fou et de détruire tout le système avec. Ne les voyez pas comme des feux rouges et des panneaux d’arrêt sur une route appropriée, mais plutôt comme des zones de ruissellement et des glissières de sécurité sur une piste de course.

Si vous voulez toujours accéder à la position int dans le tableau, essayez de comstackr le code avec le nom principal .. ceci n’appellera pas _start

vérifier cette discussion entrer la description du lien ici