🔒 Locked
Dx lock problem/ Pointer?????? don't know :(
Advertisement
Original Post
“First I get “ BASIC caused an invalid page fault in module BASIC.EXE at 016f:0040b974. Registers: EAX=cccccccc CS=016f EIP=0040b974 EFLGS=00010202 EBX=00580000 SS=0177 ESP=0068fbd2 EBP=0068fbde ECX=00000000 DS=0177 ESI=0068fc48 FS=2c3f EDX=006a5f34 ES=0000 EDI=00680068 GS=0000 Bytes at CS:EIP: 66 c5 75 0c 0f b6 55 18 0f b6 5d 10 66 83 fa 00 Stack dump: 00000177 0068fc48 0068fc2c fc9cfc2c fc480068 00000068 cccc0058 cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc There are two basic causes for an invalid page fault in the Windows 95 environment: · Something unexpected has happened within the Windows environment, typically an improper memory address. For example, an application or a Windows component might read or write to a memory location that has not been allocated to it (memory that it does not own), potentially overwriting and corrupting other program code in that area of memory. · Parameters that are not valid have been passed between applications and the Windows environment. Invalid parameters can cause invalid instructions to be executed, resulting in page faults. This is usually the result of the application's internal program code incorrectly passing specific data that could not be correctly interpreted by Windows or a Windows-based application. “Then the next time I run the code I get : DDERR_CANTLOCKSURFACE” “windowed directx code I use for trouble shooting that returns error during lock function!” “ an help would be great! J” DX_Error_result=(lpdd7->SetCooperativeLevel(hwnd, DDSCL_NORMAL)); if (FAILED(DX_Error_result)){ Error_Engine -> Get_Error(DX_Error_result); MessageBox(NULL, "NORMAL Coopertive Operation Failed","Exit", MB_OK|MB_ICONEXCLAMATION); exit(1); }// end if failed DDRAW_INIT_STRUCT(ddsd); DDRAW_INIT_STRUCT(ddpixelformat); memset(ddsd_ptr,0,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.dwBackBufferCount = 0; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; DX_Error_result=(lpdd7->CreateSurface(&ddsd, &lpddsprimary, NULL)); if (FAILED(DX_Error_result)){ Error_Engine -> Get_Error(DX_Error_result); MessageBox(NULL, "Create Primary Surface Failed","Exit", MB_OK|MB_ICONEXCLAMATION); exit(1); }// end if failed DX_Error_result=(lpddsprimary->GetPixelFormat(&ddpixelformat)); if (FAILED(DX_Error_result)){ Error_Engine -> Get_Error(DX_Error_result); MessageBox(NULL, "Get Pixel Format Failed","Exit", MB_OK|MB_ICONEXCLAMATION); exit(1); }// end if failed Color_Depth = ddpixelformat.dwRGBBitCount; Depth_modifier = (Color_Depth / 8); Color_Modified_Size = Vid_Buff_Size * Depth_modifier; GetWindowRect(hwnd,lpRect); result = lpddsprimary->IsLost(); if (FAILED(result)){ Error_Engine -> Get_Error(result); MessageBox(NULL, "Surface Lost","Exit", MB_OK|MB_ICONEXCLAMATION); exit(1); }// end if failed else{ MessageBox(NULL, "Surface not Lost","Exit", MB_OK|MB_ICONEXCLAMATION); } result = (lpddsprimary->Lock(NULL, ddsd_ptr, DDLOCK_WAIT, NULL)); if (FAILED(result)){ Error_Engine -> Get_Error(result); MessageBox(NULL, "LOCK Operation Failed","Exit", MB_OK|MB_ICONEXCLAMATION); exit(1); }// end if failed else{ Screen_Engine->BackBuffAddress = (unsigned char far*)ddsd_ptr->lpSurface;// Asign the Back Buffer address here Screen_Engine->mempitch = (ddsd_ptr->lPitch); if (Screen_Engine->mempitch == 0){ W = Vid_Scr_W * Vid_Scr_H; H = 0; } else { W = Vid_Scr_W; H = Vid_Scr_H; } //MOVE(unsigned char far* BuffDestAddress, unsigned char far* BuffSrcAddress, unsigned int LPitch, unsigned int W, unsigned int H); MOVE(Screen_Engine->BackBuffAddress, Screen_Engine->SrcBuffAddress, Screen_Engine->mempitch, Screen_Engine->W, Screen_Engine->H); //MOVE(BackBuffAddress, SrcBuffAddress, Color_Modified_Size); if(FAILED(lpddsprimary->Unlock(NULL))){ //ERROR } } Accessing the Frame-Buffer Directly Pixel format??????hmmm…..L NT Kernal Built in Kernel Debugging Extensions !locks !locks [Options] [Address] !locks displays information about kernel ERESOURCE locks. Parameters Options This parameter is optional. The following options can be specified to control the information output. -V Maximum output about each lock should be displayed. -P Performance lock information should be displayed Address This parameter is optional. Displays information about the ERESOURCE lock at the specified address. If Address is not specified, then information about all ERESOURCE locks in the system will be displayed. Platforms Power PC, Alpha, MIPS, x86 [Edited by - Kenneth Alexander on April 9, 2005 1:22:50 PM]
It's impossible to tell if it's a stack problem by looking at your registers, but if the error keeps popping up in different places when you make small changes, it sounds just like a stack problem.
How big is your complete source? If you want to zip it up and PM it to me, or e-mail it to me (Link in my profile), I'll see if I can see anything.
How big is your complete source? If you want to zip it up and PM it to me, or e-mail it to me (Link in my profile), I'll see if I can see anything.
// This is the problem here.....well at least it dies here :(
result = (lpddsprimary->Lock(NULL, ddsd_ptr, DDLOCK_WAIT, NULL));
This line is after the clear function which zeros a memory block of a given size.
and before the move function which move a chunk of memory very fast.
clear is about the same as move parms (src dest size value)
not much to write home about
both move and clear are in assembly.
result = (lpddsprimary->Lock(NULL, ddsd_ptr, DDLOCK_WAIT, NULL));
This line is after the clear function which zeros a memory block of a given size.
and before the move function which move a chunk of memory very fast.
clear is about the same as move parms (src dest size value)
not much to write home about
both move and clear are in assembly.
Well, I had a look at your source. You seem to trample over the call stack, since MSVC can't display it properly when the access violation occurs. Putting a breakpoint at the start of the MOVE function shows that it's called from SCREEN_ENGINE::DISPLAY()
I've forgotten what the problem was now :/
The lock succeeds here (Screen.cpp, line 522), and then the code assigns Screen_Engine->BackBuffAddress and Screen_Engine->mempitch, then calls MOVE(Screen_Engine->BackBuffAddress, Screen_Engine->SrcBuffAddress, Screen_Engine->mempitch, Screen_Engine->W, Screen_Engine->H);, which is where the crash occurs.
It seems that the parameters passed to MOVE become invalid. My MSVC (2003) says that when you execute the line mov bp,sp, your parameters get destroyed, since they're on the stack. You'll have to move them into a register before pushing things onto the stack, or find some way around this.
Here's the portion of code I'm talking about (with the comments changed):
I've forgotten what the problem was now :/
The lock succeeds here (Screen.cpp, line 522), and then the code assigns Screen_Engine->BackBuffAddress and Screen_Engine->mempitch, then calls MOVE(Screen_Engine->BackBuffAddress, Screen_Engine->SrcBuffAddress, Screen_Engine->mempitch, Screen_Engine->W, Screen_Engine->H);, which is where the crash occurs.
It seems that the parameters passed to MOVE become invalid. My MSVC (2003) says that when you execute the line mov bp,sp, your parameters get destroyed, since they're on the stack. You'll have to move them into a register before pushing things onto the stack, or find some way around this.
Here's the portion of code I'm talking about (with the comments changed):
void SCREEN_ENGINE::MOVE(unsigned char far* BuffDestAddress, unsigned char far* BuffSrcAddress, unsigned int LPitch, unsigned int W, unsigned int H){ _asm{ push bp ; BuffDestAddress = 0x00fc0000 after this line mov bp, sp ; BuffDestAddress = 0xf0000012 after this line push edi push esi push ds push es push eax les di, BuffDestAddress lds si, BuffSrcAddress
Well.... that explains alot.
If MSCV6, which I am using, is using bp to access the parameters, then messing with it is a bad idea.
The code was originaly external and linked in as an OBJ when I used Borland 4.5 so pushing bp and moving sp to bp is a standard operation, but with inline code I'm playing with others so to speak :)
Almost all external Assembly subroutines use:
push bp
mov bp,sp
...code...
pop bp
to access the stack for parameters / data passed to the function.
So either I'm going to have to access the stack directly or use the compiler and leave bp alone.
It is one or the other not both. :)
Thanks Steve,
Ken
If MSCV6, which I am using, is using bp to access the parameters, then messing with it is a bad idea.
The code was originaly external and linked in as an OBJ when I used Borland 4.5 so pushing bp and moving sp to bp is a standard operation, but with inline code I'm playing with others so to speak :)
Almost all external Assembly subroutines use:
push bp
mov bp,sp
...code...
pop bp
to access the stack for parameters / data passed to the function.
So either I'm going to have to access the stack directly or use the compiler and leave bp alone.
It is one or the other not both. :)
Thanks Steve,
Ken
Well.... now I get surface busy.....
this needs more work
Ken
this needs more work
Ken
First that mov bp,sp in the move function was an error. stop.
But, it is not alone. stop.
teletype days :)
I must have an errant pointer or array some where :(
Because, after review, that is the only explanation left.
And it is writing into Display-Frame or the Lock function or their variables or members.
Resulting in a wide array of failures including coruption of the call stack.
You can see in the following:
Clear function
0040B650 push ebp // This is a dissassembly of the compiler
0040B651 mov ebp,esp // code
0040B653 sub esp,44h
0040B656 push ebx
0040B657 push esi
0040B658 push edi
0040B659 push ecx
0040B65A lea edi,[ebp-44h]
0040B65D mov ecx,11h
0040B662 mov eax,0CCCCCCCCh
0040B667 rep stos dword ptr [edi]
0040B669 pop ecx
0040B66A mov dword ptr [ebp-4],ecx
---------my code----------------------
0040B6BD pop edi
0040B6BE pop esi
0040B6BF pop ebx
0040B6C0 add esp,44h
0040B6C3 cmp ebp,esp
0040B6C5 call __chkesp (004125d0)
0040B6CA mov esp,ebp
0040B6CC pop ebp
0040B6CD ret 14h
This is normal exit and entry of functions in MSVC(Debug...thanks Steve:) )
I need to look more into this but am out of time.
Ken
[Edited by - Kenneth Alexander on April 12, 2005 1:34:30 PM]
But, it is not alone. stop.
teletype days :)
I must have an errant pointer or array some where :(
Because, after review, that is the only explanation left.
And it is writing into Display-Frame or the Lock function or their variables or members.
Resulting in a wide array of failures including coruption of the call stack.
You can see in the following:
Clear function
0040B650 push ebp // This is a dissassembly of the compiler
0040B651 mov ebp,esp // code
0040B653 sub esp,44h
0040B656 push ebx
0040B657 push esi
0040B658 push edi
0040B659 push ecx
0040B65A lea edi,[ebp-44h]
0040B65D mov ecx,11h
0040B662 mov eax,0CCCCCCCCh
0040B667 rep stos dword ptr [edi]
0040B669 pop ecx
0040B66A mov dword ptr [ebp-4],ecx
---------my code----------------------
0040B6BD pop edi
0040B6BE pop esi
0040B6BF pop ebx
0040B6C0 add esp,44h
0040B6C3 cmp ebp,esp
0040B6C5 call __chkesp (004125d0)
0040B6CA mov esp,ebp
0040B6CC pop ebp
0040B6CD ret 14h
This is normal exit and entry of functions in MSVC(Debug...thanks Steve:) )
I need to look more into this but am out of time.
Ken
[Edited by - Kenneth Alexander on April 12, 2005 1:34:30 PM]
Got it Steve, and do I feel stupid :(
Again, that mov bp,sp would cause some problems.
But it is not alone.
First, for those who don't know and are "listening in", just a small note on registers for those new to using inline assembly in "c/c++". You can find this under help "inline assembly" :)
Back to the problem :)
I say again:
Got it, and do I feel stupid :(
If you look at the Clear function you will find a line:(not show in the thread)
mov edi, BuffDestAddress ;// Load start address of destination buffer in di
This used to be:
les di, BuffDestAddress ;// Load start address of destination buffer in es:di
Until I found Load ES/DS with pointer caused a Page fault.
I forgot, I changed that a month ago.
Something to due, I think, with the cpu running in
Protected Mode.
The opcode is either illegal out of the os's ring "0"
or it is not passing the right address.
This needs to be changed:
379: les di, BuffDestAddress ;// Load start address of destination buffer in es:di
0040B712 les di,dword ptr [ebp+8]
380: lds si, BuffSrcAddress ;// Load start address of source buffer in ds:si
0040B716 lds si,dword ptr [ebp+0Ch]
To:
mov edi, BuffDestAddress ;// Load start address of destination buffer in es:di
mov esi, BuffSrcAddress ;// Load start address of source buffer in ds:si
The page fault, I believe, caused colateral damage resulting in a cascade of errors.
It still needs additional work, but it is closer.
The "Lock" fuction still gets corrupted in debug mode....
I don't know why.
fails -1
exits
I then need to reboot the computer to get the surface free again.
Oh well, at least I'm making progress.
If anyone knows or has additional information please "chime in"
hope this helps,
Still at it,
Ken
Again, that mov bp,sp would cause some problems.
But it is not alone.
First, for those who don't know and are "listening in", just a small note on registers for those new to using inline assembly in "c/c++". You can find this under help "inline assembly" :)
Quote:
"When using __asm to write assembly language in C/C++ functions, you don't need to preserve the EAX, EBX, ECX, EDX, ESI, or EDI registers. For example, in the POWER2.C example in Writing Functions with Inline Assembly, the power2 function doesn't preserve the value in the EAX register. However, using these registers will affect code quality because the register allocator cannot use them to store values across __asm blocks. In addition, by using EBX, ESI or EDI in inline assembly code, you force the compiler to save and restore those registers in the function prologue and epilogue.
You should preserve other registers you use (such as DS, SS, SP, BP, and flags registers) for the scope of the __asm block. You should preserve the ESP and EBP registers unless you have some reason to change them (to switch stacks, for example). Also see Optimizing Inline Assembly.
Note If your inline assembly code changes the direction flag using the STD or CLD instructions, you must restore the flag to its original value." - MS
Back to the problem :)
I say again:
Got it, and do I feel stupid :(
If you look at the Clear function you will find a line:(not show in the thread)
mov edi, BuffDestAddress ;// Load start address of destination buffer in di
This used to be:
les di, BuffDestAddress ;// Load start address of destination buffer in es:di
Until I found Load ES/DS with pointer caused a Page fault.
I forgot, I changed that a month ago.
Something to due, I think, with the cpu running in
Protected Mode.
The opcode is either illegal out of the os's ring "0"
or it is not passing the right address.
This needs to be changed:
379: les di, BuffDestAddress ;// Load start address of destination buffer in es:di
0040B712 les di,dword ptr [ebp+8]
380: lds si, BuffSrcAddress ;// Load start address of source buffer in ds:si
0040B716 lds si,dword ptr [ebp+0Ch]
To:
mov edi, BuffDestAddress ;// Load start address of destination buffer in es:di
mov esi, BuffSrcAddress ;// Load start address of source buffer in ds:si
The page fault, I believe, caused colateral damage resulting in a cascade of errors.
It still needs additional work, but it is closer.
The "Lock" fuction still gets corrupted in debug mode....
I don't know why.
fails -1
exits
I then need to reboot the computer to get the surface free again.
Oh well, at least I'm making progress.
If anyone knows or has additional information please "chime in"
hope this helps,
Still at it,
Ken
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement