why am I getting a segfault error from the following code in C?
I have a project due in my operating systems class where I'm supposed to simulate a translation lookaside buffer.
I'm writing a method that will be called after a TLB-miss. It's supposed to find the next entry in the TLB that is either empty or has not been hit in awhile, delete that entry, and replace it with the entry from the page table that was last called. The data from the page table entry is given when the method i开发者_如何学JAVAs called.
Void tlb_insert(VPAGE_NUMBER new_vpage, PAGEFRAME_NUMBER new_pframe, BOOL new_mbit, BOOL new_rbit)
{
// Starting at the clock_hand'th entry, find first entry to
// evict with either valid bit = 0 or the R bit = 0. If there
// is no such entry, then just evict the entry pointed to by
// the clock hand.
int m;
int evct = clock_hand;
for (m = clock_hand; m < (num_tlb_entries); m++){
if (tlb[m].vbit_and_vpage & VBIT_MASK == 0 || tlb[m].mr_pframe & RBIT_MASK == 0){
evct = m;
break;
}
}
// Then, if the entry to evict has a valid bit = 1,
// write the M and R bits of the of entry back to the M and R
// bitmaps, respectively, in the MMU (see mmu_modify_rbit_bitmap, etc.
// in mmu.h)
if (tlb[evct].vbit_and_vpage & VBIT_MASK == 1){
PAGEFRAME_NUMBER pfr = tlb[evct].mr_pframe & PFRAME_MASK;
int val1 = tlb[evct].mr_pframe & RBIT_MASK;
int val2 = tlb[evct].mr_pframe & MBIT_MASK;
mmu_modify_rbit_bitmap (pfr, val1);
mmu_modify_mbit_bitmap(pfr, val2);
}
// Then, insert the new vpage, pageframe, M bit, and R bit into the
// TLB entry that was just found (and possibly evicted).
tlb[evct].vbit_and_vpage = VBIT_MASK | new_vpage;
tlb[evct].mr_pframe = new_mbit | (new_rbit | new_pframe);
// Finally, set clock_hand to point to the next entry after the
// entry found above.
clock_hand = evct + 1;
}
//Writes the M & R bits in the each valid TLB
//entry back to the M & R MMU bitmaps.
void tlb_write_back()
{
int n;
for (n = 0; n < num_tlb_entries; n++){
if (tlb[n].vbit_and_vpage & VBIT_MASK == 1){
PAGEFRAME_NUMBER pfr = tlb[n].mr_pframe & PFRAME_MASK;
int val1 = tlb[n].mr_pframe & RBIT_MASK;
int val2 = tlb[n].mr_pframe & MBIT_MASK;
mmu_modify_rbit_bitmap (pfr, val1);
mmu_modify_mbit_bitmap(pfr, val2);
}
}
}
I'm getting a segfault from the lines:
tlb[evct].vbit_and_vpage = VBIT_MASK | new_vpage;
tlb[evct].mr_pframe = new_mbit | (new_rbit | new_pframe);
VBIT_MASK is a previously defined variable to mask out the bit I now want to insert. I am not sure if I am misunderstanding how to use bitmasks, or if there is something more seriously wrong with my code. I realize that it would be too much to ask anyone to go through the whole thing in detail, but if anyone had any suggestions for what direction I should be thinking in to fix this, I'd appreciate it!
I draw your attention to how surprisingly low &
is in this table:
$ cat /usr/share/misc/operator
Operator Associativity
-------------------------------------------------------------
() [] -> . left to right
! ~ ++ -- - (type) * & sizeof new delete right to left
->* .* left to right
* / % left to right
+ - left to right
<< >> left to right
< <= > >= left to right
== != left to right
& left to right
^ left to right
| left to right
&& left to right
|| left to right
?: right to left
= += -= *= /= %= <<= >>= &= ^= |= throw right to left
?: (C++, third operand) right to left
, left to right
$FreeBSD: src/share/misc/operator,v 1.2.22.1 2009/05/31 18:14:24 ed Exp $
Segfaults are extremely easy to find, assuming the right tools. Normally I just start gdb
, look at the backtrace and know the reason at once. So, instead of going through your code (which I don't have), I just give you a general recipe to find any segfault (and many other errors):
If you are using GCC on a Linux system, I recommend you to (re-)compile your code with -Wall -g -ggdb -O0
. -Wall
will display interesting warnings, which are often the cause for undefined behavior or segfaults, and -g -ggdb
adds some useful debugging information to your code and -O0
disables optimization (so that counter variables inside loops aren't optimized out and so on).
After that, you should start the debugger with gdb ./yourprog
. Then write run
to start your program. After your program has crashed, you will see something like "got segfault, program exited with ...'. Type bt
which displays a backtrace (i.e. the stack of function calls including the line numbers and so on.). Just look at the list and search for the first top-most file which is part of your program. With that, you will now know the exact location (file and line number) where the segfault is happening, and normally its extremely easy to decide whats the cause if you know the exact line (just think about what might be unitialized or NULL in that statement).
Alternatively, you can also set a breakpoint yourfile.c:123
at that line (in this example line number 123) and display the content of your variables with print your_var_or_pointer
. Examine all variables in that line - now you should finally know whats the cause :D
(PS: I can not give you advice how to debug in other environments such like Visual Studio and so on, but the idea is the same. They all come with an excellent debugger included!)
精彩评论