Caused by abnormal code compiler option

1. Problem

Recently when calling darknet dynamic library, I encountered a strange question, the library's contents can not be heard inside, but the printed results are normal in the library, after careful investigation found that this is because of what we call libdarknet.a when compiling a file does not add -DGPU options, resulting in an offset due to address appears.

2. Examples

In order to express more clearly, to write a simple code to restore the problem.

fun.h, reads as follows:

#include <iostream>
void get_res(struct RESULT *res_);
struct RESULT
{
    float *res;
#ifdef GPU
    float *res_gpu;
#endif
    int n;
    int c;
    int h;
    int w;
};

fun.cpp, the main function is to give the members of the body structure assignment:

#include "fun.h"
void get_res(RESULT *res_)
{
    res_->res = (float*)malloc(10 * sizeof(float));
    for (int i = 0; i < 10; i++)
    {
        rs_->res[i] = i;
    }
    res_->n = 1;
    res_->c = 2;
    res_->h = 3;
    res_->w = 4;
}

Compile a dynamic library
g++ -fPIC -shared -g -DGPU -o libfun.so fun.cpp

Write call dynamic library code:

#include "fun.h"

int main(int argc, char **argv)
{
    struct RESULT *result = (struct RESULT*)malloc(sizeof(struct RESULT));
    get_res(result);
    std::cout << "n:" << result->n << std::endl;
    std::cout << "c:" << result->c << std::endl;
    std::cout << "h:" << result->h << std::endl;
    std::cout << "w:" << result->w << std::endl;
    return 0;
}

First test code compiled using -DGPU options: g++ main.cpp -g -Ilib -Llib -lfun -Wl,-rpath lib -DGPU -o main
look at the results:

./main
n:1
c:2
h:3
w:4

Consistent output and expectations.

Next, remove the compiler option -DGPU:g++ main.cpp -g -Ilib -Llib -lfun -Wl,-rpath lib -o main

./main
n:0
c:0
h:1
w:2

Is clearly wrong, a closer look at the results seemingly h was originally part of n, w and the result was originally belonging to c, the fundamental reason is due to address -DGPU offset caused. The following debug the code to verify our conjecture.

gdb ./main
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 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".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./main...done.
(gdb) b 6
Breakpoint 1 at 0x400a14: file main.cpp, line 6.
(gdb) r
Starting program: /home/gcs/work/study/diy_cnn/code/compile_opt/main

Breakpoint 1, main (argc=1, argv=0x7fffffffe398) at main.cpp:6
6       get_res(result);
(gdb) p &result->n
$1 = (int *) 0x613c28
(gdb) p &result->c
$2 = (int *) 0x613c2c
(gdb) p &result->h
$3 = (int *) 0x613c30
(gdb) p &result->w
$4 = (int *) 0x613c34
(gdb) s
get_res (res_=0x613c20) at fun.cpp:5
5       res_->res = (float*)malloc(10 * sizeof(float));
(gdb) p &res_->n
$5 = (int *) 0x613c30
(gdb) p &res_->c
$6 = (int *) 0x613c34
(gdb) p &res_->h
$7 = (int *) 0x613c38
(gdb) p &res_->w
$8 = (int *) 0x613c3c
(gdb)

From our print out the address can be found before entering .so, n, c, h, w corresponding to the addresses are

n:0x613c28
c:0x613c2c
h:0x613c30
w:0x613c34

After entering the .so, n, c, h, w address becomes:

n:0x613c30
c:0x613c34
h:0x613c38
w:0x613c3c

After printing the additional address information in association with the structure

Before entering the library function result variable at the following address:

result------------------0x613c20
struct RESULT
{
    float *res;---------0x613c20
#ifdef GPU
    float *res_gpu;-----由于编译选项里没有定义,所以该变量无地址
#endif
    int n;--------------0x613c28
    int c;--------------0x613c2c
    int h;--------------0x613c30
    int w;--------------0x613c34
};

res_ variable address after entering the library functions as follows:

res_--------------------0x613c20
struct RESULT
{
    float *res;---------0x613c20
#ifdef GPU
    float *res_gpu;-----0x613c28
#endif
    int n;--------------0x613c30
    int c;--------------0x613c34
    int h;--------------0x613c38
    int w;--------------0x613c3c
};

After the address by contrast, is already evident, when we tried to get the value of n, that is, where the use value 0x613c28 address, simply do not find the address assignment in a dynamic library, so naturally acquired and the expected results are not the same, c is the same reason, look h, when we obtain the value h in a dynamic library outside, i.e. when 0x613c30 address, which can be seen in the dynamic link library corresponding to the value of n, the above results coincide.

3. Summary

  • When we call the library functions, we found abnormal results, to consider whether it is caused by code option.
  • When we write library, try not to put pieces of compiler options structure using conditional compilation in the implementation file.
  • Header files used to call the library functions and header files compiled version of the library has been kept to avoid database upgrade results in the header file structure changes, resulting in an address offset.

Guess you like

Origin www.cnblogs.com/ganchunsheng/p/11781184.html