[C] gcc -pg et Solaris

4 réponses
Avatar
JKB
Bonjour à tous

J'essaye d'optimiser un calcul qui tourne durant plusieurs heures.
Pour cela, je cherche à savoir ce qui consomme le plus de temps en
utilisant l'option -pg de gcc. Je me souviens avoir utilisé cette option
sans problème sous Linux dans le passé (et sous Solaris 2.5.1, ça ne
nous rajeûnit pas...).

poincare:[~] > uname -a
SunOS poincare 5.10 Generic_139556-08 i86pc i386 i86pc
poincare:[~] > gcc -v
Utilisation des specs internes.
Target: i386-pc-solaris2.10
Configuré avec: ../gcc-4.3.1/configure -v
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr/local
--enable-shared --enable-threads=posix --disable-multilib
--with-mpfr=/usr/local --with-gmp=/usr/local --with-gnu-as --with-gnu-ld
Modèle de thread: posix
gcc version 4.3.1 (GCC)
poincare:[~] >

Je compile mon programme et j'effectue cette édition des liens avec
-pg. Lorsque je le lance, je n'obtiens qu'une erreur de segmentation.

Core was generated by `rpl -is'.
Program terminated with signal 11, Segmentation fault.
[New process 79302 ]
#0 0x081e9931 in rplinit (argc=0, argv=0x0, resultats=0x0) at rpl.conv.c:438
438 openlog(argv[0], LOG_ODELAY | LOG_PID, LOG_USER);
(gdb)

Forcément... argv étant nul, *argv plante. Sans -pg, le programme
fonctionne parfaitement, d'autant que je ne vois pas pourquoi argv[0] ne
donnerait pas le nom du programme. Je ne trouve rien de probant sur
google (sauf une question datant de 2005 mais restée sans réponse).

Pour information, rplinit est appelé par :

int
main(int argc, char *argv[])
{
return((rplinit(argc, argv, NULL) == EXIT_SUCCESS)
? EXIT_SUCCESS : EXIT_FAILURE);
}

J'ai beau prendre le problème dans tous les sens, je ne vois pas ce
que j'ai encore pu écrire comme bêtise !...

Cordialement,

JKB

PS: Xpost et Fu2

--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.

4 réponses

Avatar
Marc
JKB wrote:

Je compile mon programme et j'effectue cette édition des liens avec
-pg. Lorsque je le lance, je n'obtiens qu'une erreur de segmentation.



Aucune idée pour résoudre ce problème particulier, mais les outils
fournis avec Studio (collect+er_print) doivent fournir des informations
suffisantes sans recompiler avec -pg (il doit quand même falloir utiliser
-g), au besoin.
Avatar
Richard Delorme
JKB a écrit :
Bonjour à tous

J'essaye d'optimiser un calcul qui tourne durant plusieurs heures.
Pour cela, je cherche à savoir ce qui consomme le plus de temps en
utilisant l'option -pg de gcc.



Tu as de l'espoir. A mon avis les résultats donnés par -pg n'ont qu'un
lointain rapport avec la réalité. Des programmes comme sysprof (pour
Linux uniquement) donnent de meilleurs résultats. Je ne sais pas s'il
existe un équivalent sous Solaris.

Je compile mon programme et j'effectue cette édition des liens avec
-pg. Lorsque je le lance, je n'obtiens qu'une erreur de segmentation.

Core was generated by `rpl -is'.
Program terminated with signal 11, Segmentation fault.
[New process 79302 ]
#0 0x081e9931 in rplinit (argc=0, argv=0x0, resultats=0x0) at rpl.conv.c:438
438 openlog(argv[0], LOG_ODELAY | LOG_PID, LOG_USER);
(gdb)

Forcément... argv étant nul, *argv plante. Sans -pg, le programme
fonctionne parfaitement, d'autant que je ne vois pas pourquoi argv[0] ne
donnerait pas le nom du programme. Je ne trouve rien de probant sur
google (sauf une question datant de 2005 mais restée sans réponse).



Ce que dit la norme du langage C :

5.1.2.2.1 Program startup
[...]
2 If they are declared, the parameters to the main function shall obey
the following constraints:
— The value of argc shall be nonnegative.
— argv[argc] shall be a null pointer.
[...]
— If the value of argc is greater than zero, the string pointed to by
argv[0] represents the program name; argv[0][0] shall be the null
character if the program name is not available from the host environment.

A priori, rien n'interdit à argc de valoir zéro. Par contre, comme il
est écrit qu'argv[argc] doit être un pointeur nul, il me semble qu'argv
doit être "déférençable" et donc un pointeur non nul. Par contre, il
n'est pas obligatoire qu'argv[0] donne le nom du programme. Il peut être
un pointeur nul (si argc == 0) ou une chaîne vide.


Pour information, rplinit est appelé par :

int
main(int argc, char *argv[])
{
return((rplinit(argc, argv, NULL) == EXIT_SUCCESS)
? EXIT_SUCCESS : EXIT_FAILURE);
}

J'ai beau prendre le problème dans tous les sens, je ne vois pas ce
que j'ai encore pu écrire comme bêtise !...



Ça peut être un bug qui écrase les piles d'appels, ce qui fait qu'argc,
argv, etc. apparaissent nul, mais ne le sont pas avant le bug. Il
faudrait tester le programme avec un "vérificateur de mémoire" genre
valgrind, où à défaut suivre comment évolue les valeurs d'argc et argv
au cours du programme.

--
Richard
Avatar
JKB
Le 07-06-2009, ? propos de
Re: [C] gcc -pg et Solaris,
Richard Delorme ?crivait dans fr.comp.os.unix :
JKB a écrit :
Bonjour à tous

J'essaye d'optimiser un calcul qui tourne durant plusieurs heures.
Pour cela, je cherche à savoir ce qui consomme le plus de temps en
utilisant l'option -pg de gcc.



Tu as de l'espoir. A mon avis les résultats donnés par -pg n'ont qu'un
lointain rapport avec la réalité. Des programmes comme sysprof (pour
Linux uniquement) donnent de meilleurs résultats. Je ne sais pas s'il
existe un équivalent sous Solaris.



Normalement, je développe sous Solaris, mais bon, ma machine de dev
est en SAV depuis plus d'un mois et je suis contraint à utiliser entre
temps un Solaris 10 des familles... Je garde sysprof sous la main.

Je compile mon programme et j'effectue cette édition des liens avec
-pg. Lorsque je le lance, je n'obtiens qu'une erreur de segmentation.

Core was generated by `rpl -is'.
Program terminated with signal 11, Segmentation fault.
[New process 79302 ]
#0 0x081e9931 in rplinit (argc=0, argv=0x0, resultats=0x0) at rpl.conv.c:438
438 openlog(argv[0], LOG_ODELAY | LOG_PID, LOG_USER);
(gdb)

Forcément... argv étant nul, *argv plante. Sans -pg, le programme
fonctionne parfaitement, d'autant que je ne vois pas pourquoi argv[0] ne
donnerait pas le nom du programme. Je ne trouve rien de probant sur
google (sauf une question datant de 2005 mais restée sans réponse).



Ce que dit la norme du langage C :

5.1.2.2.1 Program startup
[...]
2 If they are declared, the parameters to the main function shall obey
the following constraints:
— The value of argc shall be nonnegative.
— argv[argc] shall be a null pointer.
[...]
— If the value of argc is greater than zero, the string pointed to by
argv[0] represents the program name; argv[0][0] shall be the null
character if the program name is not available from the host environment.

A priori, rien n'interdit à argc de valoir zéro. Par contre, comme il
est écrit qu'argv[argc] doit être un pointeur nul, il me semble qu'argv
doit être "déférençable" et donc un pointeur non nul. Par contre, il
n'est pas obligatoire qu'argv[0] donne le nom du programme. Il peut être
un pointeur nul (si argc == 0) ou une chaîne vide.



C'est exactement ce que je comprends. D'un autre côté, la pratique
me fait dire que argv[0] donne toujours le nom du programme ou "". Bref,
je ne suis pas plus avancé ;-)


Pour information, rplinit est appelé par :

int
main(int argc, char *argv[])
{
return((rplinit(argc, argv, NULL) == EXIT_SUCCESS)
? EXIT_SUCCESS : EXIT_FAILURE);
}

J'ai beau prendre le problème dans tous les sens, je ne vois pas ce
que j'ai encore pu écrire comme bêtise !...



Ça peut être un bug qui écrase les piles d'appels, ce qui fait qu'argc,
argv, etc. apparaissent nul, mais ne le sont pas avant le bug. Il
faudrait tester le programme avec un "vérificateur de mémoire" genre
valgrind, où à défaut suivre comment évolue les valeurs d'argc et argv
au cours du programme.



valgrind n'existe pas sous Solaris, mais je peux essayer de tracer
le truc. Je vais mettre ça dans ma todo list parce qu'entre temps, je
viens encore de trouver un truc bizarre qui se termine par un segfault
(alors que le signal 11 est récupéré par l'application)...

Je hais de plus en plus Solaris ! (cri du coeur ;-) )

Cordialement,

JKB

--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.
Avatar
Gilles
Bonjour,

Honnêtement, je ne peu pas te dire ce qui plante, mais j'ai déjà eu ce genre de problème.
C'est pourquoi en général, j'évite '-pg' et je lui préfère '-p'. En général, '-p' seul à l'édition de liens donne des informations intéressantes du genre temps cumulé passé dans chaque fonction.
En ajoutant '-p' à la compilation aussi, tu as en plus le nombre d'appel et le temps moyen par appel. Si tu ajoute '-g', tu peu alors tenté un profiling par ligne... Mais là, c'est pas gagné que ça marche.

Bon courage.

Gilles


JKB wrote:
Bonjour à tous

J'essaye d'optimiser un calcul qui tourne durant plusieurs heures.
Pour cela, je cherche à savoir ce qui consomme le plus de temps en
utilisant l'option -pg de gcc. Je me souviens avoir utilisé cette option
sans problème sous Linux dans le passé (et sous Solaris 2.5.1, ça ne
nous rajeûnit pas...).

poincare:[~] > uname -a
SunOS poincare 5.10 Generic_139556-08 i86pc i386 i86pc
poincare:[~] > gcc -v
Utilisation des specs internes.
Target: i386-pc-solaris2.10
Configuré avec: ../gcc-4.3.1/configure -v
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr/local
--enable-shared --enable-threads=posix --disable-multilib
--with-mpfr=/usr/local --with-gmp=/usr/local --with-gnu-as --with-gnu-ld
Modèle de thread: posix
gcc version 4.3.1 (GCC)
poincare:[~] >

Je compile mon programme et j'effectue cette édition des liens avec
-pg. Lorsque je le lance, je n'obtiens qu'une erreur de segmentation.

Core was generated by `rpl -is'.
Program terminated with signal 11, Segmentation fault.
[New process 79302 ]
#0 0x081e9931 in rplinit (argc=0, argv=0x0, resultats=0x0) at rpl.conv.c:438
438 openlog(argv[0], LOG_ODELAY | LOG_PID, LOG_USER);
(gdb)

Forcément... argv étant nul, *argv plante. Sans -pg, le programme
fonctionne parfaitement, d'autant que je ne vois pas pourquoi argv[0] ne
donnerait pas le nom du programme. Je ne trouve rien de probant sur
google (sauf une question datant de 2005 mais restée sans réponse).

Pour information, rplinit est appelé par :

int
main(int argc, char *argv[])
{
return((rplinit(argc, argv, NULL) == EXIT_SUCCESS)
? EXIT_SUCCESS : EXIT_FAILURE);
}

J'ai beau prendre le problème dans tous les sens, je ne vois pas ce
que j'ai encore pu écrire comme bêtise !...

Cordialement,

JKB

PS: Xpost et Fu2