Odd problem... [Possible Memory Corruption]

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Odd problem... [Possible Memory Corruption]

Post by neon »

Hello everyone,

Perhaps Im missing something but Im not sure what can cause this. It may be paging-related, which is why I decided to post this here.

In a routine I have a unsigned char array defined as BYTE Image [1024+1];. I also have a BYTE pointer that points to a region where the data is to be copied, ImageRel. An instruction, *ImageRel = 0;, sets ImageRel[0] to 0 as expected. However if I loop it (or call memset) :

Code: Select all

for (; count != 0; count--, i++)
	ImageRel[i] = Image[i];
When running in Bochs, My display routine reports that ImageRel == 0xff instead of the value in Image (I display both values.)

This seems to work fine in the lower identity mapped region without problems. It only started happening when I first attempted to use a higher dynamically-mapped virtual address (tried 0xc0000000, mapped to a dynamically allocated page table.)

Has anyone seen this before? I am happy to post more code if needed,

*edit: Just tested with different code. This works as expected. ImageRel[0] == Image[0] :

Code: Select all

ImageRel[0] = Image[0];
This does not: ( ImageRel[0] == 0xff? )

Code: Select all

for (i=0; i < 1024; i++)
	ImageRel[i] = Image[i];
Thank you for any help :D
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
kmcguire
Member
Member
Posts: 120
Joined: Tue Nov 09, 2004 12:00 am
Location: United States
Contact:

Re: Odd problem...

Post by kmcguire »

Post the assembly generated from that function by the compiler you are using. Use objdump or something similar. Or, just use boches debugger and step through the assembly checking the registers and memory locations with manual probing as you go. The stack can do weird stuff if it grows into something. Also the time between the loop and when you display the values is unknown -- anything could be happening between there.

You could have major problems with corruption somewhere. I used to find a way to disable threading right before the problem area so I could step through using boches (disable interrupts) and generally I could discover if the problem was corruption from something multi-tasking related.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Odd problem...

Post by neon »

Thanks for your suggestions :D

I was thinking a form of corruption as well, but I dont understand how this could surface only when using a non-identity mapped virtual address :? (It works fine if both addresses passed into the routine is identity mapped or physical addresses.)

Hm, then again that might mean theirs an issue in the memory manager somehow, although the pages are accessible fine and the "loop bug" only happens in that one routine. Ill post if I find any more info.

The routine is fairly complex, bochs does not seem to let me view virtual addresses (hm, perhaps I should test with newer versions as well.) but following the registers and disassembly seem to show the correct values.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Odd problem...

Post by neon »

Hello everyone,

This is a little update: I created a stub memcpy2 routine and am printing the values of the addresses after being set and they are showing that they copied successfully. In a similar loop right after the call to the routine, I just print the values at the location we are copying to that has shown it was copied successfully. Sure enough, its somehow 0xff right after returning from the memcpy() call.

The only thing that I can think of that can cause this is that the virtual address is being set to a different frame while copying (This makes me think there might be page table corruption somehow...)
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
xyzzy
Member
Member
Posts: 391
Joined: Wed Jul 25, 2007 8:45 am
Libera.chat IRC: aejsmith
Location: London, UK
Contact:

Re: Odd problem... [Possible Memory Corruption]

Post by xyzzy »

If you're doing any modification of page table entries, are you flushing the TLB entry for the page afterwards? I've had problems like this before from not flushing the TLB properly.
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Odd problem... [Possible Memory Corruption]

Post by neon »

Hello,

Thanks for the response - I do not, however. Currently I allocate a page directory and a page table (when needed) followed by a series of pages (as needed.) It does give me another place to look, though.

I also thank whoever changed the topic title - I originally did not know what the problem was thus the lack of info in the title :)
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Odd problem... [Possible Memory Corruption]

Post by neon »

Hello everyone,

Im still not sure what the actual cause of the issue is. However I found the new version of bochs does provide a page command that can be used to obtain the virtual to physical address mapping. When looking at the mapping, I noticed that the high bit of the frame address was always getting set which my physical frame allocator was not configured to work with addresses in that region. After fixing that, everything now seems to be working fine.

Thanks for the suggestions everyone :D
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Post Reply