You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
before sys_write is run, the interrupt is enabled, so after breaking at sys_write, you had better use set $sstatus = a new value to modify the register sstatus to disable all interrupts (timer interrupt is annoying when debugging) , but this method seems not working ???
1. indeed, this method can disable timer interrupt
2. After I set the value of $sstatus to disable interrupts (refer to intr_off()), I come across another interrupt kernel/trap.c:devintr() ==> virtio_disk_intr() , why ???
there are several CPUs, so modifying the sstatus to disable interrupts only works on one CPU ???
(gdb) info threads
Id Target Id Frame
* 1 Thread 1.1 (CPU#0 [running]) acquire (lk=lk@entry=0x8000e478 <proc+22080>)
at kernel/spinlock.c:63
2 Thread 1.2 (CPU#1 [running]) 0x00000000800067bc in release (
lk=lk@entry=0x8000b398 <proc+9568>) at kernel/spinlock.c:98
3 Thread 1.3 (CPU#2 [running]) 0x00000000800024b8 in bwrite (
b=b@entry=0x8000eed8 <bcache+1152>) at kernel/bio.c:118
solution:
https://pdos.csail.mit.edu/6.1810/2023/labs/traps.html
It will be easier to look at traps with gdb if you tell qemu to use only one CPU, which you can do by running
make CPUS=1 qemu-gdb
===============================
when you enter "make qemu-gdb", you can see the following infomation about file system:
nmeta 46 (boot, super, log blocks 30 inode blocks 13, bitmap blocks 1) blocks 1954 total 2000
balloc: first 915 blocks have been allocated
balloc: write bitmap block at sector 45
==============================
// In writei(), after executing bmap(), we have the "log"
(gdb) p log
$24 = {lock = {locked = 0, name = 0x800084f0 "log", cpu = 0x0, nts = 0, n = 46},
start = 2, size = 30, outstanding = 1, committing = 0, dev = 1, lh = {n = 2, block = {
45, 915, 32, 0 <repeats 27 times>}}}
log.lh.block[0] is 45 which indicates the 45th block that stores the bitmap, log.lh.block[1] is 915 which indicates the 915-th block that stores data
=============================
In writei(), after executing either_copyin(), we can see that "hi" has been written into bp->data, (bp->blockno is 915)
(gdb) p *bp
$36 = {valid = 1, disk = 0, dev = 1, blockno = 915, lock = {locked = 1, lk = {locked = 0,
name = 0x80008540 "sleep lock", cpu = 0x0, nts = 0, n = 7},
name = 0x800083d0 "buffer", pid = 3}, refcnt = 2, prev = 0x800104b8 <bcache+6752>,
next = 0x8000ea78 <bcache+32>, data = "hi", '\000' <repeats 1021 times>}
===========================
after kernel/fs.c: writei() ---> iupdate() ----> log_write(), now log.lh.n is 3, log.lh.block[2] is 33 which indicates the 33-th block contains the dinode that is updated
now we get kernel/file.c:filewrite() ---> end_op() ---> commit()
in write_log():
copy from the buffer of block 45(bitmap) to block 3 (log)
copy from the buffer of block 915(data block containing "hi") to block 4 (log)
copy from the buffer of block 33(dinode block) to block 5 (log)
in write_head():
copy log.lh to block 2
in install_trans(int recovering):
copy from block 3 to block 45
copy from block 4 to block 915
copy from block 5 to block 33
then erase the transaction from the log
log.lh.n = 0;
write_head();
The text was updated successfully, but these errors were encountered:
In step 2, open("x", ...) also modifies the file system, let's check it, switch to kernel/kernel, set a breakpoint at usertrap or sys_open
OccupyMars2025
changed the title
[not solved] what's the step-by-step execution flow of the command "$ echo hi > x"
[solved] what's the step-by-step execution flow of the command "$ echo hi > x"
Mar 31, 2024
step 1:
make clean
step 2:
make CPUS=1 qemu-gdb
step 3: disable all interrupts
step 4:
(gdb) info threads
, only one threadHow the ">" symbol works
https://pdos.csail.mit.edu/6.1810/2023/lec/l-fs.txt
If I break at user/echo.c:main, I only see "echo", "hi" in argv, and argc is 2, where does the " > x " part go ?
===============================
before sys_write is run, the interrupt is enabled, so after breaking at sys_write, you had better use
set $sstatus = a new value
to modify the registersstatus
to disable all interrupts (timer interrupt is annoying when debugging) , but this method seems not working ???1. indeed, this method can disable timer interrupt
2. After I set the value of $sstatus to disable interrupts (refer to intr_off()), I come across another interrupt
kernel/trap.c:devintr() ==> virtio_disk_intr()
, why ???there are several CPUs, so modifying the
sstatus
to disable interrupts only works on one CPU ???solution:
===============================
when you enter "make qemu-gdb", you can see the following infomation about file system:
==============================
log.lh.block[0] is 45 which indicates the 45th block that stores the bitmap, log.lh.block[1] is 915 which indicates the 915-th block that stores data
=============================
In writei(), after executing either_copyin(), we can see that "hi" has been written into bp->data, (bp->blockno is 915)
===========================
after kernel/fs.c: writei() ---> iupdate() ----> log_write(), now log.lh.n is 3, log.lh.block[2] is 33 which indicates the 33-th block contains the dinode that is updated
==========================
now we get kernel/file.c:filewrite() ---> end_op() ---> commit()
in write_log():
in write_head():
in install_trans(int recovering):
then erase the transaction from the log
The text was updated successfully, but these errors were encountered: