LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Step-thru debugging an opensource project. (https://www.linuxquestions.org/questions/programming-9/step-thru-debugging-an-opensource-project-4175437716/)

cov 11-18-2012 03:51 PM

Step-thru debugging an opensource project.
 
I'm interested in stepping through an opensource project but am not sure how to do it.

The project is LibreDwg

I have installed Eclipse, Netbeans and Data Display debugger but cannot seem to get any of them to step through the source.

The source files are in a subdirectory called 'src'.

There is a directory called "examples" which has a number of c source files. Theses files have a "main" function which calls the source files in the "src' directory. One such is called "test" which takes as an argument the file name of a drawing file. I can run "./test example.dwg" from the command line.

How do I get the debugger to run the executable and pass it the path to the drawing file?

Netbeans appears to need an executable to be selected but "test" does not appear in the "Browse Executable" selection dialog which lists "Elf Executable Files".

Eclipse says "Launch failed. Binary not found."

DDD (Data Display Debugger) needs for a Program to be opened but does not show any any of the files in the examples directory as Executables.

If anyone has any suggestions, they would be appreciated.

Sergei Steshenko 11-18-2012 06:46 PM

Quote:

Originally Posted by cov (Post 4832199)
...
If anyone has any suggestions, they would be appreciated.

https://duckduckgo.com/?q=gcc+-g+switch+debugging

cov 11-18-2012 10:27 PM

As suggestions go, I find that one highly insulting.

You think I haven't googled extensively?

I have mentioned 3 applications that I have used to try to solve this, do you really think that I wouldn't have bothered to find out how to use them before posting a question on here?

Moreover, the link you provide is a collection of 404s and man pages, none of which appears to be relevant.

If you are trying to suggest that I use the -g switch when compiling why don't you say so, rather than be sarcastic? I have compiled using ./configure CFLAGS=-g which I believe is the equivalent.

cov 11-18-2012 11:30 PM

I have tried to compile the test.c from the command line as obliquely alluded to by Mr. Steshenko using:
Code:

gcc -g -Wall test.c -o test
in the hope that this might produce an executable which may be recognised by a step-through debugger, but this generates more problems, namely that the functions referenced in test.c are defined in ../src/ so I get an error "undefined reference to `dwg_read_file'".

Using the normal method when one compiles using the ./configure && make method, the Make file will define where these library functions are located. How do I do this from the command line?

Google turns up the technique to add standard library functions using the -l switch, but I can't see any way to show the compiler that the referenced function is in a C code file in the ../src/ directory.

firstfire 11-18-2012 11:32 PM

Hi.

I do not use Eclipse, Netbeans or DDD, so I can't suggest anything about them. But here is how to run simple test program within GDB.

First, compile the library as suggested by README file.
Code:

$ sh autogen.sh
$ ./configure --enable-trace
$ make

Now we have a compiled library in src/.libs directory. There are static (*.a) and dynamic (*.so) versions. To debug the library we need a test program, for example examples/test.c. To compile it with the static version of the library:
Code:

$ cd examples
$ gcc -static -g  test.c -I ../src/ -L../src/.libs -lredwg

Note that it may be enough to run
Code:

$ gcc -static -g  test.c -lredwg
(-static is optional) if you already installed the library (with sudo make install).

Now launch the debugger and run test program with example.dwg as an argument:
Code:

$ gdb ./a.out
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /tmp/libredwg/examples/a.out...done.
(gdb) break main
Breakpoint 1 at 0x4012de: file test.c, line 31.
(gdb) run example.dwg
Starting program: /tmp/libredwg/examples/a.out example.dwg

Breakpoint 1, main (argc=2, argv=0x7fffffffe098) at test.c:31
31        REQUIRE_INPUT_FILE_ARG (argc);
(gdb) list
26      test_dwg_c(char *filename);
27
28      int
29      main(int argc, char *argv[])
30      {
31        REQUIRE_INPUT_FILE_ARG (argc);
32        return test_dwg_c (argv[1]);
33      }
34
35      int
(gdb) step
32        return test_dwg_c (argv[1]);
(gdb)
test_dwg_c (filename=0x7fffffffe3c9 "example.dwg") at test.c:37
37      {
(gdb) l
32        return test_dwg_c (argv[1]);
33      }
34
35      int
36      test_dwg_c(char *filename)
37      {
38        int error;
39        Dwg_Data dwg_struct;
40
41        error = dwg_read_file(filename, &dwg_struct);
(gdb) s
41        error = dwg_read_file(filename, &dwg_struct);
(gdb)
dwg_read_file (filename=0x7fffffffe3c9 "example.dwg", dwg_data=0x7fffffffd460) at dwg.c:39
39      {
(gdb)
46        if (stat(filename, &attrib))
(gdb) next
49            return -1;
(gdb)
46        if (stat(filename, &attrib))
(gdb)
51        if (!S_ISREG (attrib.st_mode))
(gdb)
56        fp = fopen(filename, "rb");
(gdb)
57        if (!fp)
(gdb)
56        fp = fopen(filename, "rb");

That is it. DDD is a graphical frontend to GDB so you may use the same commands.

cov 11-18-2012 11:38 PM

Thank you!

I'll try that!

cov 11-23-2012 08:46 AM

Works a treat!

However, I'm not getting the results I'm expecting and I'd be interested to hear any reasons why.

I'm trying to step through this code:

Code:

419 decompress_r2007(char *dst, int dst_size, char *src, int src_size)
420 {
421  uint32_t length = 0;
422  uint32_t offset = 0;
423 
424  char *dst_end = dst + dst_size;
425  char *src_end = src + src_size;
426 
427  unsigned char opcode = *src++;// opcode=0x20
 
428  if ((opcode & 0xf0) == 0x20)
429    {
430      src += 2;
431      length = *src++ & 0x07;// length=2
432   
433      if (length == 0)
434        return 1; 
435    }
...
...

I set the breakpoint: break decode_r2007.c:419
when I run the program it stops at 420. I'd expect it to stop at 419, but it's no train smash.

Code:

gdb ./a.out
GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/dave/Documents/Projects/Programs/workspace/libredwg/examples/a.out...done.
(gdb) break decode_r2007.c:419
Breakpoint 1 at 0x42f61f: file decode_r2007.c, line 419.
(gdb) run 4m2.dwg
Starting program: /home/dave/Documents/Projects/Programs/workspace/libredwg/examples/a.out 4m2.dwg

Breakpoint 1, decompress_r2007 (dst=0x7fffffffd960 "", dst_size=272,
    src=0x7096b0 " ", src_size=166) at decode_r2007.c:420
420          uint32_t offset = 0;
(gdb)

I'm interested in getting the contents of the array src, which, I know is [32,0,0,2,0,112,96,3,10,27,128,...]

I confirm this:
Code:

(gdb) print src[0]
$1 = 32 ' '
(gdb) print src[1]
$2 = 0 '\000'
(gdb) print src[2]
$3 = 0 '\000'
(gdb) print src[3]
$4 = 2 '\002'
(gdb) print src[4]
$5 = 0 '\000'
(gdb) print src[5]
$6 = 112 'p'
(gdb)

Then I step through:
Code:

(gdb) step
422          char *dst_end = dst + dst_size;
(gdb)
424         
(gdb)
425          unsigned char opcode = *src++;// opcode=0x20
(gdb)

Right, so 'opcode' should be 32, which it is. However, I'm expecting src[0]==0 after *src++.

Code:

(gdb) print opcode
$7 = 32 ' '
(gdb) print src[0]
$8 = 2 '\002'
(gdb) print src[1]
$9 = 0 '\000'
(gdb) print src[2]
$10 = 112 'p'
(gdb) print src[3]
$11 = 96 '`'
(gdb)

Instead of simply incrementing src, it appears to have incremented it 3 times.

What am I doing wrong?

cov 11-23-2012 10:59 AM

Additionally, the debugger doesn't step through in a way that makes sense.

For example the following trace steps into 420->422->424->425->428->425->427->425->427->431->433->436->439

Code:

(gdb) run 4m2.dwg
Starting program: /home/dave/Documents/Projects/Programs/workspace/libredwg/examples/a.out 4m2.dwg

Breakpoint 1, decompress_r2007 (dst=0x7fffffffd960 "", dst_size=272,
    src=0x7096b0 " ", src_size=166) at decode_r2007.c:420
420          uint32_t offset = 0;
(gdb) step
422          char *dst_end = dst + dst_size;
(gdb)
424         
(gdb)
425          unsigned char opcode = *src++;// opcode=0x20
(gdb)
428            {
(gdb)
425          unsigned char opcode = *src++;// opcode=0x20
(gdb)
427          if ((opcode & 0xf0) == 0x20)
(gdb)
425          unsigned char opcode = *src++;// opcode=0x20
(gdb)
427          if ((opcode & 0xf0) == 0x20)
(gdb)
431           
(gdb)
433                return 1; 
(gdb)
436          while (src < src_end)
(gdb)
439                      length = read_literal_length((unsigned char**)&src, opcode);
(gdb) print length
$1 = 2
(gdb)

I'd expect it to go 419-420-421-422-423-424-425-426-427-428-429-430-431-432-434-435-436-437-438-439.

ie. I wouldn't expect it to keep going back to line 425 and I wouldn't expect it to line 433 which would return it.

However, the 'length'==2 which is what I expected.

Sergei Steshenko 11-23-2012 11:28 AM

Quote:

Originally Posted by cov (Post 4835576)
Additionally, the debugger doesn't step through in a way that makes sense.

For example the following trace steps into 420->422->424->425->428->425->427->425->427->431->433->436->439

Code:

(gdb) run 4m2.dwg
Starting program: /home/dave/Documents/Projects/Programs/workspace/libredwg/examples/a.out 4m2.dwg

Breakpoint 1, decompress_r2007 (dst=0x7fffffffd960 "", dst_size=272,
    src=0x7096b0 " ", src_size=166) at decode_r2007.c:420
420          uint32_t offset = 0;
(gdb) step
422          char *dst_end = dst + dst_size;
(gdb)
424         
(gdb)
425          unsigned char opcode = *src++;// opcode=0x20
(gdb)
428            {
(gdb)
425          unsigned char opcode = *src++;// opcode=0x20
(gdb)
427          if ((opcode & 0xf0) == 0x20)
(gdb)
425          unsigned char opcode = *src++;// opcode=0x20
(gdb)
427          if ((opcode & 0xf0) == 0x20)
(gdb)
431           
(gdb)
433                return 1; 
(gdb)
436          while (src < src_end)
(gdb)
439                      length = read_literal_length((unsigned char**)&src, opcode);
(gdb) print length
$1 = 2
(gdb)

I'd expect it to go 419-420-421-422-423-424-425-426-427-428-429-430-431-432-434-435-436-437-438-439.

ie. I wouldn't expect it to keep going back to line 425 and I wouldn't expect it to line 433 which would return it.

However, the 'length'==2 which is what I expected.

With optimization only order of calls to non-inline functions is guaranteed.

Order of statements is not guaranteed, as well as presence of non-static variables. Regarding the latter I mean the following example:

Code:

int i = 1;
int j = 2 + i; // 'i' is not used anywhere else

- compiler most likely will optimize 'i' out, i.e. it will simply implement

Code:

int j = 3;
.

cov 11-23-2012 11:38 AM

Ok, thank you, I understand that.

Sergei Steshenko 11-23-2012 11:49 AM

...

Sergei Steshenko 11-23-2012 09:06 PM

Quote:

Originally Posted by cov (Post 4835610)
Ok, thank you, I understand that.

Once I wrote (for learning purposes) a tool (script) which unrolls all loops in FFT and does other optimizations.

One of the versions of the tool did it right from the point of view of final result, but sub-optimally from the point of view of generated code - there were too many occasions of the same expression calculated twice.

Surprisingly, 'gcc' optimized out about 40% of lines (!).

I wasn't running a debugger, I was looking at assembly listing with source code as comments (see, for example, http://www.fclose.com/b/programming/...ing-using-gcc/ ). Assembly listing with source code as comments should be the source of your expectations regarding stepping through code.


All times are GMT -5. The time now is 01:06 AM.