Click here to Skip to main content
15,883,921 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
VB
binary file need recompiled while the c++ classs shared lib members changed?



C#
//test.h
#pragma once

#include <string>

class test_t
{
public:
        test_t() {m_xxxx=0;}
        int get_xxxx(int count);
public:
        int m_xxxx;
        int m_aaa;
        //std::string m_str;
};


//test.cpp
#include "test.h"
#include <string.h>


int test_t::get_xxxx(int count)
{
        m_xxxx += count;
        //m_str = "ddd"
        return m_xxxx;
}


#include "test.h"
#include <stdio.h>


int main(int argc,char* argv[])
{
        test_t test;
        int count = test.get_xxxx(10);
        printf ("%d \n",count);
        return 0;
}

1)compile the share lib and test binary
<pre lang="vb">
g++ -m32 -fPIC -g -o test.o -c test.cpp
g++ -g -m32 -shared -o libtest.so test.o
g++ -m32 -o main.o -c main.cpp
g++ -m32 -o test main.o -L./ -ltest

2)
add shared lib path to env,just run fine

3) now uncomment 
//std::string m_str in test.h
and
//m_str = ddd in test.cpp

4)only recomplie the shared lib
g++ -m32 -fPIC -g -o test.o -c test.cpp
g++ -g -m32 -shared -o libtest.so test.o

5)run test
coredump !!!

after recompile test,works find.


I try to use 
a)
int m_aaa instead of m_str, and m_aaa=1000
test runs ok,
b)
use static 
static std::string m_str;
also works,

so my questions:
1)what cause the test coredump?
2)when shoud my binary need recompiled?
3)add a std::string member of class will change GOT and PLT of shared lib,this related to th coredump? why?
Posted
Updated 7-Jan-15 3:25am
v3

Whenever you change the interface to a class (yep, adding/removing a data member is changing the interface) you have to rebuild all clients of the class. The reason for this is that the client allocates the memory for the object while the shared library writes stuff into that memory.

So adding a string to a class means that the size of objects of that class increases by the size of a string. On the platforms I use std::string has a size of 16 bytes. When the client code creates an object it's only seen the old definition of the object and reserves too little memory on the stack for the object. The code in the shared library is called to initialise the object and assumes that the object is 16 bytes bigger than it is and ends up scribbling over memory it doesn't own - and the program crashes messily.

So whenever you change a class's interface make sure you recompile anything that needs to know the interface of the class. If you want to be able to independently change a class's implementation in a shared library you'll have to use something like an abstract base class or the PIMPL idiom.
 
Share this answer
 
thanks Aescleal

i add some code my test and finger out your point,

XML
#include "test.h"
#include <string.h>
#include <stdio.h>


int test_t::get_xxxx(int count)
{
        printf("in class:%p class size %d\n",this,sizeof(*this));
        //printf("%p %d\n",&m_str,sizeof(m_str));
        m_xxxx += count;
        //m_str = "ddd";
        return m_xxxx;
}


#include "test.h"
#include <stdio.h>


int main(int argc,char* argv[])
{
        test_t test;
        printf("in main:%p %d\n",&test,sizeof(test_t));
        int count = test.get_xxxx(10);
        printf ("%d \n",count);
        return 0;
}




fist output:
VB
in main:0xff896a74 8
in class:0xff896a74 class size 8
10


while adding m_str code and only recompiled shared lib,output:
VB
in main:0xfff2f2d4 8
in class:0xfff2f2d4 class size 12
<big>0xfff2f2dc</big> 4
Segmentation fault


m_str is addr exceed test_t
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900