• Advertisement
Sign in to follow this  

VC crashes in 'Start without debugging' mode

This topic is 3293 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I usually run w/o debugging, but now the program only seems to run in debugging mode. My code stores large arrays and vectors (the vectors of which I've been hoping to 'delete' since I only need them temporarily, but closest I can get is 'clear'), which are used to store a mesh and its AABB tree. I use an .obj loader which was written in C along with the code I'm trying to run written in C++ (shouldn't pose a problem?). I'd thought the program was crashing because of a memory shortage, but it runs fine in debugging mode. Checked for leaks too, none found. Also, when I use 'printf' to try to find out where the problem lies, it runs without crashing. Any of this info raise any red flags?

Share this post


Link to post
Share on other sites
Advertisement
This would be a good time to investigate as to what running in debug mode actually does. I cannot say for certain, but a big offender is uninitialised variables. In debug mode all variables are initialised (usually with particular bit patterns that have meaning). It just might happen that the bit pattern one of your variables is set to works, but when your run without the debugger there no longer is that pattern.

Mixing C and C++ typically works fine. There are subtle differences sometimes but these are relatively rare in practise.

Share this post


Link to post
Share on other sites
Thanks for the quick reply.
The biggest puzzler for me is why a 'printf' statement would allow the program to run fine. I've checked all my variables and they seem to be initialized, else a warning would have come up anyway. Any links to what the debug mode does differently?

Share this post


Link to post
Share on other sites
Quote:
Original post by Demolit
I've checked all my variables and they seem to be initialized, else a warning would have come up anyway.
Not necessarily. A compiler can not prove that a variable is initialised before it is used, in every case. So unless it gives you false positives it wont necessarily be giving a warning in every case.

Anyway, the only two possibilities I've ever heard of are uninitialised variables, and different paths leading to files not being found. Check the results of attempts to open files.

Share this post


Link to post
Share on other sites
It seems to be the latter of what iMalc mentioned, but I'm not sure what to do about it. fclose seems to be messing up the memory, arrays created after it don't get initialized. Should I just not close the file? I'm definitely not accessing the file again after closing it, it's merely in a function which opens a file and reads the data into a struct.
And as usual, calling 'printf' or 'fprintf(stderr)', or even std::cout, before opening the second file allows the program to run without problems. A stream buffer problem?

Share this post


Link to post
Share on other sites
Something else, since no one seemed to mention it, that would be worth looking into is the compiler settings itself. When you mess with the linker settings in visual studio (for instance, to change between multithreaded and single threaded libraries) it only effects the current build specifications (unless changed manually to both). by default, in VS at least, you are only changing the settings to the debug build.

There are many many many painful and strange conflicts that can happen when mixing single and multithreaded libraries.

In addition, optimizing compilers sometimes perform certain things like struct alignment that can sometimes cause problems. so you could always mess around with the optimizations, lowering them until it works (if that helps anyways), and then using information about what differenciates that particular optimization technique.

Share this post


Link to post
Share on other sites
I'm afraid I don't mess with the configurations enough to know how those are configured.
These look to be my configurations:
C/C++ optimization is disabled, Linker optimization is default.
Runtime library is multi-threaded debug (no option for single threaded)

Following what you've mentioned, I don't think changing these will affect the outcome.

Share this post


Link to post
Share on other sites
PaulCesar's suggestions might not explain your problem in this case. Assuming of course my interpretation of your description is correct in that it works when you run a debug build normally, but then without recompiling the same debug build subsequently fails to run without the debugger.

Double-check what is passed to fclose is exactly what was obtained from fopen.
Any chance you can post a section of code around where you think the problem is? In particular I'd like to confirm what your description of arrays created after the fclose, that are not being initialised, refers to. Is the file opened in the same function that it is closed from? If so, perhaps posting the whole function would be best, if that is okay.

Oh and of course I just thought I should check that you've tried a rebuild-all[smile].

Share this post


Link to post
Share on other sites
Quote:
Assuming of course my interpretation of your description is correct in that it works when you run a debug build normally, but then without recompiling the same debug build subsequently fails to run without the debugger.

Yes, but even if I recompile it, it still fails without debugger.

Yes I always rebuild-all. Tried a clean then rebuilding, didn't change anything.

Did a few more tests, the problem occurs after using the conversion function.


// This is probably the problem, works fine when I don't use it
template <typename T>
vector<T> convertArrayToVector(T *array, int size)
{
vector<T> newVec;
for(int i=0; i<size; i++)
{
newVec.push_back(array);
}
return newVec;
}

// This function works fine, tested and used several times
// If I chuck a random 'printf' statement here, program runs fine
mesh_t *mesh_load(const char *obj_filename)
{
mesh_t *mesh = mesh_create();
char buf[MAX_LINE_LENGTH];
const char *bufp;
size_t token_len;
int line_number = 0;
const material_t *current_material;
char material_filename[MAX_LINE_LENGTH];
char material_path[MAX_PATH_SIZE];
FILE *file = fopen(obj_filename, "r");
int i;

if(!file)
return NULL;

/* Get the relative path where the mtl file is (it should be in the same
location as the obj file) */

strcpy(material_path, obj_filename);
for(i = (int)strlen(obj_filename); material_path != '\\' &&
material_path != '/' && i >= 0; i--)
{
material_path = '\0';
}

/* Process each line from the OBJ file */
while (fgets(buf, sizeof(buf), file))
{
... // Process object file
}

/* Pad the normals and tex coords arrays to be as large as the vertex
* array. */

pad_vertex_data(&mesh->normals, mesh->vertices.n_vertices);
pad_vertex_data(&mesh->tex_coords, mesh->vertices.n_vertices);

fclose(file); // Had been giving problems
return mesh;
}

int main(int argc, char **argv)
{
... (opengl and glut initialization)

ship.mesh = mesh_load(argv[2]);
vector<triangle_t> ship_tri = convertArrayToVector(
ship.mesh->triangles, ship.mesh->n_triangles);

asteroid.g_mesh = mesh_load(argv[1]);
cout << asteroid.mesh->vertices.vertices[0].x << endl; // Crashes here, doesn't seem to be initialized

glutMainLoop();

return EXIT_SUCCESS;
}

Share this post


Link to post
Share on other sites
Set a break point at the line

cout << asteroid.mesh->vertices.vertices[0].x << endl; // Crashes here, doesn't seem to be initialized

and run it in the debugger. When the break point is hit, hover your mouse over the variables and make sure they are all valid. If they are invalid, then you need to find where in your code you fail to give them valid values. Make sure the array passed to convertArrayToVector really is of length size. Also make sure that the parameters you are giving it when you call it (ship.mesh->triangles and ship.mesh->n_triangles) are valid.

Share this post


Link to post
Share on other sites
That's what I was thinking of doing from the beginning, but as I said, it works fine in the debugger. I'll examine the array sizes a little more.

Share this post


Link to post
Share on other sites
There's a simple way to debug this:

- Put a message box or something at the start of main, to delay the bug (you only need this if the bug normally happens without user interaction).

- Run the program without debugging.

- Connect the debugger to the program (Attach in the Debug menu).

- Press ok on that message box and reproduce the bug.

Share this post


Link to post
Share on other sites
Thanks, that was helpful.
It now tells me this line is giving me an exception:
material_t *material = malloc(sizeof(*material));

The only reason I can think of for such a line causing a crash is a lack of memory, am I right?

Share this post


Link to post
Share on other sites
Lack of memory should make malloc() return NULL. A crash suggests that some of the bookkeeping information that gets stored before and after the memory you've allocated has been corrupted.

I'd start looking for problems between that call to malloc and the previous one, although it could be anywhere before that point. The first thing I'd look for is an uninitialized (or otherwise out of range) variable used for an array index.

Share this post


Link to post
Share on other sites
Sorry, I completely forgot about the idea of attaching the debugger after it's running, though I myself use this all the time.

Yep, okay it sounds like memory corruption. It's possible that you're overrunning an array, but only due to a certain variable being uninitialised and hence having a value greater than zero at times, or something like that.

Incidentally, here's a shorter way of writing one of your functions:
template <typename T>
vector<T> convertArrayToVector(const T *array, int size)
{
vector<T> newVec(size);
std::copy(array, array+size, newVec.begin());
return newVec;
}

You'll find it's slightly faster too due to not having to grow during the push_back operations. I also added the missing 'const'.

Note that you'll probably get a speed increase out of it if your compiler performs NRVO too. That would mean you'd have it running much slower in a debug build. Consider returning the vector as an out parameter instead. Even better would be to have the original data in a vector to begin with, if possible [cool].

Share this post


Link to post
Share on other sites
Oh that's great, thanks :) And yeah I should've put a const there..
Apparently the bug is in my obj loader (which I didn't write), and figured my time's better spent getting another loader..could've written one from scratch, but then there's that 'time better spent' issue again.

About NRVO, I'm using VC++ 2005, I believe it does perform that.
And about having the original data in a vector, I tried that, but reading from the vectors reduced my FPS quite a bit, which was kinda odd..

Again, thanks for the help :)

Share this post


Link to post
Share on other sites
Hi,

I also got the same kind of problem: run well with F5 but not with Clt+F5.
Could you help me know how to : ?

-put a message box to delay the bug (Some lines of code as example is very appreciated)
- connect the debugger to the program (I change the Attach in Debug menu from No to Yes...but it seems there 's nothing special when I press Clt+F5 (start without debugging). Is it the right way ?


Thank you very much for your help!

I tried to follow the advice of Adam as in previous posts (below):

There's a simple way to debug this:

- Put a message box or something at the start of main, to delay the bug (you only need this if the bug normally happens without user interaction).

- Run the program without debugging.

- Connect the debugger to the program (Attach in the Debug menu).

- Press ok on that message box and reproduce the bug.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement