Debug Memoirs in LLDB

2

When you start writing programs that are reasonably long, it becomes difficult to look for errors.

At such a time, what becomes necessary is a "debugger".

Maybe I can't do it without it、、??? I think.

It's mostly for my own use, but I'll do a summary of how to use LLDB.

Since it seems to be in the Mac by default, I think that it is not necessary to build an environment in particular.

By the way, if you 、、、、、、 that the behavior is different every time you run the file、、、、、、, or if you can not identify the cause of the bug, you can use Valgrind to know the memory leak in one shot, so please try it. (There are memory commands in LLDB, so maybe LLDB can understand it?) )

The file used as an example this time looks like this

test.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

void dainyu(int aa, int bb);

int main(void)
{
   double a = 3.0 ;
   double b = 5.0 ;
   double c = 7.0 ;

   dainyu(1,2);
   dainyu(2,3);
}
//--------------------------------------------------------
void dainyu(int aa, int bb){
    const int num1 = aa ;
    static int num2 = 0;
    num2 = 0;
    num2 += 2;

    printf("aa(const) :%d, bb(static) : %d \
", num1, num2);
}

It is a program that experiments with the difference between const and static.

By the way, the output is

aa(const) :1, bb(static) : 2 
aa(const) :2, bb(static) : 2 

It comes to. In other words, if left to static, the num2 will continue to hold the value even after the function exits. This means that the static int num2 = 0; is initialized only once, the first time the dainyu() is called.

Preparation

In order to do debugging, you must specify a -g during compilation.

gcc -g test.c

(It's a snake foot, but it is better to put -O3 for optimization and -Wall to give a lot of warnings every time)

launch

Suppose that the previous compilation yields an executable file named test.

To start it, type lldb [実行ファイル] command.

lldb ./test
(lldb) target create "./test"
Current executable set to '/Users/K-eno/Scripts/test' (x86_64).

List of frequently used commands

[Execute]

(lldb) r

Once you do this, you can do it simply.

(lldb) r
Process 18038 launched: '/Users/KeigoEnomoto/Scripts/hydrodynamics/MPS/test' (x86_64)
aa(const) :1, bb(static) : 2 
aa(const) :2, bb(static) : 2 
Process 18038 exited with status = 0 (0x00000000) 

[View Code]

(lldb) l

Every few lines you can see the contents of the test.c code.

Set Breakpoint

Specified on a line

(lldb) b 15
Breakpoint 1: where = test`main + 32 at test.c:15:8, address = 0x0000000100000ec0

Now you can hit the breakpoint on line 15. The b part can be br or breakpoint Then run it and it looks like this.

(lldb) r
Process 18105 launched: '/Users/KeigoEnomoto/Scripts/hydrodynamics/MPS/test' (x86_64)
Process 18105 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100000ec0 test`main at test.c:15:8
   12   int main(void)
   13   {
   14   
-> 15   double a = 3.0 ;
   16   double b = 5.0 ;
   17   double c = 7.0 ;
   18   
Target 0: (test) stopped.

You can stop at line 15.

Also, if you're compiling multiple files, you can specify that if you like b main.c : 20, you hit a breakpoint on line 20 of the main.c file, and so on.

Specified by function name

br set -n [funciton]

Put the function name in the [function].

It looks like this when you actually use it.

(lldb) br set -n dainyu
Breakpoint 1: where = test`dainyu + 14 at test.c:27:22, address = 0x0000000100000f0e
(lldb) r
Process 18177 launched: '/Users/KeigoEnomoto/Scripts/hydrodynamics/MPS/test' (x86_64)
Process 18177 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100000f0e test`dainyu(aa=1, bb=2) at test.c:27:22
   24   }
   25   
   26   void dainyu(int aa, int bb){
-> 27       const int num1 = aa ;
   28       static int num2 = 0;
   29       num2 = 0;
   30       num2 += 2;
Target 0: (test) stopped.

It even contains the first line of the function. If you step through it afterwards, you will see that in this case, the first dainyu(1,2) has a breakpoint.

By the way, you can output all the breakpoints set in the breakpoint list.

[Stepping]

After hitting a breakpoint somewhere s you can hit n (next) to execute step by step. If you do something like s -c , you can specify the number of steps. Other options come up by typing h s.

You can also use c (continue) to run until the next breakpoint (or to the end if you haven't set one).

Show Variables

You can use the frame varuable to display a list of variables and their contents.

(lldb) frame variable

It's actually like this.

(lldb) n
Process 18352 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step over
    frame #0: 0x0000000100000eca test`main at test.c:17:8
   14   
   15   double a = 3.0 ;
   16   double b = 5.0 ;
-> 17   double c = 7.0 ;
   18   
   19   //printf("re : 5.0 , w(3) : %lf , w(7) : %lf ", weight(a,b), weight(c,b));
   20   //printf("a : %lf, b : %lf, c : %lf \
",a,b,c);
Target 0: (test) stopped.
(lldb) frame variable
(double) a = 3
(double) b = 5
(double) c = 0

It is still only executed up to line 16, so 7.0 is not assigned to the c.

You can also look at it by specifying a variable after it.

(lldb) frame variable a
(double) a = 3

  • If you only want to see the contents of a variable po you can also do it using a command.
(lldb) po b
5

  • When you print a structure, use p commands.
(lldb) p *parameters
(simulation_parameters) $6 = {
  DIM = 2
  ParticleDistance = 0.025000000000000001
  FluidDensity = 1000
  KinematicViscosity = 9.9999999999999995E-7
  GRAVITY_SWITCH = 1
  DT = 0.001
  FINISH_TIME = 2
  OUTPUT_INTERVAL = 20
}

(This is a struct that I'm using in a completely different code、、、、)

  • It seems that when looking at the contents of an array, you need to hit a slightly special command.  (Let me know if there are any other good ones、、、)
(lldb) p *(double (*)[10])Pressure
(double [10]) $1 = ([0] = 0, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0, [6] = 0, [7] = 0, [8] = 0, [9] = 0)

With this, you can see 10 values from the beginning of the array called Pressure.

[End]

It can be terminated by q or quit.

afterword

It became very similar to the reference article, so I was worried about whether to make it public, but it was a good note. I'll add useful commands as appropriate.

See also

A next-generation high-performance debugger called LLDB that uses LLDB to debug C

Share:
2
Author by

MPSで流体シミュレーションをやっています

Updated on August 06, 2020