Memory Access Errors associated with mesh functions

Hlynkacg

Aspiring rocket scientist
Addon Developer
Tutorial Publisher
Donator
Joined
Dec 27, 2010
Messages
1,870
Reaction score
3
Points
0
Location
San Diego
I've been getting a lot of unhandled exemptions / memory access errors associated with oapiMeshGroupEx, oapiGetMeshGroup, oapiMeshGroupCount, in the latest beta. This is problematic as I'm using these functions a lot in my VC code.

I'm already checking to make sure that the mesh and visual pointers I'm passing the functions are initialized/valid, so I'm wondering what other issues might cause these functions to fail, and if anyone else has had the same problem?
 
Last edited:

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,588
Reaction score
2,312
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
What I remember is really making sure that you make sure that the referred resource in Orbiters core is existing at the time, especially for animations. Its easy to change a mesh and then forget fixing the animations. Or use animations on meshes that are not yet loaded.
 

Hlynkacg

Aspiring rocket scientist
Addon Developer
Tutorial Publisher
Donator
Joined
Dec 27, 2010
Messages
1,870
Reaction score
3
Points
0
Location
San Diego
I have safety checks and have been stepping through with the debugger to make sure that the pointers being passed are initialized and valid.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,588
Reaction score
2,312
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
I have safety checks and have been stepping through with the debugger to make sure that the pointers being passed are initialized and valid.

Don't focus too much on pointers or handles. Indexes are equally easily problem sources.
 

Blake

Addon Developer
Addon Developer
Joined
Mar 9, 2009
Messages
225
Reaction score
104
Points
58
Location
Lehi, Utah
The animation group list address, since it is passed indirectly through the MGROUP structure, has tripped me up more then once if I don't have it nailed down someplace.

Code:
[B]static[/B] UINT apLever[] = { bl::VC::WingsLeverId };
 

Hlynkacg

Aspiring rocket scientist
Addon Developer
Tutorial Publisher
Donator
Joined
Dec 27, 2010
Messages
1,870
Reaction score
3
Points
0
Location
San Diego
Don't focus too much on pointers or handles. Indexes are equally easily problem sources.

So what should I do about it?

I'm trying to build a vessel based on Martins' ComponentVessel framework but I've hit a brick wall because the sim CTDs any time a mesh function is called.


Edit:
For example...

Code:
bool LunarModule::clbkVCRedrawEvent(int id, int event, SURFHANDLE surf)
{
    OBJHANDLE lm = GetHandle();
    VISHANDLE vis = oapiObjectVisualPtr(lm);

    if (vis)
    {
        //sprintf(oapiDebugString(), "Visual Pointer Found %0.1f", oapiGetSimTime());

        [COLOR="Red"]DEVMESHHANDLE devmesh = GetDevMesh(vis, mesh_vc);[/COLOR]
        return ComponentVessel::clbkVCRedrawEvent(id, event, devmesh, surf);
    }

    return false;
}

The highlighted line is the problem. If I comment it out, the sim does not crash. In short how do I debug a core VESSEL function to make sure that it doesn't cause memory errors?
 
Last edited:

jarmonik

Well-known member
Orbiter Contributor
Addon Developer
Beta Tester
Joined
Mar 28, 2008
Messages
2,651
Reaction score
785
Points
128
oapiObjectVisualPtr's API documentation says "Returns a pointer storing the objects visual handle.".

So, would it need to be:
VISHANDLE vis = *oapiObjectVisualPtr(lm);
 

Hielor

Defender of Truth
Donator
Beta Tester
Joined
May 30, 2008
Messages
5,580
Reaction score
2
Points
0
Isn't that the sort of thing that should be caught by the compiler?
 

Lisias

Space Traveller Wanna-be
Joined
May 31, 2015
Messages
346
Reaction score
3
Points
18
Website
www.youtube.com
Isn't that the sort of thing that should be caught by the compiler?

IMHO it should, but it doesn't. C++ is a weakly typed language, i.e., you can make assignments between some different types without being aware. It's somewhat better than ANSI C, however.

(do not misunderstand with statically/dynamic typed languages: C++ is statically typed, once a variable is declared with a type, it remains on that type until the end of the scope)

Problem is that a pointer to void and a pointer to a pointer to void are both pointers, and the compiler happily makes the assignment.

To make a quick test, I typed the following snipped and compiled it with GCC 4.9.3:
Code:
int main(int argc, char** argv)
{
    int i = 0;
    void* x = &i;
    void** y= x;
}

Trying to compile it, I get:
Code:
myboxi:~ lisias$ gcc x.cpp
x.cpp: In function 'int main(int, char**)':
x.cpp:5:15: error: invalid conversion from 'void*' to 'void**' [-fpermissive]
     void** y= x;
               ^

However, using the fpermissive, the code is compiled:

Code:
mybox:~ lisias$ gcc -fpermissive x.cpp
x.cpp: In function 'int main(int, char**)':
x.cpp:5:15: warning: invalid conversion from 'void*' to 'void**' [-fpermissive]
     void** y= x;
               ^

There's a long way since I had read the C++ specs, since there we have C++11 and C++14 that can have fixed some of this mess (or at least, the GCC guys step up to fix themselves) - but you must cope with the specs of the compiler you are using. I'm using VC 2010, so I'm stuck with C++03 and MSVC proprietary extensions.
 

Urwumpe

Not funny anymore
Addon Developer
Donator
Joined
Feb 6, 2008
Messages
37,588
Reaction score
2,312
Points
203
Location
Wolfsburg
Preferred Pronouns
Sire
IMHO it should, but it doesn't. C++ is a weakly typed language, i.e., you can make assignments between some different types without being aware.

I would describe it better: C++ is a strongly typed language if you let it. AFAIR, such an assignment as above should be a error with a very annoying complex error message.

For C++ under x86, most kinds of return value are exchanged by using the same register EAX, so its easy to tolerate such errors because the produced object code would be identical.

But: For a properly configured compiler, X** is different to Y*, even if you used "typedef X* Y;". There is no duck typing in C++.

But yes, because of the wild past of C++, there are always ways to make C++ close both eyes on your source code.
 

Hlynkacg

Aspiring rocket scientist
Addon Developer
Tutorial Publisher
Donator
Joined
Dec 27, 2010
Messages
1,870
Reaction score
3
Points
0
Location
San Diego
...and right now I'm feeling like an idiot, because I completely missed the pointer issue.
 

Lisias

Space Traveller Wanna-be
Joined
May 31, 2015
Messages
346
Reaction score
3
Points
18
Website
www.youtube.com
...and right now I'm feeling like an idiot, because I completely missed the pointer issue.

I completely understands the pointer issue, and I feels like an idiot while compiling my programs the same way. :)

From the ANSI C times, if two data types are equally sized in bits on the compiler definition (ex. char and bool were both 8 bits, and int, enums and pointers were both 16 bits on a old compiler I used to use), you can use them indiscriminately on the same expression without further considerations.

Worst, if you mix 8 bits and 16 bits data on an expression, the compiler will happily "promote" the 8 bits to 16 by adding zeros to the left (or 1s, if the variable is declared as signed and the value is negative - humm... not sure if I'm right, perhaps I'm talking about some other language now...).

We call this mess a "weakly typed" system. The datum are typed, but the type is not strictly enforced.

See that I'm not against mixing data types. Sometimes you really want to add 8 to a pointer in order to access something you know it's 8 bytes after the address on the pointer (it's how structs are implemented down there on the metal, by the way).

What makes things a living hell is this being done automagically by the compíler - so any mistake you do is terribly hard to detect. The guys from that times invented a pre-compiler phase called "lint" in order to get the errors that can be detected statically (i.e., that you don't have to run the program to detect it).

C++ at first introduced Objects to this mess, and things became even messier.

At least things are becoming better with last C++ revisions, as it appears. :)
 
Top