Pourquoi gdb saute de façon imprévisible entre les lignes et imprime des variables comme""?

quelqu'un peut-il expliquer ce comportement de gdb?

900         memset(&new_ckpt_info,'"151900920"',sizeof(CKPT_INFO));
(gdb)
**903         prev_offset   = cp_node->offset;**
(gdb)
**905         m_CPND_CKPTINFO_READ(ckpt_info,(char *)cb->shm_addr.ckpt_addr+sizeof(CKPT_** HDR),i_offset);
(gdb)
**903         prev_offset   = cp_node->offset;**
(gdb)
**905         m_CPND_CKPTINFO_READ(ckpt_info,(char *)cb->shm_addr.ckpt_addr+sizeof(CKPT_ HDR),i_offset);**
(gdb)
**908         bitmap_offset  = client_hdl/32;**
(gdb)
**910         bitmap_value = cpnd_client_bitmap_set(client_hdl%32);**
(gdb)
**908         bitmap_offset  = client_hdl/32;**
(gdb)
**910         bitmap_value = cpnd_client_bitmap_set(client_hdl%32);**
(gdb)
**908         bitmap_offset  = client_hdl/32;**
(gdb)
**910         bitmap_value = cpnd_client_bitmap_set(client_hdl%32);**
(gdb)
913         found = cpnd_find_exact_ckptinfo(cb , &ckpt_info , bitmap_offset , &offset , &prev_offset);
(gdb)
916         if(!found)
(gdb) p found
 = <value optimized out>
(gdb) set found=0
Left operand of assignment is not an lvalue.

pourquoi après avoir exécuté la ligne 903 Il exécute à nouveau la même chose pour 905 908 910?

une Autre chose est found est un bool -type de la variable, alors pourquoi montre de value optimized out ? Je ne suis pas en mesure de définir la valeur de found .

Cela semble être une optimisation du compilateur (dans ce cas, son -O2 ); comment puis-je encore définir la valeur de found ?

81

8 réponses

pour déboguer le code optimisé, apprendre le langage Assemblée/machine.

utilisez le mode TUI GDB. Ma copie de GDB l'active quand je tape le moins et entre. Ensuite, tapez C-x 2 (c'est-à-dire maintenez le contrôle vers le bas et appuyez sur X, relâchez les deux puis appuyez sur 2). Cela le mettra dans split source et l'affichage de démontage. Ensuite, utilisez stepi et nexti pour déplacer une instruction machine à la fois. Utilisez C-x O pour passer entre les fenêtres TUI.

télécharger un PDF à propos du langage machine de votre CPU et des conventions d'appel de fonction. Vous apprendrez rapidement à reconnaître ce qui est fait avec les arguments de fonction et les valeurs de retour.

vous pouvez afficher la valeur d'un registre en utilisant une commande GDB comme p $eax

113
répondu Zan Lynx 2009-08-30 19:56:50

recompiler sans optimisations (- O0 sur gcc).

71
répondu D'Nabre 2009-08-30 20:04:13

Déclarer trouvé comme "volatile". Cela devrait dire au compilateur de ne pas l'optimiser.

volatile int found = 0;
38
répondu BenB 2009-08-28 07:57:03

le compilateur va commencer à faire des choses très intelligentes avec des optimisations activées. Le débogueur affichera le code sautant vers l'avant et vers l'arrière alot en raison de la façon optimisée les variables sont stockées dans les registres. C'est probablement la raison pour laquelle vous ne pouvez pas configurer votre variable (ou dans certains cas voir sa valeur) car elle a été habilement distribuée entre les registres pour la vitesse, plutôt que d'avoir un emplacement de mémoire directe auquel le débogueur peut accéder.

compiler sans optimisations?

11
répondu kjfletch 2009-08-28 07:02:43

typiquement, les valeurs booléennes qui sont utilisées dans les branches immédiatement après qu'elles soient calculées comme ceci ne sont jamais réellement stockées dans les variables. Au lieu de cela, le compilateur branche juste directement les "codes de condition qui ont été établis à partir de la comparaison précédente. Par exemple,

int a = SomeFunction();
bool result = --a >= 0; // use subtraction as example computation
if ( result ) 
{
   foo(); 
}
else
{
   bar();
}
return;

se compile habituellement à quelque chose comme:

call .SomeFunction  ; calls to SomeFunction(), which stores its return value in eax
sub eax, 1 ; subtract 1 from eax and store in eax, set S (sign) flag if result is negative
jl ELSEBLOCK ; GOTO label "ELSEBLOCK" if S flag is set
call .foo ; this is the "if" black, call foo()
j FINISH ; GOTO FINISH; skip over the "else" block
ELSEBLOCK: ; label this location to the assembler
call .bar
FINISH: ; both paths end up here
ret ; return

remarquez que le "bool" n'est jamais stocké nulle part.

5
répondu Crashworks 2009-08-28 08:26:19

Vous ne pouvez pas définir la valeur de trouvé. Déboguer des programmes optimisés en vaut rarement la peine, le compilateur peut réorganiser le code de manière à ce qu'il ne corresponde en aucune façon au code source (autre que de produire le même résultat), ce qui crée de la confusion pour les débogueurs.

4
répondu nos 2009-08-28 07:48:22

lors du débogage de programmes optimisés (ce qui peut être nécessaire si le bogue n'apparaît pas dans les compilations de débogage), vous devez souvent comprendre le compilateur d'assemblage généré.

dans votre cas particulier, la valeur de retour de cpnd_find_exact_ckptinfo sera stockée dans le Registre qui est utilisé sur votre plate-forme pour les valeurs de retour. Sur ix86 , ce serait %eax . Sur x86_64 : %rax , etc. Vous aurez peut-être besoin de google pour "[votre processeur] procédure appelant la convention" si c'est pas de la ci-dessus.

Vous pouvez examiner ce registre dans GDB et vous pouvez le régler. Par exemple: sur ix86 :

(gdb) p $eax
(gdb) set $eax = 0 
4
répondu Employed Russian 2009-08-29 04:19:56

Im utilisant QtCreator avec gdb.

ajouter

QMAKE_CXXFLAGS += -O0
QMAKE_CXXFLAGS -= -O1
QMAKE_CXXFLAGS -= -O2
QMAKE_CXXFLAGS -= -O3

fonctionne bien pour moi

0
répondu Haselnussstrauch 2015-12-23 13:16:25