Pelles C forum

C language => Beginner questions => Topic started by: Hydronium on November 19, 2012, 12:07:51 AM

Title: Is my Pelles C Debugger skipping lines?
Post by: Hydronium on November 19, 2012, 12:07:51 AM
I'm not sure if this has anything to do with a bug or if it's just the way Pelles C is supposed to work. Basically, I'll reach a breakpoint in my code and then use "Step Into" to continue. At a certain line, which are the source of other problems I'm trying to reproduce, my "Step Into" seems to execute "Go/Debug" instead, and all the debugger options become disabled as the program runs infinitely (there is an infinite loop, as this side project involves a Win API window). The screen i create still functions, but I can no longer Stop debugging. Additionally, moving to any other tab that is open (such as the source code) and the moving back to the Debugger tab shows me a blank page. All the views are blank (Auto, Local, Globals, etc).

The breakpoint was placed in a function that only gets called once, before reaching the while(!done) loop where window messages are handled. Is this standard Pelles C behavior? It's making it very difficult to tell what the problem is at the point where it begins running infinitely (and I know there is a problem there, but I don't know what).

I'm sorry if this sounds vague, or if there is a better place for this question. Doing a search for "debugger" only gave me 22 results, and the issue is similar to http://forum.pellesc.de/index.php?topic=2699.msg10200#msg10200 (http://forum.pellesc.de/index.php?topic=2699.msg10200#msg10200) but this was unresolved.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Bitbeisser on November 19, 2012, 03:30:48 AM
It's pretty much impossible to give you a definitive answer as to what your problem is unless we could see the (whole!) source and your project settings...

The most common reason for something like you seem to be describing is either that a breakpoint is placed on a line of source code that isn't reached by the program logic or in case of a project consisting of several source files (and hence object files) with not all of them properly compiled with debug info enabled...

Ralf
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CommonTater on November 19, 2012, 10:46:55 AM
Hydronium...
Ralf is right in that we're going to have to see your sourcecode to know what's going on.

Understand that the debugger is not running your source code line by line.  What's actually happening is that a series of markers are placed in the executable file and as the file runs, the debugger aligns a disiplay of your source code with the current marker in the program...  Thus if your program locks up, so does the IDE.

There are a couple of things you can try... Plase a number of breakpoints  before and after the problem code as well as in it. Now move through your code by clicking the GO button to move from break to break... observe your program's behaviour as you approach the bad spot. 

Another trick I commonly use is to place Beep(500,100); calls at different spots in the problem code... if it beeps I know it's reaching that part of the code... move the Beep along a bit, if it doesn't beep before messing up I know where the problem is.

But be warned... the debugger and various other tricks will help you find the place where it locks up...
figuring out why it locks up is your job. 

 
(Hi Ralf!)
 
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Hydronium on November 19, 2012, 11:23:27 PM
I've uploaded my code on https://github.com/Hydronium/TimeSink. Also, the origin of this problem (before trying to reproduce it with the current modified code) is described in a stack overflow post, if you want a link to that as well.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CommonTater on November 20, 2012, 04:07:05 AM
I've uploaded my code on https://github.com/Hydronium/TimeSink. Also, the origin of this problem (before trying to reproduce it with the current modified code) is described in a stack overflow post, if you want a link to that as well.

In future... go into the POIDE Menu ... Project -> Zip Project Files ... post a message here explaining the problem, where it is, what happens and attach the zip ... we need the Pelles C project files to properly deduce the problem. 

I am not going to chase all over the net to find your source code and then still have to create my own projects to test it.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Hydronium on November 21, 2012, 12:17:56 AM
I wasn't aware you could do that, though in the end I needed to zip up some .bmps for the program to work, so I just did it manually. Plus it makes sense to do it, seeing as you wouldn't know my project settings etc. Sorry.

I've attached the 64bit and 32bit versions. 64bit is the one I'm actually working on, 32bit I made in case you have a 32bit system.

Basically I get to certain API calls and something seems to fail, at which point following API calls will be skipped (and they're from a separate, but similar, .dll).

The first case of this happens inside GetBitmap(), here:
Code: [Select]
      glActiveTexture(GL_TEXTURE0); <---------------------------Problem is here
      glGenTextures(1, &texture);      <---------------------------This and the following calls are skipped entirely to the end of the function
      glBindTexture(GL_TEXTURE_2D, texture);

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

      glTexImage2D(GL_TEXTURE_2D,   /*Type of texture*/
                   0,               /*Level of Detail number*/
                   GL_RGB,          /*Internal format*/
                   bmWidthPx,       /*Width in texels(pixels?)*/
                   bmHeightPx,      /*Height in texels(pixels?)*/
                   0,               /*Border. Must be 0 (probably only for 2D)*/
                   GL_BGR,          /*Format, of the data the texture will be created from*/
                   GL_UNSIGNED_BYTE,/*Data type of the pixel data*/
                   bmBuffer);       /*Pointer to the image data to create the texture from*/

glActiveTexture comes from atio6axx.dll in 64bit (not sure in 32bit because the debugger lists EVERY dll as "untitled", don't know why. I assume it is the same or similar, as it would also be from AMD). The other functions i include afterwards are from OPENGL32.dll. If I comment out the glActiveTexture call, the following calls are called and executed.

This same issue happens here:

Code: [Select]
GLvoid InitGL(GLvoid)
{
      FnLdInit();
      GetBitmap();

      glClearColor(0.0f, 0.0f, 0.0f, 0.0f);           <-------OPENGL32.dll, good.
      glClearDepth(1.0f);                                  <-------OPENGL32.dll, good.
      glEnable(GL_DEPTH_TEST);                     <-------OPENGL32.dll, good.
      glDepthFunc(GL_LEQUAL);                      <-------OPENGL32.dll, good.

      glGenBuffers(1, &positionBufferObject);  <-------atio6axx.dll, BUT it works! positionBufferObject receives a value of 1! (this value is legitimate).
      errort = glGetError();                                <------this runs, and returns 0 (which means it either detected no errors, or it failed. OPENGL32.dll
      glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject);   <----------atio6axx.dll. Stepping into this point causes the debugger to lose control to the window, and I cannot use any more buttons (step Into, Go/Debug, etc). I'm forced to close the tab to quit.
      errort = glGetError();
      glBufferData(GL_ARRAY_BUFFER, sizeof(thing), thing, GL_STATIC_DRAW);
      errort = glGetError();
      glBindBuffer(GL_ARRAY_BUFFER, 0);
      errort = glGetError();

      myProgram = CreateProgram();
}

All this code is a partial re-do of prior code which encountered a similar error, which I meant to debug with this (by scraping off some of the less necessary functions). That issue is outlined here: http://stackoverflow.com/questions/13433071/why-do-i-get-an-access-violation-in-atio6axx-dll-when-calling-glbindbuffer. That is part of the larger, precursor code. The problem is that this re-do does not recreate the exact same error, just a similar one dealing with the same code locations.

The reason I have come here is because I would like to know why the Pelles C debugger acts how it does upon reaching those API calls (the call-skipping and the debugger losing control after Step Into). If you can also assist me with my code issue, that would be nice as well, but not required (I can start a new post for that, and am already attempting to solve it on my own/with stackoverflow). If there's anything else you need from me, let me know. I'll get back to you ASAP, but it seems we're in different time zones (if you're local to this forum's time, as I am not).

Thank you for your assistance so far.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CommonTater on November 21, 2012, 01:15:09 AM
On my system it crashes as soon as it creates the window... If you add WS_VISIBLE to the styles it will crash right on the CreateWindowEX() or if you use your ShowWindow() it crashes there... Because... the hinstance passed into the program at WinMain is different than the one you're getting from GetModuleHandle() in your create window function.

A module's handle is NOT it's instance.  What you should do is store your global hinstance from the one passed in at WinMain() (which will be correct) and dispense with the GetModuleHandle() call, altogether. 

Another aspect of your problem is that you do exhorbitant error checking in some places where it's not really needed, and almost none in places where it is.  For example... you don't check your LoadLibrary() call or any of the GetProcAddress() calls at all but you have about 4 checks right after creating your window (which almost never fails, btw).

Best I can see, the debugger is working fine (Pelles ver 7.00.335), it led me right to the problem with the Instance handles...  The debugger locks up because your program locks up.  It skips lines because your program skips lines... It's tracing what your program does... which is what it's supposed to do.

Hope this helps...
 
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Hydronium on November 21, 2012, 02:30:55 AM
I made the change you suggested regarding hInstance, but I still ran into the same error and my program's function did not change. I'm going to look into why GetModuleHandle(NULL) would return a different handle than the hInstance (and mine was different, like you said), though from what I've read they are used interchangeably and are supposed to be the same. I'll keep the change as you mentioned, since it makes more sense to use a HINSTANCE where it is required instead of using a HMODULE. Did you make the change as well, and come across the problems I mentioned? In the meantime I'm going to re-evaluate the reasons I'm using the WinAPI calls that I use. Maybe I have another mix up somewhere.

Thanks.

Edit: After looking around, it seems that HMODULE and HINSTANCE for a process are supposed to be interchangeable. I'm not disputing that the value of hInstance and the return value of GetModuleHandle(NULL) were different (14000D2D8 for hInstance, 140000000 for GMH), but could you explain why this might be the case? All the places I've looked explain that after 16bit windows, win32 and beyond were created with HINSTANCE and HMODULE pointing to the same place. Do you have any information on this? Do you also have any insight as to why (in my case, apparently not in yours) changing it had no effect on my program?

http://blogs.msdn.com/b/oldnewthing/archive/2004/06/14/155107.aspx
http://cboard.cprogramming.com/windows-programming/70479-getmodulehandle-null-vs-hinstance.html
http://stackoverflow.com/questions/2126657/how-can-i-get-hinstance-from-a-dll

Also, according to http://msdn.microsoft.com/en-us/library/windows/desktop/ms633559%28v=vs.85%29.aspx:

Code: [Select]
hInstance [in]

    Type: HINSTANCE

    A handle to the current instance of the application.

So it turns out that they're both handles.

The ridiculous error checking is the side effect of a) basing my work off a tutorial b) never going back to clean it up because it works. Not necessarily the correct way to do things, I'll admit. Right now the loadlibrary functions work. When they stop working, i'll diagnose why and act.

Also, my program does not crash with/without WS_VISIBLE, with or without fixing GetModuleHandle(NULL). Not sure why yours is crashing yet mine is not.

I'll keep tinkering. Thanks again.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: aardvajk on November 21, 2012, 04:15:48 AM
Consider when you call ShowWindow
Consider what happens when that calls your WndProc with WM_SIZE
Consider glViewport
Consider when you actually give glViewport a value

Then consider this (http://stackoverflow.com/questions/5600735/how-do-i-fix-win7-app-compatibility-shim-with-disableusercallbackexception) as to why the 64-bit version crashed the first time and then never again, and the 32-bit one never crashed at all.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CommonTater on November 21, 2012, 04:57:35 AM
In my experience the only occasion of HInstance that is always correct is the one passed in on WinMain.  I have no explaination why GetModuleHandle is returning different values... but it is.  What I can tell you is that even if they are both handles, there's no reason to assume that two functions using them will return the same handle.

In your place, I would place all of the gl, hdc, etc. initialization steps in a WM_CREATE handler, not in the same function.  That way you can be absolutely sure your system is registering it's class, creating the window, tossing messages and generally active before you start getting fancy.  You actually should register the class and make the main window right in WinMain (which is why the handles are passed to WinMain).  The sequence should be WinMain -> Check mutexes etc -> register your class -> Create your window -> straight into the message tosser.  Everything else should be done via messages...

Similarly, I would place all the close out functions in a WM_CLOSE handler, then call DestroyWindow() after you are sure you've got a clean shutdown.

To not error check a disk operation such as LoadLibrary() is just begging for sporadic unexplained failures.  If that disk read fails, every function address after it will be either null or incorrect, depending on what GetProcAddress() finds. This code is core to your system, it's silly not to trap it.  It might never fail... but the one time it does you will be glad of the error message.

As to why it hangs when creating a window... I dunno.  Perhaps your best bet is to take a short side trip, write a small proggy that successfully creates a window, as described... and then slowly add your stuff to it, one step at a time, testing as you go...





Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CLR on November 21, 2012, 05:30:57 AM
It works for me. I can set a breakpoint, and step into, etc.
However, glActiveTexture comes from ig4icd64.dll in my computer; see attachment.

Title: Re: Is my Pelles C Debugger skipping lines?
Post by: TimoVJL on November 21, 2012, 12:56:41 PM
As aardvajk pointed out, there is an error in InitGL() / FnLdInit() usage.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Hydronium on November 22, 2012, 12:22:16 AM
Consider when you call ShowWindow
Consider what happens when that calls your WndProc with WM_SIZE
Consider glViewport
Consider when you actually give glViewport a value

Then consider this (http://stackoverflow.com/questions/5600735/how-do-i-fix-win7-app-compatibility-shim-with-disableusercallbackexception) as to why the 64-bit version crashed the first time and then never again, and the 32-bit one never crashed at all.

As aardvajk pointed out, there is an error in InitGL() / FnLdInit() usage.

I never thought that ShowWindow would send a WM_SIZE message, and before ever encountering my crashing problem it was never a problem (the glViewport call never failed, that I recall). I've since changed the ordering so that OpenGL functions are properly set up before ShowWindow, just in case. This hasn't changed the nature or effect of my problem, though, since with InitGL happening before the first ShowWindow call it breaks on the atio6axx.dll access violation before it ever reaches ShowWindow. Did I go in the completely wrong direction with what you guys meant though?

As to your last point: my program never crashed up until recently, at which point it repeatedly does. When I tested it in 32bit it does not crash when run (like you said) but upon debugging it still encounters the Access Violation error, in the same way my 64bit one does. Maybe I'm missing the point of your statement; if so, could you clarify? I followed the links and I'll look into creating a manifest; I visited that registry key and saw the same thing from that stackoverflow post, so it is clearly happening.

Thanks.

In my experience the only occasion of HInstance that is always correct is the one passed in on WinMain.  I have no explaination why GetModuleHandle is returning different values... but it is.  What I can tell you is that even if they are both handles, there's no reason to assume that two functions using them will return the same handle.

In your place, I would place all of the gl, hdc, etc. initialization steps in a WM_CREATE handler, not in the same function.  That way you can be absolutely sure your system is registering it's class, creating the window, tossing messages and generally active before you start getting fancy.  You actually should register the class and make the main window right in WinMain (which is why the handles are passed to WinMain).  The sequence should be WinMain -> Check mutexes etc -> register your class -> Create your window -> straight into the message tosser.  Everything else should be done via messages...

Similarly, I would place all the close out functions in a WM_CLOSE handler, then call DestroyWindow() after you are sure you've got a clean shutdown.

To not error check a disk operation such as LoadLibrary() is just begging for sporadic unexplained failures.  If that disk read fails, every function address after it will be either null or incorrect, depending on what GetProcAddress() finds. This code is core to your system, it's silly not to trap it.  It might never fail... but the one time it does you will be glad of the error message.

As to why it hangs when creating a window... I dunno.  Perhaps your best bet is to take a short side trip, write a small proggy that successfully creates a window, as described... and then slowly add your stuff to it, one step at a time, testing as you go...

CreateGLWindow is the first function called, so merely moving all those lines from the function into WinMAIN wouldn't make any noticeable change except to eliminate variable passing. Nevermind, I misread.

I don't error-check GetProcAddress() because it has worked so far, and I can see the value of the PFN when debugging if I need to see if it is null (and I did this extensively while trying to implement it). I have no way of knowing what the true value of it should be, beyond it's name and an offset into the DLL.

According to this (http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212%28v=vs.85%29.aspx) and this (http://msdn.microsoft.com/en-us/library/windows/desktop/dd374386%28v=vs.85%29.aspx) I couldn't see any way of verifying the exact address of any particular function. Either it returns NULL or some address, which may or may not be correct. The wgl ones in particular vary from context to context, which makes it more difficult (unless I misinterpreted what the MSDN said).

Thanks.

It works for me. I can set a breakpoint, and step into, etc.
However, glActiveTexture comes from ig4icd64.dll in my computer; see attachment.


I run Windows 7, 64bit Home edition with a Radeon HD 6850. The atio6axx.dll is AMD(or ATI)'s OpenGL driver. ig4icd64.dll is nVidia's OpenGL driver.

Did you run this without any of the modifications discussed thus far? If so, it would seem that my WinAPI code is not the (biggest) problem.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CLR on November 22, 2012, 01:02:12 AM
Did you run this without any of the modifications discussed thus far?
Yes.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CommonTater on November 22, 2012, 12:26:13 PM
I don't error-check GetProcAddress() because it has worked so far, and I can see the value of the PFN when debugging if I need to see if it is null (and I did this extensively while trying to implement it). I have no way of knowing what the true value of it should be, beyond it's name and an offset into the DLL.

Very simply ... how do you know it worked?
 
If your LoadLibrary() call fails --the library is missing, the paths are wrong, your disk is crapping out, etc.-- all those GetProcAddress() calls are going to fail, returning nulls... and your function is going to return just like everything went perfectly.  What impact do you think that would have on the rest of your program?
 
"It's always worked so far" does not cut it when the code is "mission critical"...
 
Quote
According to this (http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212%28v=vs.85%29.aspx) and this (http://msdn.microsoft.com/en-us/library/windows/desktop/dd374386%28v=vs.85%29.aspx) I couldn't see any way of verifying the exact address of any particular function. Either it returns NULL or some address, which may or may not be correct. The wgl ones in particular vary from context to context, which makes it more difficult (unless I misinterpreted what the MSDN said).

You are looking for total failure...
 
Code: [Select]

if (! LoadLibrary(...))
  ReportFatalError();
 
if (! GetProcAddress(...  ))
  ReportFatalError();

When it cannot fetch the address of the function (for any reason) it returns NULL... signalling failure.  If it returns an address, it will be the correct address.
 
 
Also I am in agreement with the others who are pointing out flaws in your sequence of events... You really have to go at this incrementally... as already suggested, get the window showing up, resizing and closing, first then add the GL stuff in bits and pieces, testing as you go.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Hydronium on November 23, 2012, 12:55:36 AM
This way you can avoid that 64-bit crash:
InitGL() must be before ShowWindow() because ShowWindow() send WM_SIZE message.
If you have WS_VISIBLE flag in windows style, then InitGL() have to be before CreateWindow().
That glViewport() is called from ResizeGLScene().

See my previous post. I moved it and the same error occurred. Also, I don't use WS_VISIBLE, so that part is not important. Thanks for pointing it out though.

I don't error-check GetProcAddress() because it has worked so far, and I can see the value of the PFN when debugging if I need to see if it is null (and I did this extensively while trying to implement it). I have no way of knowing what the true value of it should be, beyond it's name and an offset into the DLL.

Very simply ... how do you know it worked?
 
If your LoadLibrary() call fails --the library is missing, the paths are wrong, your disk is crapping out, etc.-- all those GetProcAddress() calls are going to fail, returning nulls... and your function is going to return just like everything went perfectly.  What impact do you think that would have on the rest of your program?
 
"It's always worked so far" does not cut it when the code is "mission critical"...
 
Quote
According to this (http://msdn.microsoft.com/en-us/library/windows/desktop/ms683212%28v=vs.85%29.aspx) and this (http://msdn.microsoft.com/en-us/library/windows/desktop/dd374386%28v=vs.85%29.aspx) I couldn't see any way of verifying the exact address of any particular function. Either it returns NULL or some address, which may or may not be correct. The wgl ones in particular vary from context to context, which makes it more difficult (unless I misinterpreted what the MSDN said).

You are looking for total failure...
 
Code: [Select]

if (! LoadLibrary(...))
  ReportFatalError();
 
if (! GetProcAddress(...  ))
  ReportFatalError();

When it cannot fetch the address of the function (for any reason) it returns NULL... signalling failure.  If it returns an address, it will be the correct address.
 
 
Also I am in agreement with the others who are pointing out flaws in your sequence of events... You really have to go at this incrementally... as already suggested, get the window showing up, resizing and closing, first then add the GL stuff in bits and pieces, testing as you go.

You're right, I wouldn't know how it worked. Generally, the fact that my window did what I wanted and I saw squares when I drew them was good enough for me, so I didn't bother. I've since fixed that.

I started another project as of yesterday; see attached. Is this more along the lines of what you'd expect a WinAPI window creation to look like?

Also, is it correct that, even though CreateWindowEx sends the WM_CREATE message, it isn't handled by WndProc until the while(!done) loop is reached and the message is dispatched? Or is the operating system sending the message directly to the WndProc in this case? MSDN page for WM_CREATE says nothing, and the MSDN page for CreateWindowEx says it "sends WM_NCCREATE, WM_NCCALCSIZE, and WM_CREATE messages to the window being created. " Is it using "send" in the sense that it is skipping the queue, or that it is just sending a message which is handled by the queue?

Edit #1: I also tried making a manifest file (also attached), mainly for the new program that I started. Is that properly formatted/correct for the issue you mentioned, aardvajk? I couldn't install the hotfix because the .msu that the support page sent me quit after telling me my system is unsupported, so I wrote up a manifest like the links you provided said to. I'm going to see what happens if I use it with my old code.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CommonTater on November 23, 2012, 02:51:14 AM
You're right, I wouldn't know how it worked.

That's not what I asked... How would you know it worked *at all* if your program is constantly crashing? 
How do you know that's not the cause?
 
Quote
Generally, the fact that my window did what I wanted and I saw squares when I drew them was good enough for me, so I didn't bother. I've since fixed that.

Actually no, you haven't... that whole big string of nulltester = lines actually only tests the last call to GetProcAddress()... You could have multiple failures and it would report true as long as the last one worked. Similarly it would report false if the last one fails, even if all the rest worked.
 
Quote
Also, is it correct that, even though CreateWindowEx sends the WM_CREATE message, it isn't handled by WndProc until the while(!done) loop is reached and the message is dispatched? Or is the operating system sending the message directly to the WndProc in this case? MSDN page for WM_CREATE says nothing, and the MSDN page for CreateWindowEx says it "sends WM_NCCREATE, WM_NCCALCSIZE, and WM_CREATE messages to the window being created. " Is it using "send" in the sense that it is skipping the queue, or that it is just sending a message which is handled by the queue?

WM_CREATE et all use SendMessage() which calls your window proc directly.
 
Quote
Edit #1: I also tried making a manifest file

Here's a much better general purpose manifest you can use... just edit the program name and description parts and you're in business... Also you can just as easily import the manfest into your program's resources so the two never get separated.
 
Code: [Select]

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32"
                    name="ProgramNameWithoutExtension"
                    version="1.0.0.0"
                    processorArchitecture="*" />
  <description>
    My Program Description goes here   
  </description>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32"
                        name="Microsoft.Windows.Common-Controls"
                        version="6.0.0.0"
                        processorArchitecture="*"
                        publicKeyToken="6595b64144ccf1df"
                        language="*" />
    </dependentAssembly>
  </dependency>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel  level="asInvoker"
                                  uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>

Also, to give you the idea about what I was saying for WinMain :
This is typical of my programs, and it's the entire function...
Code: [Select]
// cold entry point
INT APIENTRY wWinMain (HINSTANCE Inst, HINSTANCE Prev, LPWSTR CmdLine, INT Show)
  {
    gInst = Inst;  // global instance handle
 
#ifndef _WIN64
    CheckWindowsVersion();   
#endif
 
    InitCommonControls();
 
     {
      WNDCLASS wc = {0};
      wc.style        = CS_CLASSDC;
      wc.lpszClassName= EZPRO_CLASS;
      wc.hCursor      = LoadCursor(NULL,IDC_ARROW);
      wc.hIcon        = LoadIcon(Inst,L"APPICON");
      wc.lpszMenuName = L"MAINMENU";
      wc.hInstance    = Inst;
      wc.lpfnWndProc  = MainTosser;
 
      if(! RegisterClass(&wc))
        {
          MessageBox(NULL,L"Class registration failed.", NULL, MB_ICONSTOP | MB_OK);
          return (GetLastError());   
        }
    }   
 
    // create the main window
    gMainWind = CreateWindowEx(WS_EX_CONTROLPARENT, EZPRO_CLASS, L"Easy Project",
                                WS_OVERLAPPEDWINDOW,
                                CW_USEDEFAULT,CW_USEDEFAULT,200,200,
                                NULL, NULL, Inst, NULL);
    if(!gMainWind)
      {
        MessageBox(NULL,L"Main window creation failed.", NULL, MB_ICONSTOP | MB_OK);
        return (GetLastError());   
      }
     
    // dispatch messages
    {
      MSG msg;
      while(GetMessage(&msg, NULL, 0, 0))
        {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
        }
 
      return (DWORD) msg.wParam;   
    }
 
    // if all else fails
    return 0;
  }

All the initialization occurs in WM_CREATE...
 
And FWIW... except in rare circumstances you actually want GetMessage() to block so your system can enter a low CPU usage idle state.  If the loop is running around in circles full speed you can cause CPU races that will overheat some systems.
 
 
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Hydronium on November 23, 2012, 03:28:48 AM
That's not what I asked... How would you know it worked *at all* if your program is constantly crashing? 
How do you know that's not the cause?
Meant to say if* it worked, and my program was functional with that code before this issue, so I knew that it worked at the the time at which it did. Right now I have no idea what the issue is, and have started over.
Quote

Actually no, you haven't... that whole big string of nulltester = lines actually only tests the last call to GetProcAddress()... You could have multiple failures and it would report true as long as the last one worked. Similarly it would report false if the last one fails, even if all the rest worked.
Yea, just realized that before coming back. Not sure how to do it without a line of if statements, but I'll probably have to do that.

Quote

WM_CREATE et all use SendMessage() which calls your window proc directly.

Could you clarify "et all"? Aren't only a few messages sent directly, based on the function that is sending them? Else why would I bother with a Translate/Dispatch loop?

Quote
All the initialization occurs in WM_CREATE...
 
And FWIW... except in rare circumstances you actually want GetMessage() to block so your system can enter a low CPU usage idle state.  If the loop is running around in circles full speed you can cause CPU races that will overheat some systems.

Your code only differs from mine in that I check for full screen, and use a RECT struct for window dimensions. I don't see your WndProc nor how your WM_CREATE message is handled.

I use PeekMessage because I will be rendering to the screen and am not interesting in waiting for messages to allow my program to continue.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CommonTater on November 23, 2012, 06:51:36 AM
Yea, just realized that before coming back. Not sure how to do it without a line of if statements, but I'll probably have to do that.

Code: [Select]
SetLastError(0);
 
// getprocaddress lines go here
 
if(GetLastError())
  ScreamBloodyMurder();

The only way for GetLastError() to return 0 is if there were no errors.

Quote

Quote
WM_CREATE et all use SendMessage() which calls your window proc directly.

Could you clarify "et all"?

"And others"
 
Quote

Aren't only a few messages sent directly, based on the function that is sending them? Else why would I bother with a Translate/Dispatch loop?

Yep ... and WM_CREATE is one of them.  It has to be sent that way... your message loop won't be running yet.
 
 
Quote

Quote
All the initialization occurs in WM_CREATE...
 
And FWIW... except in rare circumstances you actually want GetMessage() to block so your system can enter a low CPU usage idle state.  If the loop is running around in circles full speed you can cause CPU races that will overheat some systems.

Your code only differs from mine in that I check for full screen, and use a RECT struct for window dimensions. I don't see your WndProc nor how your WM_CREATE message is handled.
From the same program....
Code: [Select]
// resize the main window
INT DoWmSize(HWND Win, INT Width, INT Height)
  {
    RECT tbr;     // toolbar rectangle
 
    // resize the toolbar
    SendMessage(gToolBar, TB_AUTOSIZE, 0, 0);
 
    // adjust for tool bar rectangle
    GetWindowRect(gToolBar, &tbr);
    tbr.bottom -= tbr.top;
   
    // now the treeview
    MoveWindow(gTreeView, 0, tbr.bottom, Width, Height - tbr.bottom, 1);
    return 0;
  }
 
 
// Initialize the application
INT DoWmCreate(HWND Win, LPCREATESTRUCT Data)
  {
    RECT cr;            // client rectangle
    HIMAGELIST hti;     // treview images 
    HIMAGELIST hbi;     // button images 

    // button initializers
    const TBBUTTON  btnu[4] =     
            {
              {0, 1000, TBSTATE_ENABLED, BTNS_BUTTON},
              {1, 1001, TBSTATE_ENABLED, BTNS_BUTTON},
              {2, 1002, TBSTATE_ENABLED, BTNS_BUTTON},
              {3, 1003, TBSTATE_ENABLED, BTNS_BUTTON},
            };
 
    // visual display elements
    hti = ImageList_LoadImage(gInst,L"TREE",16,0,RGB(255,255,255),
                        IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_LOADTRANSPARENT);
    hbi = ImageList_LoadImage(gInst,L"TOOL",16,0,RGB(255,255,255),
                        IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_LOADTRANSPARENT);

    // toolbar
    gToolBar = CreateWindow(TOOLBARCLASSNAME, NULL,
                        WS_VISIBLE | WS_CHILD |
                        TBSTYLE_WRAPABLE | TBSTYLE_FLAT,
                        0, 0, 0, 0,
                        Win, (HMENU) 1000, Data->hInstance, NULL);
   
    SendMessage(gToolBar,TB_SETBITMAPSIZE,0,MAKELONG(16,16));   
    SendMessage(gToolBar,TB_SETBUTTONSIZE,0,MAKELONG(20,20));
    SendMessage(gToolBar,TB_SETIMAGELIST,0,(LPARAM)hbi);
    SendMessage(gToolBar,TB_BUTTONSTRUCTSIZE,sizeof(TBBUTTON),0);
    SendMessage(gToolBar,TB_ADDBUTTONS,4,(LPARAM)&btnu);
 
     // treeview
    gTreeView = CreateWindow(WC_TREEVIEW, NULL,
                        WS_VISIBLE | WS_CHILD |
                        TVS_HASLINES |
                        TVS_EDITLABELS | TVS_INFOTIP | TVS_HASBUTTONS | TVS_LINESATROOT,
                        0, 0, 0, 0,
                        Win, (HMENU) 1010, Data->hInstance, NULL);
    TreeView_SetImageList(gTreeView, hti, TVSIL_NORMAL);

     // organize children
    GetClientRect(Win, &cr);
    SendMessage(Win,WM_SIZE, SIZE_RESTORED, MAKELPARAM(cr.right, cr.bottom));
 
    // and lets see it
    ShowWindow(Win, SW_SHOWNORMAL);
    return 0;
  }
 
// main message loop
LRESULT CALLBACK MainTosser(HWND Win, UINT Msg, WPARAM Wparm, LPARAM Lparm)
  {
    switch(Msg)
      {
        case WM_CREATE :
          return DoWmCreate(Win, (LPCREATESTRUCT) Lparm);
        case WM_SIZE :
          return DoWmSize(Win, LOWORD(Lparm), HIWORD(Lparm));
        case WM_CLOSE :
          DestroyWindow(Win);
          return 0;
        case WM_DESTROY :
          PostQuitMessage(0);
          return 0; 
 
// a ton of stuff removed

        default :   
          return DefWindowProc(Win, Msg, Wparm, Lparm);
      }
  }

Small differences sometimes make all the difference.  The reason for doing it that way is that in WM_CREATE the window actually exists, has a valid DC and can accept children but it is static and not yet on the screen.  This is the perfect time to do things like resizing, adding controls, rendering images, etc.  That is, in fact why the message is sent when it is sent.
 
Quote
I use PeekMessage because I will be rendering to the screen and am not interesting in waiting for messages to allow my program to continue.

Screen renders usually take about 2 to 3 milliseconds (on anything newer than P3). The vertical frame rate is about 16 milliseconds for most LCD monitors and TV sets... you could set an 8 millisecond timer to check if any rendering needs to be done and still render at twice the vertical frame rate without racing the CPU.  Alternatively you could render in a separate thread that is governed by timed events (CreateEvent(), WaitForSingleObject() etc) and let the main thread block unless there is user input... Once again an 8 millisecond interval will let you render at twice the frame rate without playing silly tricks on your message loop.
 
More than one clever programmer has cooked a supply or cpu trying to mess with methods that are by design intended to use as little CPU time as possible.
 
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Hydronium on November 24, 2012, 02:23:51 PM
Thanks for GetLastError(), totally forgot about that WRT WinAPI calls.

More than one clever programmer has cooked a supply or cpu trying to mess with methods that are by design intended to use as little CPU time as possible.

Yea, I forgot to say that I would implement a timer and wait to reduce it. I've implemented it now.

Thanks for your help, I think I'm good from here on out but we'll see.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Hydronium on November 24, 2012, 03:26:41 PM
Alright, nevermind.

Tried implementing my GetBitmap function after my loadlibrary and function pointer setup. Stepping into the same line as last time causes the same strange issue: the Pelles C debugger treats the next "Step Into" as "Go/Debug" and loses focus to the window. Now, it doesn't tell me anything either through the debugger or normal execution that would let me know that the calls are not being reached. I added sprintf and MessageBox lines so that I could get the error code (which the debugger couldn't show me because it wouldn't step to the next line) and it's 0, which probably means it is OK. It's interesting that by adding these two lines the debugger allows me to "step into" normally! But why is it skipping lines otherwise?

This might make it clearer, if my explanation was confusing:

Case #1:
Code: [Select]
      fclose(bmFile); <------------------------------------BREAKPOINT HERE.

      glActiveTexture(GL_TEXTURE0); <------------------------------------STEP INTO HERE
      enumGLError = glGetError(); <------------------------------------Another step into DOES NOT get here! It just runs and gives focus to my window.
      glGenTextures(1, &texture);
      enumGLError = glGetError();
      glBindTexture(GL_TEXTURE_2D, texture);
      enumGLError = glGetError();

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

      glTexImage2D(GL_TEXTURE_2D,   /*Type of texture*/
                   0,               /*Level of Detail number*/
                   GL_RGB,          /*Internal format*/
                   bmWidthPx,       /*Width in texels(pixels?)*/
                   bmHeightPx,      /*Height in texels(pixels?)*/
                   0,               /*Border. Must be 0 (probably only for 2D)*/
                   GL_BGR,          /*Format, of the data the texture will be created from*/
                   GL_UNSIGNED_BYTE,/*Data type of the pixel data*/
                   bmBuffer);       /*Pointer to the image data to create the texture from*/

      //glBindTexture(GL_TEXTURE_2D, 0);

      free(bmBuffer);

Case #2:
Code: [Select]
      fclose(bmFile); <------------------------------------BREAKPOINT HERE.

      char msgData[100];
      glActiveTexture(GL_TEXTURE0); <------------------------------------STEP INTO HERE.
      enumGLError = glGetError(); <------------------------------------STEP INTO works here!
      sprintf(msgData, "%i", enumGLError); <------------------------------------And here!
      MessageBox(NULL, msgData, NULL, MB_OK | MB_ICONINFORMATION); <------------------------------------And for everything after! Returns 0 for error, which leads me to believe it is OK, but the debugger just ignores everything after glActiveTexture.
      glGenTextures(1, &texture);
      enumGLError = glGetError();
      glBindTexture(GL_TEXTURE_2D, texture);
      enumGLError = glGetError();

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

      glTexImage2D(GL_TEXTURE_2D,   /*Type of texture*/
                   0,               /*Level of Detail number*/
                   GL_RGB,          /*Internal format*/
                   bmWidthPx,       /*Width in texels(pixels?)*/
                   bmHeightPx,      /*Height in texels(pixels?)*/
                   0,               /*Border. Must be 0 (probably only for 2D)*/
                   GL_BGR,          /*Format, of the data the texture will be created from*/
                   GL_UNSIGNED_BYTE,/*Data type of the pixel data*/
                   bmBuffer);       /*Pointer to the image data to create the texture from*/

      //glBindTexture(GL_TEXTURE_2D, 0);

      free(bmBuffer);
glActiveTexture comes from atio6axx.dll. That is the only thing about it that I think could be related to the way Pelles C is handling this. I checked my registry key related to the Windows 7 compatibility shim, etc, and saw nothing. So that is not occurring here. It looks like this is error free, but the debugger is acting weird. Is it just the way that Pelles C handles returns from certain externally loaded libraries?

Edit: I suppose my real question is: Does this behaviour of the Pelles C debugger mask a real issue with my code?

Attached is code, 64bit.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CommonTater on November 24, 2012, 04:58:16 PM
Ok, downloaded your latest sample...
 
After correcting the error handling in your LoadLibrary() call...
Code: [Select]

    HINSTANCE hGLLIB = NULL;
    SetLastError(0);                    // Explicitly set last error to 0
   
     hGLLIB = LoadLibrary("opengl32.dll");
     if(hGLLIB != NULL)                            // explicitly test the library handle
        {
          // library imports
          glActiveTexture    = (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTexture");
          glAttachShader     = (PFNGLATTACHSHADERPROC)wglGetProcAddress("glAttachShader");
          ...
        }

     // check and report error
     if (GetLastError())
      {
         char err[32] = {0};
 
         sprintf(err,"Fatal Error #%d", GetLastError());
         MessageBox (NULL, "Failed to import one or more procedures from OpenGl32.dll",
                                  err, MB_ICONSTOP | MB_OK);
         exit (GetLastError());
      }
I stepped throught the program line by line...

The result of your  GetProcAddress calls is attached...
As you can see, about half of them failed.
 
It is as I said all along ... How did you know it worked?
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Hydronium on November 24, 2012, 06:21:05 PM
Because I have the required DLL, and you do not. See attached.

Is it possible that this is a machine specific issue? wgLGetProcAddress gets it from the appropriate driver dll, so I have no control (that I know of) over whether or not you're able to get the same functions.

EDIT:

I just tested that the glActiveTexture calls were appropriately setting the right enumerator value, using multiple glActiveTexture calls to set different texture locations and glGetIntegerv(GL_ACTIVE_TEXTURE, &testval); to return the changed value. I checked the enum definitions in glcorearb.h. They are correct, and the function is getting called. So my code is doing what I want it to (possibly things I don't, but I have not been notified by the debugger or a crash about it) so my question is still: why does the Pelles C debugger skip lines after this particular (style of) call? Is there a hidden issue it is detecting and not telling me about? Or is it "just how it is"?
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Bitbeisser on November 24, 2012, 07:48:19 PM
...so my question is still: why does the Pelles C debugger skip lines after this particular (style of) call? Is there a hidden issue it is detecting and not telling me about? Or is it "just how it is"?
Sorry for possibly stating the obvious, but if you set the breakpoint at a function call to something contained in a (3rd party provided) DLL, you can of course not "step into", as that DLL is very likely not compiled with any debug info to begin with...  ???

Ralf
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Hydronium on November 24, 2012, 08:13:32 PM
That's a good point, I hadn't even thought of that. Although, why would the debugger not pick up on the rest of the code when the external DLL calls return? I have a feeling you're correct, and to be honest I have not tried Step Over which may continue the debugging properly (maybe, I'm not sure).

So is the debugger getting lost, can't regain it's "footing" in my local code, and then just "running" instead of stepping?

Thanks for the input.

Edit:

"Stepping over" exhibits the same behaviour. I still think you're correct, but I feel like it wouldn't make sense to suddenly stop debugging after coming across something that many C programs probably do (call things from an external DLL, that was manually loaded). Even though the function pointer is the same style as a regular GetProcAddress function pointer, might the wglGetProcAddress function have anything to do with it? This odd behaviour forces me to double break-point all my code, so that the debugger halts after coming out of one of these DLL's. Output code such as MessageBox seem to halt it as well though. I'm confused. :|
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CommonTater on November 24, 2012, 08:56:36 PM
I'm confused.

You're not alone... It's now obvious I can't test your software here, so I'm pretty much out of the game, except for general advice.  You should definately set up error checks the way I showed you in my last message, any external process like that needes to be checked... especially one that is crucial to making your program run.  (Had you done that, you could have saved me about 9 ot 10 hours messing with code that is destined not to work on my system!)

I do find myself wondering exactly what you expect from the debugger. I use it quite routinely with my own projects and so far it seems to track my program's behaviour correctly in that when an if() is true it skips the else part, follows loops for the required number of repititions, tracks into and out of subroutines according to my program's flow, etc.  And, yes, if my program hangs, so does the debugger... If it loses track of your program then it's most likely because your program is no longer in control.
 
I'd like to be more help... but I just don't see how...
 
 
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Hydronium on November 24, 2012, 10:44:23 PM
Well, I would expect to be able to step through my code, without the debugger deciding to do something else for some indiscernible reason. If I click "Step Into", I expect to step into the next line. If I hit "Step Into" and it pretends to be "Go/Debug" in certain instances only instead, then that doesn't make sense.

It seems related to what Bitbeisser said, but I can Step through Win API calls and other external calls which are definitely not local without this odd behaviour. My code still seems to work, the debugger just refuses to play nice....but won't tell me why not. For now it doesn't appear to be a problem. We'll see as I reach the point I was at with my older code.

Thanks for the assistance so far. Hopefully no actual problems end up appearing.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CommonTater on November 24, 2012, 11:16:33 PM
If I click "Step Into", I expect to step into the next line. If I hit "Step Into" and it pretends to be "Go/Debug" in certain instances only instead, then that doesn't make sense.

One important distinction... it does not step to the next line... When you click "Step Into" or "Step Over" it executes the current line then relocates itself to the next point where your program has control. 

For example...
Code: [Select]
int x = 10;
 
if (x == 10)
  puts("Yes it's ten");
else
  puts("Sorry not ten");
 
puts("I'm here now")
It's going to execute the if statement, locate on the first puts, then jump completely over the else clase and land on the last puts.  It follows your program's execution... not your source code's line numbers.  If your program does something silly like overwriting the return address of a function (and it happens with buffer overflows and such) it's going to follow your program as it descends into the bowels of undefined behaviour.

Quote
It seems related to what Bitbeisser said, but I can Step through Win API calls and other external calls which are definitely not local without this odd behaviour.

Because in assembler mode it follows instructions... the steps are smaller.  If you step into a JMP or CALL it's going to follow that too...
 
Quote
My code still seems to work, the debugger just refuses to play nice....but won't tell me why not. For now it doesn't appear to be a problem. We'll see as I reach the point I was at with my older code.

Thanks for the assistance so far. Hopefully no actual problems end up appearing.

You can pretty much take to the bank that if the debugger is misbehaving there are problems in the program...
 
One distinct possibility the compiler won't catch, is if your code is trashing the stack.  FWIW, the stack in most windows programs is limited to about a megabyte, once that's exceeded, just about any darned strange thing can happen since you will be playing in unallocated memory.  Check your variables, see how much stuff you're piling up on the stack... you might be surprised.  (FWIW... an array of 1000 x 1000 chars can trash a stack quite easily... which is why I malloc() most everything bigger than a pointer these days.)
 
Another possibility (although far less likely) is that some debuggers have problems with uninitialized variables...
Code: [Select]
// wrong
WIN32_FIND_DATA fd;
 
// correct
WIN32_FIND_DATA fd = {0};
Any variable that is declared inside a function has to be manually initialized. C does not intialize them for you.
 
Well, anyway .... good luck with this, I'm thinking you got a bit of a row to hoe here...
 
 
 
 
 
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Bitbeisser on November 25, 2012, 04:09:57 AM
Well, I would expect to be able to step through my code, without the debugger deciding to do something else for some indiscernible reason. If I click "Step Into", I expect to step into the next line.
Sorry, that is not correct.

"Step into" means that you want to follow the function call and that's where I guess your program goes south. As mentioned, if that function call is in a 3rd party DLL (or any object file linked in that is compiled without debug info for that matter!), the debugger will perform a "Step over", which will move the debugger to the next source code line that is reachable, after returning from that function call.
Quote
If I hit "Step Into" and it pretends to be "Go/Debug" in certain instances only instead, then that doesn't make sense.
Well, you are a bit unclear as to what exactly is happening and unfortunately, those people that are trying to help you out here (including me) can't properly reproduce this problem without that specific DLL...  :-\

My best guess is that this is somehow related to the DLL call itself or something in the parameters in the called function that is messing with the call stack that prevents the debugger from behaving nicely...

What I would test in your case, place a breakpoint right in front and right behind the function call in question. If the call to the DLL returns properly, the second on should stop the program again.
I don't use Pelle's C as much as CommonTater for example is, but in those cases where I have traced code (no DLLs involved though), I have never seen such behavior as you are describing...

Ralf
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CommonTater on November 25, 2012, 04:54:55 AM
Ralf speaks the truth ...  :D  (Hi Ralf)

Looking at the part of your code where you open your file, there is a far simpler way of doing that...

1) Use GetFileAttributesEx() to get the file size and attributes.
2) Use calloc() or malloc() to create the buffer, with a few extra bytes for good measure.
3) Open the file using the winapi  CreateFile() call
4) Read the whole thing into memory in one go with ReadFile()
5) Close the file with FileClose()

Now you have an array of bytes and can access the entire thing using simple notation like ...  bmp[offset] without any seeks pre-reading or backtracking...
 
Think what happens if the file size in the header is wrong...

Even more clever you can design a struct for the header information and overlay that on the buffer to access the variables directly from the buffer... none of this Read4Bytes crap.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Bitbeisser on November 25, 2012, 05:14:04 AM
Ralf speaks the truth ...  :D  (Hi Ralf)
Hi and thanks as well!  8)
Quote
Looking at the part of your code where you open your file, there is a far simpler way of doing that...

1) Use GetFileAttributesEx() to get the file size and attributes.
2) Use calloc() or malloc() to create the buffer, with a few extra bytes for good measure.
3) Open the file using the winapi  CreateFile() call
4) Read the whole thing into memory in one go with ReadFile()
5) Close the file with FileClose()

Now you have an array of bytes and can access the entire thing using simple notation like ...  bmp[offset] without any seeks pre-reading or backtracking...
 
Think what happens if the file size in the header is wrong...

Even more clever you can design a struct for the header information and overlay that on the buffer to access the variables directly from the buffer... none of this Read4Bytes crap.
Well, I do not quite agree with you here...

Reading in a whole file might work for small or even midsize (a couple 100KB) files, but for larger files, you are just wasting time (and RAM!). Windows caching is pretty good, so there is no real a penalty in doing so, and when taking a brief look at the over all code, I rather feel it enhances a bit the readability of the code...

And certainly, none of this is the source of his debugger problems...  ;)

Ralf
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CommonTater on November 25, 2012, 06:43:56 AM
Reading in a whole file might work for small or even midsize (a couple 100KB) files, but for larger files, you are just wasting time (and RAM!).

It's a BMP file... he needs the header to know the setup of the file, he needs the entire bitmap available at one time if he's going to bitblt or otherwise copy it to a window.  So, read the whole file then parse the header... it's the easiest way.
 
With 4 and 8gb of ram becoming common place, space is hardly a problem.
Plus he can free it when he's done, so nothing is wasted.

I do this all the time Ralf... 100mb+ files with no problems.  It's blinding fast when you can work the data from memory and it's really quite simple code-wise. 
 
It is (IMO) "old think" --a mistake-- to cling to character by character or line by line methods that were made necessary by limited resources when those limitations are long gone.

Consider this trivial example...
Code: [Select]
typedef struct t_FILEHDR
  {
     DWORD DataSize;
     DWORD DataOffset;
     CHAR  TagName[256];
   } FILEHDR, *pFILEHDR;
 
PVOID Data;
 
// now read the entire 10mb file into memory  at Data
 
printf("Data Size = %u", ((pFILEHDR) Data)->DataSize);
printf("Data Offsert = %u", ((pFILEHDR) Data)->DataOffset);
printf("Tag Name = %s", ((pFILEHDR) Data).TagName);
 
ParseData(Data + ((pFILEHDR) Data)->DataOffset, ((pFILEHDR) Data)->DataSize);

How much easier do you want it to be?
 
Quote
And certainly, none of this is the source of his debugger problems...  ;)

Absolutely.  This has nothing to do with his debugging problems... it was just a suggestion from looking at his code... which is rather convoluted at the moment. 
 
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: TimoVJL on November 25, 2012, 09:15:24 AM
Example for debugging.
At line 30 debugger lost control.
Code: [Select]
#define UNICODE
#define WIN32_LEAN_AND_MEAN
//#define WIN32_DEFAULT_LIBS
#include <windows.h>
#include <ole2.h>

#pragma comment(lib, "ole32.lib")

CLSID const IID_IScriptControl = { 0x0E59F1D3, 0x1FBE, 0x11D0, {0x8F, 0xF2, 0x00, 0xA0, 0xD1, 0x00, 0x38, 0xBC} };

TCHAR *szAppName = TEXT("MSScriptTest");

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
HRESULT hr;
GUID clsid;
IDispatch *pISC = NULL;

hr = CoInitialize(NULL);
hr = CLSIDFromProgID(L"MSScriptControl.ScriptControl", &clsid);
if (hr)
MessageBox(0, TEXT("Error CLSIDFromProgID()"), szAppName, 0);
else {
hr = CoCreateInstance(&clsid, NULL, CLSCTX_ALL, &IID_IScriptControl, (void **)&pISC);
if (hr)
MessageBox(0, TEXT("Error CoGetClassObject()"), szAppName, 0);
else {
//MessageBox(0, "OK", szAppName, 0);
pISC->lpVtbl->Release(pISC);
pISC = NULL;
}
}
CoUninitialize();
return 0;
}
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Hydronium on November 25, 2012, 04:47:34 PM
What I would test in your case, place a breakpoint right in front and right behind the function call in question. If the call to the DLL returns properly, the second on should stop the program again.

Sorry if my description is vague, but I can't think of any other way of describing it. Also, if anyone has an nVidia or ATI (specifically ATI in my case, since nVidia's might not do this strange stuff) graphics card you should have the associated drivers and wglGetProcaddress should find it. Even an integrated GPU should have drivers for simple OpenGL graphics, I would think (but I'm not sure).

I can do what you've described above, and it does as you say. This is why I'm unsure why I explicitly need to tell the debugger to stop. I've never built a compiler or debugger, so it's probably something way over my head, design-wise. I suppose it is not a huge problem, but it will make debugging slightly more tedious.

Thanks.

Looking at the part of your code where you open your file, there is a far simpler way of doing that...
Even more clever you can design a struct for the header information and overlay that on the buffer to access the variables directly from the buffer... none of this Read4Bytes crap.

At the time, I was looking up purely C related functions to do the job. Honestly, I hadn't even thought of what WinAPI calls windows had available and didn't think to look. I'll investigate it, though the more transferable my code is between platforms the better so that I have less to change if I ever move to a different OS. The WinAPI calls may be the best bet for this particular implementation anyways. Thanks.

Even more clever you can design a struct for the header information and overlay that on the buffer to access the variables directly from the buffer... none of this Read4Bytes crap.
It's a BMP file... he needs the header to know the setup of the file, he needs the entire bitmap available at one time if he's going to bitblt or otherwise copy it to a window.  So, read the whole file then parse the header... it's the easiest way.

I designed those little procedures because the bytes are in little-endian format, and I needed to reverse them for those particular entries in the header. Does your suggestion take care of that, or do you mean I should do the byte-twiddling after having all the information in memory?

Also, the bmp data is only read in so that I can then load it into GPU memory with the glTexImage2D call. It only requires the data, not the header. I thought it would be simpler to read and not store the header data, and only read the data into memory, as the call requires a pointer to the texture data (not including the header, which the GL can not interpret). Is this irrelevant, given what you've said (ie, did you take it into account, or does it not matter)?

Absolutely.  This has nothing to do with his debugging problems... it was just a suggestion from looking at his code... which is rather convoluted at the moment. 

Could you expand on that? Is the design convoluted, the implementation, something else (hopefully not all of it :( )? Thanks.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CommonTater on November 25, 2012, 06:03:52 PM
Looking at the part of your code where you open your file, there is a far simpler way of doing that...
Even more clever you can design a struct for the header information and overlay that on the buffer to access the variables directly from the buffer... none of this Read4Bytes crap.

At the time, I was looking up purely C related functions to do the job. Honestly, I hadn't even thought of what WinAPI calls windows had available and didn't think to look. I'll investigate it, though the more transferable my code is between platforms the better so that I have less to change if I ever move to a different OS. The WinAPI calls may be the best bet for this particular implementation anyways. Thanks.

Grab a copy of the Windows 7 sdk ... HERE (http://www.microsoft.com/en-us/download/details.aspx?id=18950) You only need to install the desktop documentation, pretty much everything else is supplied by Pelles C...
 
As for the fantasy of platform independent code... my friend, you're playing with DRIVERS which are just about the least platform independet code you're going to find. 
 
Quote
I designed those little procedures because the bytes are in little-endian format, and I needed to reverse them for those particular entries in the header. Does your suggestion take care of that, or do you mean I should do the byte-twiddling after having all the information in memory?

Windows is natively little endian.  Overlay a struct on the header portion of the file... do the values it gives you make sense?
 
Quote
Also, the bmp data is only read in so that I can then load it into GPU memory with the glTexImage2D call. It only requires the data, not the header. I thought it would be simpler to read and not store the header data, and only read the data into memory, as the call requires a pointer to the texture data (not including the header, which the GL can not interpret). Is this irrelevant, given what you've said (ie, did you take it into account, or does it not matter)?

Take another look at the example I supplied to Ralf... The hints are all there....
 
Quote
Absolutely.  This has nothing to do with his debugging problems... it was just a suggestion from looking at his code... which is rather convoluted at the moment. 

Could you expand on that? Is the design convoluted, the implementation, something else (hopefully not all of it :( )? Thanks.

There's no such thing as bad code, provided it actually works... But there is always a way to simplify your approach and make things work better.  I would suggest your code reflects a lack of planning... the bright idea, straight to keyboard approach seldom gives you the best outcomes.
 
 
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Bitbeisser on November 25, 2012, 06:42:11 PM
What I would test in your case, place a breakpoint right in front and right behind the function call in question. If the call to the DLL returns properly, the second on should stop the program again.
Sorry if my description is vague, but I can't think of any other way of describing it.
Well, the main problem with trying to give help in a forum like this is that we can't see what yo are doing. So a description you write down can sometimes interpreted in different ways and might therefor need clarification...
Quote
Also, if anyone has an nVidia or ATI (specifically ATI in my case, since nVidia's might not do this strange stuff) graphics card you should have the associated drivers and wglGetProcaddress should find it. Even an integrated GPU should have drivers for simple OpenGL graphics, I would think (but I'm not sure).
I haven't been much into graphics programming on Windows for almost two decades now, pretty much since OpenGL was first pulished. But I thought that it's purpose is to provide a device independent way to do 2D and 3D graphics on Windows, so I am not sure why your code depends on a specific DLL. And as I am currently be short on time due to RL issues, just stopping by the forum for a couple of minutes, I haven't had the time to take a closer look yet....
Quote
I can do what you've described above, and it does as you say. This is why I'm unsure why I explicitly need to tell the debugger to stop. I've never built a compiler or debugger, so it's probably something way over my head, design-wise. I suppose it is not a huge problem, but it will make debugging slightly more tedious.
Well, if it works the way I suggested, then this means that something in the DLL (or with the parameters call functions in it) isn't quite kosher and messes with the debugger environment. I think it would take a bit more investigating as to why this is happening...

Ralf
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: Hydronium on November 25, 2012, 08:43:35 PM
As for the fantasy of platform independent code... my friend, you're playing with DRIVERS which are just about the least platform independet code you're going to find. 
But I thought that it's purpose is to provide a device independent way to do 2D and 3D graphics on Windows, so I am not sure why your code depends on a specific DLL.

OpenGL is platform-independent, and only needs the drivers supplied by the graphics card makers. ATI supplies Linux drivers, and I assume Apple has drivers somewhere or another. Same for nVidia, and possibly other GPU makers. The drivers will be specific to the machine, but the API will always be the same (glClear on Windows is glClear on Apple is glClear on Linux).

Windows is natively little endian.  Overlay a struct on the header portion of the file... do the values it gives you make sense?

I never even though to do that, that's pretty clever. The only thing I'm worried about is the first few pieces of data. I'd have to make sure the struct is packed to a 2-byte alignment, instead of whatever Pelles C chooses. I'm away from my regular computer at the moment, so I'm not able to start looking into this. I definitely will though, as it could make this much simpler (maybe not quite yet though, as I'd like to reach the point of code which started this thread topic to see if my Access Violation error is gone).

Thanks.
Title: Re: Is my Pelles C Debugger skipping lines?
Post by: CommonTater on November 25, 2012, 09:18:23 PM
I never even though to do that, that's pretty clever. The only thing I'm worried about is the first few pieces of data. I'd have to make sure the struct is packed to a 2-byte alignment, instead of whatever Pelles C chooses. Thanks.

Look in the help file at pragmas... I believe you will want #pragma pack(2)  before your struct definition then #pragma pack() after.  You may also have to add some filler bytes in the event the compiler decides to insert them in different places than you want...  But it is doable.
 
I'd also check in your header files... you may find a bmp header struct already defined that you can use.