A Hang Problem Involving Locked Records
>>> Problem: Program "Pain" running in Slot 4d is hung with a blank
>>> screen. Everything else in the system seems OK. Mouse moves, we
>>> can change focus and so on..
>>> Lets take a look at slot 4d.
# .p 4d
Slot Pid Ppid Csid Ord Sta Pri pTSD pPTDA pTCB Disp SG Name
004d# 001c 001b 001c 0001 blk 0300 ab80f000 ab99e220 ab980620 1e60 1d PAIN
>>> Blocked!
>>> We can approach this two ways:
>>> 1) Take a look at what the application did
>>> 2) Take a look at the BlockId and try see how far the system got
>>> Looking at the application we examine its registers and determine
>>> what API it called to cause it to block.
# .s 4d
Current slot number: 004d
# .r
eax=00023305 ebx=00000000 ecx=00000006 edx=0002004f esi=00000000 edi=00000000
eip=00010181 esp=0002337c ebp=000233fc iopl=2 -- -- -- nv up ei pl zr na pe nc
cs=005b ss=0053 ds=0053 es=0053 fs=150b gs=0000 cr2=00000000 cr3=001d9000
005b:00010181 83c414 add esp,+14
# u %eip-10
%00010171 e8508d45e0 call %e0468ec6
%00010176 50 push eax
%00010177 ff75f8 push dword ptr [ebp-08]
%0001017a b005 mov al,05
%0001017c e8c762f81b call %1bf96448
%00010181 83c414 add esp,+14
%00010184 0bc0 or eax,eax
%00010186 7404 jz %0001018c
%00010188 ebde jmp %00010168
%0001018a 8bc0 mov eax,eax
%0001018c b858000200 mov eax,00020058
%00010191 e8fa000000 call %00010290
# ln %1bf96448
%1bf96448 DOSCALL1 DOS32SETFILELOCKS
>>> The last call was to DosSetFileLocks and we haven't returned. If
>>> we want any more information we have to analyse the BlockId.
# .pb#
Slot Sta BlockID Name Type Addr Symbol
004d# blk 00b80029 PAIN
# .m 0b8:29
*har par cpg va flg next prev link hash hob hal
00dd %feaf0308 00000010 %aa7a3000 129 00dc 00de 0000 00cb 00ea 0000 sel=00b8
hob har hobnxt flgs own hmte sown,cnt lt st xf
00ea 00dd 0000 0124 ff47 0000 0000 00 00 00 00 fsreclok
>>> Seems to be blocked on a File System Record Lock (RLR).
>>> This implies that someone else has already locked a
>>> conflicting record range.
>>> We need to dump the RLR and locate the System File Table Entry
>>> associated with it. The BlockId is the address of the RLR.
# dw 0b8:29
00b8:00000029 0000 0000 0020 0000 002f 0000 526b 00d0
00b8:00000039 0000 0018 0000 0002 0000 2000 0000 2f00
00b8:00000049 0000 2000 9806 29ab 1c00 0300 0000 006e
00b8:00000059 0000 0000 0000 0000 0000 0000 0000 0000
00b8:00000069 0000 0000 8500 0000 0000 0000 0000 0000
00b8:00000079 0000 0000 0000 0000 0000 0000 009c 0000
00b8:00000089 0000 0000 0000 0000 0000 0000 0000 0000
00b8:00000099 0000 b300 0000 0000 0000 0000 0000 0000
>>> RLR+c is a far16 pointer to the associated System File Table entry
>>> (SFT).
>>> RLR+4 and RLR+8 are the range of bytes locked. Offset +20 - +2f
>>> has been locked.
>>> We now format the SFT for the process that locked this range:
# .d sft d0:526b
sf_ref_count: 0001 sfi_mode: 0042
sf_usercnt: 0000 sfi_hVPB: 04e0
reserved: 00 sfi_ctime: 0000
sf_flags(2): 0040:0000 sfi_cdate: 0000
sf_devptr: #0000:04e0 sfi_atime: 0000
sf_FSC: #0000:ff40 sfi_adate: 0000
sf_chain: #0000:0000 sfi_mtime: 5df6
sf_MFT: fe87ca0c sfi_mdate: 1f3a
sfdFAT_firFILEclus: 0197 sfi_size: 00000061
sfdFAT_cluspos: 0000 sfi_position: 00000030
sfdFAT_lstclus: 0197 sfi_UID: 0000
sfdFAT_dirsec: 0000009f sfi_PID: 0018
sfdFAT_dirpos: 0a sfi_PDB: 0000
sfdFAT_name: VIN sfi_selfsfn: 00a1
sfdFAT_EAHandle: 0000 sfi_tstamp: 00
sf_plock: 0000 sfi_DOSattr: 20
sf_NmPipeSfn: 0000
sf_codepage: 0000
>>> The SFT contains a pointer to the MFT, which contains the fully
>>> qualified file name. If the file is FAT then the short name in the
>>> SFT is also meaningful.
# .d mft % fe87ca0c
mft_ksem:
Signature : KSEM Nest: 0000
Type : SHARE Readers: 0000
Flags : 01 PendingReaders: 0000
Owner : 0000 PendingWriters: 0000
mft_lptr: 0029 mft_sptr: 00d0:5600
mft_pCMap: 00000000 mft_serl: 128f
mft_CMapKSem:
mft_hvpb: 466d mft_opflags: 0000 mft_flags: 0000
mft_name: A:\LAB19\VIN
>>> So the locked File is a:\lab19\vin
>>> The SFT also contains the Pid of the process that opened, and in
>>> this case locked, this file - Pid 18
# .p
Slot Pid Ppid Csid Ord Sta Pri pTSD pPTDA pTCB Disp SG Name
0001 0001 0000 0000 0001 blk 0100 ffe3a000 ffe3ca00 ffe3c800 1e7c 00 *ager
0002 0001 0000 0000 0002 blk 0200 ab779000 ffe3ca00 ab977020 1f3c 00 *tsd
0003 0001 0000 0000 0003 blk 0200 ab77b000 ffe3ca00 ab977220 1f50 00 *ctxh
0004 0001 0000 0000 0004 blk 081f ab77d000 ffe3ca00 ab977420 1f48 00 *kdb
0005 0001 0000 0000 0005 blk 0800 ab77f000 ffe3ca00 ab977620 1f20 00 *lazyw
0006 0001 0000 0000 0006 blk 0800 ab781000 ffe3ca00 ab977820 1f3c 00 *asyncr
0009 0002 0000 0002 0001 rdy 0804 ab787000 ab997020 ab977e20 1c88 00 CNTRL
0008 0002 0000 0002 0002 blk 0804 ab785000 ab997020 ab977c20 00 CNTRL
000b 0002 0000 0002 0003 blk 0804 ab78b000 ab997020 ab978220 00 CNTRL
000c 0002 0000 0002 0004 rdy 0804 ab78d000 ab997020 ab978420 1c9c 00 CNTRL
000a 0003 0000 0003 0001 blk 0800 ab789000 ab997620 ab978020 00 DOSCTL
000d 0004 0001 0004 0001 rdy 0500 ab78f000 ab997c20 ab978620 1ed0 01 PMSHL32
000f 0004 0001 0004 0002 blk 0800 ab793000 ab997c20 ab978a20 1ed4 01 PMSHL32
0010 0004 0001 0004 0003 blk 0800 ab795000 ab997c20 ab978c20 01 PMSHL32
0011 0004 0001 0004 0004 blk 0800 ab797000 ab997c20 ab978e20 01 PMSHL32
0012 0004 0001 0004 0005 blk 0800 ab799000 ab997c20 ab979020 01 PMSHL32
0015 0004 0001 0004 0006 blk 0200 ab79f000 ab997c20 ab979620 1edc 01 PMSHL32
0016 0004 0001 0004 0007 blk 0200 ab7a1000 ab997c20 ab979820 1edc 01 PMSHL32
0017 0004 0001 0004 0008 blk 0200 ab7a3000 ab997c20 ab979a20 01 PMSHL32
0007 0004 0001 0004 0009 blk 0500 ab783000 ab997c20 ab977a20 01 PMSHL32
0018 0004 0001 0004 000a blk 0800 ab7a5000 ab997c20 ab979c20 01 PMSHL32
0019 0004 0001 0004 000b blk 0800 ab7a7000 ab997c20 ab979e20 1eb8 01 PMSHL32
001a 0004 0001 0004 000c blk 0800 ab7a9000 ab997c20 ab97a020 1eb8 01 PMSHL32
Slot Pid Ppid Csid Ord Sta Pri pTSD pPTDA pTCB Disp SG Name
001b 0004 0001 0004 000d blk 0804 ab7ab000 ab997c20 ab97a220 1ea8 01 PMSHL32
001c 0004 0001 0004 000e blk 0804 ab7ad000 ab997c20 ab97a420 1eb0 01 PMSHL32
001d 0004 0001 0004 000f blk 0500 ab7af000 ab997c20 ab97a620 1ea8 01 PMSHL32
001e 0004 0001 0004 0010 blk 0801 ab7b1000 ab997c20 ab97a820 1bac 01 PMSHL32
001f 0004 0001 0004 0011 blk 0801 ab7b3000 ab997c20 ab97aa20 01 PMSHL32
0020 0004 0001 0004 0012 blk 0801 ab7b5000 ab997c20 ab97ac20 01 PMSHL32
0021 0004 0001 0004 0013 blk 0800 ab7b7000 ab997c20 ab97ae20 01 PMSHL32
0022 0004 0001 0004 0014 blk 0800 ab7b9000 ab997c20 ab97b020 1b80 01 PMSHL32
0024 0004 0001 0004 0015 blk 0200 ab7bd000 ab997c20 ab97b420 1ed0 01 PMSHL32
0030 0004 0001 0004 0016 blk 0800 ab7d5000 ab997c20 ab97cc20 1eac 01 PMSHL32
004c 001b 0004 001b 0001 blk 0400 ab80d000 ab99dc20 ab980420 1ed4 1d CMD
004b 001a 0004 001a 0001 blk 0200 ab80b000 ab99d620 ab980220 1eb8 1c CMD
004a 0019 0004 0019 0001 blk 0200 ab809000 ab99d020 ab980020 1eb8 14 CMD
0048 0017 0004 0017 0001 blk 0200 ab805000 ab99a620 ab97fc20 1ed4 04 CMD
0047 0014 0004 0014 0001 blk 0200 ab803000 ab99c420 ab97fa20 1eb8 11 CMD
003d 0012 0004 0012 0001 blk 0200 ab7ef000 ab99be20 ab97e620 1ed0 1a IBMAVSD
0046 0011 0004 0011 0001 blk 0200 ab801000 ab99b820 ab97f820 1ed0 19 FPWMON
003a 0010 0004 0010 0001 blk 0200 ab7e9000 ab99b220 ab97e020 1ed0 18 PMFAX
0041 0010 0004 0010 0002 blk 0800 ab7f7000 ab99b220 ab97ee20 1edc 18 PMFAX
0043 0010 0004 0010 0003 blk 0500 ab7fb000 ab99b220 ab97f220 18 PMFAX
0045 0010 0004 0010 0005 blk 0500 ab7ff000 ab99b220 ab97f620 1d24 18 PMFAX
0039 000f 0004 000f 0001 blk 0200 ab7e7000 ab99ac20 ab97de20 1ed0 17 FPWPIMX
0040 000f 0004 000f 0002 blk 0200 ab7f5000 ab99ac20 ab97ec20 1ed0 17 FPWPIMX
0042 000f 0004 000f 0003 blk 0200 ab7f9000 ab99ac20 ab97f020 1ed0 17 FPWPIMX
Slot Pid Ppid Csid Ord Sta Pri pTSD pPTDA pTCB Disp SG Name
0038 000e 0004 000e 0001 blk 0200 ab7e5000 ab99a020 ab97dc20 1ed0 16 DINFO
003f 000e 0004 000e 0002 blk 0500 ab7f3000 ab99a020 ab97ea20 1f00 16 DINFO
0037 000d 0004 000d 0001 blk 0200 ab7e3000 ab999a20 ab97da20 1ed0 15 MRFILE32
003e 000d 0004 000d 0002 blk 0200 ab7f1000 ab999a20 ab97e820 15 MRFILE32
0033 000c 0004 000c 0001 blk 0200 ab7db000 ab998e20 ab97d220 1ed0 13 PULSE
*003b 000c 0004 000c 0002 run 0100 ab7eb000 ab998e20 ab97e220 1f28 13 PULSE
003c 000c 0004 000c 0003 blk 081f ab7ed000 ab998e20 ab97e420 1f00 13 PULSE
0026 0008 0004 0008 0001 blk 0500 ab7c1000 ab999420 ab97b820 1ed0 12 PMSHL32
002d 0008 0004 0008 0002 blk 0200 ab7cf000 ab999420 ab97c620 1edc 12 PMSHL32
002e 0008 0004 0008 0003 blk 0200 ab7d1000 ab999420 ab97c820 12 PMSHL32
002f 0008 0004 0008 0004 blk 0200 ab7d3000 ab999420 ab97ca20 1ed0 12 PMSHL32
0028 0008 0004 0008 0005 blk 0200 ab7c5000 ab999420 ab97bc20 12 PMSHL32
0025 0008 0004 0008 0006 blk 0200 ab7bf000 ab999420 ab97b620 1edc 12 PMSHL32
002c 0008 0004 0008 0007 blk 0200 ab7cd000 ab999420 ab97c420 1ed0 12 PMSHL32
0031 0008 0004 0008 0008 blk 0500 ab7d7000 ab999420 ab97ce20 1edc 12 PMSHL32
0032 0008 0004 0008 0009 blk 0200 ab7d9000 ab999420 ab97d020 1edc 12 PMSHL32
0034 0008 0004 0008 000b blk 0500 ab7dd000 ab999420 ab97d420 12 PMSHL32
0035 0008 0004 0008 000c blk 0200 ab7df000 ab999420 ab97d620 1eac 12 PMSHL32
0036 0008 0004 0008 000d blk 0500 ab7e1000 ab999420 ab97d820 1eb8 12 PMSHL32
0044 0008 0004 0008 000e blk 0200 ab7fd000 ab999420 ab97f420 1ed0 12 PMSHL32
0023 0006 0004 0006 0001 blk 0200 ab7bb000 ab998820 ab97b220 10 PMSPOOL
0027 0006 0004 0006 0002 blk 0500 ab7c3000 ab998820 ab97ba20 10 PMSPOOL
0029 0006 0004 0006 0003 blk 0200 ab7c7000 ab998820 ab97be20 10 PMSPOOL
002a 0006 0004 0006 0004 blk 0500 ab7c9000 ab998820 ab97c020 10 PMSPOOL
Slot Pid Ppid Csid Ord Sta Pri pTSD pPTDA pTCB Disp SG Name
002b 0006 0004 0006 0005 blk 0500 ab7cb000 ab998820 ab97c220 10 PMSPOOL
000e 0005 0004 0005 0001 blk 0800 ab791000 ab998220 ab978820 00 HARDERR
0013 0005 0004 0005 0002 blk 0800 ab79b000 ab998220 ab979220 00 HARDERR
0014 0005 0004 0005 0003 blk 0800 ab79d000 ab998220 ab979420 00 HARDERR
0049 0018 0017 0018 0001 blk 0200 ab807000 ab99ca20 ab97fe20 1cd4 04 FROMAGE
004d# 001c 001b 001c 0001 blk 0300 ab80f000 ab99e220 ab980620 1e60 1d PAIN
>>> Pid 18 is evidently FROMAGE.
>>> FROMAGE has the VIN and PAIN wants it!
>>> We had better find out why FROMAGE has blocked.
# .s 49
Current slot number: 0049
# .r
eax=00000001 ebx=00020366 ecx=1bf90000 edx=00020004 esi=13fa0000 edi=13fa1052
eip=0000a0c3 esp=0000324a ebp=00023270 iopl=2 -- -- -- nv up ei ng nz ac pe cy
cs=dfdf ss=0017 ds=9fe7 es=9fe7 fs=150b gs=0000 cr2=00000000 cr3=001d9000
Invalid linear address: dfdf:0000a0c3
# ln
dfdf:0000a053 DOSCALL1 GetCharIn + 70
>>> Looking at this from the application aspect may be difficult since
>>> some of the code has been paged out (The invalid linear address
>>> message).
>>> The near symbol gives a clue. We could try unwinding the stack and
>>> hope that the stack is still paged in.
# dw %ebp
%00023270 b17e dfdf 9fe7 0000 0000 a97a dfdf 0000
%00023280 0000 0366 9fe7 a8ec a48d 1052 a399 32a6
%00023290 203c 0053 9fdf 1052 1052 32c8 32a6 0360
%000232a0 0007 4fa8 32b4 b1f0 dfdf 9fd7 0000 0005
%000232b0 bb2b dfd7 0000 0000 1044 9fd7 1052 9fd7
%000232c0 32c8 0002 0053 1bf9 32f0 0002 1cba 1bf9
%000232d0 0000 0000 0000 0000 1044 13fa 1052 13fa
%000232e0 0000 0000 0360 0002 0360 0002 0042 0008
# d
%000232f0 3334 0002 78cd 0001 0000 0000 0000 0009
%00023300 1000 0000 3330 0002 0000 0000 0360 0002
%00023310 0360 0002 0000 0002 0000 0000 0000 0000
%00023320 0000 0000 0000 0000 0000 0000 0000 0000
%00023330 7000 ab80 3388 0002 2abc 0001 0360 0002
%00023340 0000 0009 1000 0000 33f0 0002 0029 0000
%00023350 0020 0000 0001 0000 0000 0000 0000 0000
%00023360 0000 0000 3388 0002 02c5 0001 339c 0002
>>> This is going to be haphazard. Evidently the code we are currently
>>> executing is not using EBP as a stack frame pointer. All we can do
>>> is scan through the stack looking for a likely stack frame or a
>>> return address to user code.
>>> %232f0 looks like a candidate. Let's unassemble the return address
>>> to see if it makes sense.
# u %178cd-10
%000178bd 03ca add ecx,edx
%000178bf 51 push ecx
%000178c0 8b5d08 mov ebx,dword ptr [ebp+08]
%000178c3 ff7320 push dword ptr [ebx+20]
%000178c6 b004 mov al,04
%000178c8 e83ba3f71b call %1bf91c08
%000178cd 83c410 add esp,+10
%000178d0 8bc8 mov ecx,eax
%000178d2 0bc0 or eax,eax
%000178d4 741b jz %000178f1
%000178d6 824b0802 or byte ptr [ebx+08],02
%000178da c705e81302003c000000 mov dword ptr [000213e8],0000003c
# ln %1bf91c08
%1bf91c08 DOSCALL1 DOS32READ
>>> So far so good. We need to see if this is consistent with the
>>> BlockId, which is the most up-to-date status indicator for this
>>> process.
# .pb#
Slot Sta BlockID Name Type Addr Symbol
0049# blk 05100604 FROMAGE
# .m 0510:0604
*har par cpg va flg next prev link hash hob hal
0003 %feaef04c 00000400 %fe6ef000 001 0002 0023 0000 0000 0003 0000 =0000
hob har hobnxt flgs own hmte sown,cnt lt st xf
0003 0003 fec5 0000 ffec 0000 0000 00 01 00 00 vmkrhrw
>>> This blockid points to data within the kernel resident read/write
>>> heap. Heap blocks have headers that tell us more about the user of
>>> the data. The data portion of a help block is usually mapped to a
>>> GDT selector. In this example, selector 510. 510:0 should
>>> be the address of the beginning of the data and therefore point
>>> just after the end of the header. We look at the data before
>>> 510:0 to see the heap block header.
# dg 510
0510 Data Bas=fe6f3000 Lim=00000b2a DPL=0 P RW A
# dd % fe6f3000-10
%fe6f2ff0 ffa4000c feaeef28 0002036f 00000b39
%fe6f3000 05000000 0000c981 424b2d29 20202444
%fe6f3010 05182020 00000510 00020000 00000000
%fe6f3020 a8030ec8 424b0170 19002444 00000000
%fe6f3030 00000000 00000000 00000000 00000000
%fe6f3040 00000000 00061400 001b0014 0a000003
%fe6f3050 00028101 81010500 0a000001 0003c747
%fe6f3060 00000000 00000000 00000000 00000000
>>> For resident heaps the header is a double-word. This one begins
>>> at %fe6f2ffc. The low 2 bits are flags, the remainder is the
>>> length of the heap block in double-words.
>>> If the flag bit 0 is 1 then this is an extended heap. Which it is.
>>> We need to look at the header extension at the end of the block.
>>> The length of the block in bytes is b38 (by mentaly AND-ing b39
>>> and 0xffc)
# dd % fe6f3000-4+b38-10
%fe6f3b24 ffff0000 0000ffff ff530510 ff77bd64
%fe6f3b34 ffc2001c 00000008 00000000 00000000
%fe6f3b44 ab240001 4d5000a6 00005854 ff9e0014
%fe6f3b54 001b0083 fe6f3b80 fe701da0 fe8777b0
%fe6f3b64 ffa4000c fe6f3b74 000102e9 ffa4000c
%fe6f3b74 fe7ea73c 0001071f ff9e0014 001b005d
%fe6f3b84 fe83baa8 fe876eac fe877654 ffc2001c
%fe6f3b94 00000008 00000000 00000000 da680001
>>> The header extension is in the last 2 double-words of the heap
>>> block. The owner Id and the selector are in the first of these (at
>>> %fe6f3b2c).
# .mo ff53
ff53 dd4
>>> This tells us selector 510 was allocated by, or is part of the 4th
>>> device driver to initialise. Listing the physical device driver
>>> MTEs will find this. They are listed last initialised first.
>>> Note: frequently we find that dd16 is the owner. This refers to
>>> all device drivers from the 16th and subsequent. The first 15
>>> device drivers to initialise are assigned unique owner ids from
>>> dd1 to dd15, where the numbers are in decimal.
# .lmp
hmte=0249 pmte=%fe848df4 mflags=0008f1c9 h:\faxpro\fmd.sys
hmte=0242 pmte=%fe856f04 mflags=0008f1c9 c:\os2tools\theseus2.sys
hmte=0240 pmte=%fe848e7c mflags=0008f1c9 c:\os2\vdisk.sys
hmte=0235 pmte=%fe848f58 mflags=0008f1c9 h:\os2\apps\sysios2.sys
hmte=0234 pmte=%fe848f08 mflags=0008f1c9 h:\tcpip\bin\ifndisnl.sys
hmte=011e pmte=%fe83ff84 mflags=0008f1c9 h:\tcpip\bin\inet.sys
hmte=012b pmte=%fe83996c mflags=0008f1c9 h:\mmos2\r0stub.sys
hmte=012a pmte=%fe839da0 mflags=0000f1c1 h:\mmos2\ssmdd.sys
hmte=0123 pmte=%fe83df4c mflags=8008f1c9 c:\os2\com.sys
hmte=0121 pmte=%fe839e64 mflags=8008f1c9 h:\os2\boot\mouse.sys
hmte=0120 pmte=%fe839ef4 mflags=8008f1c9 h:\os2\boot\pointdd.sys
hmte=011d pmte=%fe83afdc mflags=8008f1c9 h:\os2\boot\os2cdrom.dmd
hmte=0111 pmte=%fe83af88 mflags=8008f1ca h:\os2\boot\pmdd.sys
hmte=0087 pmte=%fe839fdc mflags=0008f1c9 h:\os2\boot\dos.sys
hmte=0089 pmte=%fe839f80 mflags=8008f1c9 h:\os2\boot\testcfg.sys
hmte=0103 pmte=%fe71095c mflags=0008f1c9 i:\brew\os20memu.sys
hmte=00e2 pmte=%fe6fefc4 mflags=8008e1c9 h:\os2scsi.dmd
hmte=00e1 pmte=%fe6fdf64 mflags=8008e1c9 h:\os2dasd.dmd
hmte=00de pmte=%fe6f6fb0 mflags=0008e1c9 h:\xdfloppy.flt
hmte=00a9 pmte=%fe6f5fb0 mflags=8008e1c9 h:\fd16-700.add
hmte=00a7 pmte=%fe6f4f3c mflags=8008e1c9 h:\ibm1s506.add
hmte=00a5 pmte=%fe6f3db4 mflags=8008e1c9 h:\ibm1flpy.add
hmte=009c pmte=%feaeeea0 mflags=8008e1c9 h:\print01.sys
hmte=009b pmte=%fe6f1fb8 mflags=8008e1c9 h:\ibmkbd.sys
hmte=009a pmte=%feaeeed8 mflags=8008e1c9 h:\kbdbase.sys
hmte=0099 pmte=%feaeef34 mflags=0008e1c9 h:\screen01.sys
hmte=0098 pmte=%feaeefc0 mflags=8008e1c9 h:\clock01.sys
hmte=0096 pmte=%fe6f1fdc mflags=0008e1c9 h:\resource.sys
>>> Counting backwards, the 4th device driver is kbdbase.sys.
>>> We dump its object table.
# .lmo 9a
hmte=009a pmte=%feaeeed8 mflags=8008e1c9 h:\kbdbase.sys
seg sect psiz vsiz hob sel flags
0001 0001 158c 170e 0000 0510 8c41 data prel
0002 000c 3270 3270 0000 0518 8d60 code shr prel rel
0003 0026 1987 1988 0000 0520 8d60 code shr prel rel
0004 0033 0743 0744 0000 0528 8d60 code shr prel rel
>>> Selector 510 is indeed the first data selector of kbdbase.sys and
>>> will contain the device driver header at offset +0
# .d dev 510:0
DevNext: 0500:0000
DevAttr: c981
DevStrat: 0000
DevInt: 2d29
DevName: KBD$
DevProtCS: 0518
DevProtDS: 0510
DevRealCS: 0000
DevRealDS: 0000
>>> We conclude that FROMAGE is waiting for the device driver to
>>> respond to the DosRead - i.e. A keyboard interrupt
[Back: The Record Lock Record]
[Next: Exploring Memory Management]