[Rd] C++ debugging help needed
Duncan Murdoch
murdoch.duncan at gmail.com
Wed Oct 2 22:55:31 CEST 2013
On 13-10-02 4:37 PM, Ross Boylan wrote:
> On Wed, 2013-10-02 at 16:15 -0400, Duncan Murdoch wrote:
>> On 02/10/2013 4:01 PM, Ross Boylan wrote:
>>> On Wed, Oct 02, 2013 at 11:05:19AM -0400, Duncan Murdoch wrote:
>>> ....
>>>>> Up to entry #4 this all looks normal. If I go into that stack frame, I
>>>>> see this:
>>>>>
>>>>>
>>>>> (gdb) up
>>>>> #4 Shape::~Shape (this=0x15f8760, __in_chrg=<optimized out>) at
>>>>> Shape.cpp:13
>>>>> warning: Source file is more recent than executable.
>>>
>>> That warning looks suspicious. Are your sure gdb is finding the right
>>> source files, and that the object code has been built from them?
>>
>> I'm pretty sure that's a warning about the fact that igraph also has a
>> file called Shape.cpp, and the Shape::~Shape destructor was in that
>> file, not in my Shape.cpp file.
>
> I guess the notion of the "right" source file is ambiguous in this
> context. Suppose you have projects A and B each defining a function f
> in f.cpp. Use A/f() to mean the binary function defined in project A,
> found in source A/f.cpp.
>
> The you have some code that means to invoke A/f() but gets B/f()
> instead. Probably gdb should associate this with B/f.cpp, but your
> intent was A/f() and A/f.cpp. If gdb happens to find A/f.cpp, and A was
> build after B, that could provoke the warning shown.
>
>>>
>>>>> 13 blended(in_material.isTransparent())
>>>>> (gdb) p this
>>>>> $9 = (Shape * const) 0x15f8760
>>>>> (gdb) p *this
>>>>> $10 = {_vptr.Shape = 0x7ffff2d8e290, mName = 6, mType = {
>>>>> static npos = <optimized out>,
>>>>> _M_dataplus = {<std::allocator<char>> =
>>>>> {<__gnu_cxx::new_allocator<char>> =
>>>>> {<No data fields>}, <No data fields>},
>>>>> _M_p = 0x7f7fffff7f7fffff <Address 0x7f7fffff7f7fffff out of
>>>>> bounds>}},
>>>>> mShapeColor = {mRed = -1.4044474254567505e+306,
>>>>> mGreen = -1.4044477603031902e+306, mBlue = 4.24399170841135e-314,
>>>>> mTransparent = 0}, mSpecularReflectivity = 0.0078125,
>>>>> mSpecularSize = 1065353216, mDiffuseReflectivity = 0.007812501848093234,
>>>>> mAmbientReflectivity = 0}
>>>>>
>>>>> The things displayed in *this are all wrong. Those field names come
>>>>> from the Shape object in the igraph package, not the Shape object in the
>>>>> rgl package. The mixOmics package uses both.
>>>>>
>>>>> My questions:
>>>>>
>>>>> - Has my code somehow got mixed up with the igraph code, so I really do
>>>>> have a call out to igraph's Shape::~Shape instead of rgl's
>>>>> Shape::~Shape, or is this just bad info being given to me by gdb?
>>>>>
>>>
>>> I don't know, but I think it's possible to give fully qualified type
>>> names to gdb to force it to use the right definition. That's assuming
>>> that both Shape's are in different namespaces. If they aren't, that's
>>> likely the problem.
>>
>> Apparently they aren't, even though they are in separately compiled and
>> linked packages. I had been assuming that the fact that rgl knows
>> nothing about igraph meant I didn't need to worry about it. (igraph does
>> list rgl in its "Suggests" list.) On platforms other than Linux, I
>> don't appear to need to worry about it, but Linux happily loads one,
>> then loads the other and links the call to the wrong .so rather than the
>> local one, without a peep of warning, just an eventual crash.
>
> While various OS's and tricks could provide work-arounds for clashing
> function definitions (I actually had the impression the R dynamic
> loading machinery might) those wouldn't necessary be right. In
> principle package A might use some functions defined in package B. In
> that case the need for namespaces would have become obvious.
The issue is that I don't need to import the problematic function from
another library. It is not defined in the same .o file, but it is in
the same .dll/.so. I think the linker should have resolved it, not
left it for later resolution by the loader.
I would expect to have problems if functions like Rprintf() were defined
in multiple places, because I need to import those. But I think it's a
linker bug (or a bad design) in a case where the function is defined in
another .o file being linked into a shared library.
Duncan Murdoch
>
>>
>> Supposing I finish my editing of the 100 or so source files and put all
>> of the rgl stuff in an "rgl" namespace, that still doesn't protect me
>> from what some other developer might do next week, creating their own
>> "rgl" namespace with a clashing name. Why doesn't the linking step
>> resolve the calls, why does it leave it until load time?
>
> I think there is a using namespace directive that might save typing,
> putting everything into that namespace by default. Maybe just the
> headers need it.
>
> With dynamic loading you don't know til load time if you've got a
> problem. As I said, the systemm can't simply wall if different
> libraries, since they may want to call each other.
>
> The usual solution for two developers picking the same name is to have
> an outer level namespace associated with the developer/company/project,
> with other namespaces nested inside. This reduces the problem, though
> obviously it can still exist higher up.
>
> Ross
>>
>>
>>>> - If I really do have calls to the wrong destructor in there, how do I
>>>> avoid this?
>>
>> Are you invoking the destructor explicitly? An object should know
>> it's type, which should result in the right call without much effort.
>>
>>
>> No, this is an implicit destructor call. I'm deleting an object whose
>> class descends from Shape.
>>
>> Duncan Murdoch
>>
>>
>
>
More information about the R-devel
mailing list