为什么我从以下 C 代码中收到段错误?

发布于 2024-10-31 21:04:51 字数 2388 浏览 0 评论 0原文

我的操作系统类中有一个项目,我应该在其中模拟翻译后备缓冲区。

我正在编写一个将在 TLB 未命中后调用的方法。它应该找到 TLB 中的下一个条目,该条目要么为空,要么有一段时间没有被命中,删除该条目,并将其替换为上次调用的页表中的条目。页表项中的数据在调用该方法时给出。

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); 
    }   
    } 
  } 

我从以下行中收到段错误:

tlb[evct].vbit_and_vpage = VBIT_MASK | new_vpage;
tlb[evct].mr_pframe = new_mbit | (new_rbit | new_pframe); 

VBIT_MASK 是一个先前定义的变量,用于屏蔽我现在要插入的位。我不确定我是否误解了如何使用位掩码,或者我的代码是否存在更严重的错误。我意识到要求任何人详细地完成整个事情就太过分了,但是如果有人对我应该考虑朝什么方向解决这个问题有任何建议,我将不胜感激!

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 is 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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

绾颜 2024-11-07 21:04:51

我提请您注意此表中 & 的值是多么低:

$ 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 $

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 $
屌丝范 2024-11-07 21:04:51

只要使用正确的工具,段错误就非常容易找到。通常我只是启动gdb,查看回溯并立即知道原因。因此,我不会检查您的代码(我没有),而是为您提供一个查找任何段错误(以及许多其他错误)的通用方法:

如果您在 Linux 系统上使用 GCC,我建议您(使用 -Wall -g -ggdb -O0 重新)编译您的代码。 -Wall 将显示有趣的警告,这通常是未定义行为或段错误的原因,并且 -g -ggdb 向您的代码添加一些有用的调试信息,并且 - O0 禁用优化(以便循环内的计数器变量不会被优化等等)。

之后,您应该使用 gdb ./yourprog 启动调试器。然后编写run来启动你的程序。程序崩溃后,您将看到类似“出现段错误,程序因...退出”的内容。输入 bt 显示回溯(即包含行号等的函数调用堆栈) .)。只需查看列表并搜索程序中第一个最顶层的文件,您现在就可以知道发生段错误的确切位置(文件和行号),并且通常情况下是这样。如果您知道确切的行,则很容易确定原因是什么(只需考虑该语句中可能未初始化或 NULL 的内容)

或者,您也可以在该行设置一个 断点 yourfile.c:123 。 (在此示例中,第 123 行)并使用 print your_var_or_pointer 显示变量的内容 检查该行中的所有变量 - 现在您终于应该知道原因是什么了:D

(PS:我不能给出)您建议如何在其他环境(如 Visual Studio 等)中进行调试,但想法是相同的,它们都附带了出色的调试器!)

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!)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文