Messages in this thread | | | Date | Tue, 1 Apr 1997 12:15:24 +0200 (SAT) | From | John Carter <> | Subject | mmap can create unkillable processor hog. |
| |
Greetings Kernel guru's,
Avid readers of this list may remember my joy at finding out about the 'mmap' function. I have in fact gone on to create a rather nifty class for using mmap and thence onto a really simple interface for image processing.
In the process I have unearthed a wee kernel bug.
If you mmap a file for output, and then read a memory location that you haven't ever written to... (Yes, I know this was a bug in my own program)... On the first time the program is run, a neat "segment violation" message is written and the program is shutdown quite tidily. Run the program again, (now the output file exists...), and you create an unkillable undead processor hog, which can only be got rid of by a reboot.
I am more than willing to aid the process of resolving this if somebody would tell me where to start...
Background details and program to corner bug. =============================================
I'm running this on a Slackware 3.1 setup, linux-2.0.29, 24Mb memory, 2 GB disks.
The following gets written to the system console.... ====================================================================== Apr 1 11:52:12 models kernel: Unable to handle kernel paging request at virtual address 4012c000 Apr 1 11:52:12 models kernel: current->tss.cr3 = 01486000, Lr3 = 01486000 Apr 1 11:52:12 models kernel: *pde = 00d98067 Apr 1 11:52:12 models kernel: *pte = 00000000 Apr 1 11:52:12 models kernel: Oops: 0000 Apr 1 11:52:12 models kernel: CPU: 0 Apr 1 11:52:12 models kernel: EIP: 0010:[ext2_file_write+585/1116] Apr 1 11:52:12 models kernel: EFLAGS: 00010216 Apr 1 11:52:12 models kernel: eax: 00ffb0cc ebx: 00000400 ecx: 00000100 edx: 0077a000 Apr 1 11:52:12 models kernel: esi: 4012c000 edi: 0077a000 ebp: 00000400 esp: 01492c08 Apr 1 11:52:12 models kernel: ds: 0018 es: 0018 fs: 002b gs: 002b ss: 0018 Apr 1 11:52:12 models kernel: Process mmap (pid: 196, process nr: 43, stackpage=01492000) Apr 1 11:52:12 models kernel: Stack: 00001000 4012c000 4012c000 00053000 00000000 00000000 001e1c90 00000000 Apr 1 11:52:12 models kernel: 00000000 00000138 0004e000 00000000 00ffb0cc ffffffe4 0000010c 0144b87c Apr 1 11:52:12 models kernel: 0144b7c0 0000000c 0144b878 0144b7c0 0144b7c0 00000000 00000000 01492d4c Apr 1 11:52:12 models kernel: Call Trace: [do_truncate+70/120] [do_truncate+90/120] [permission+32/208] [dump_write+28/44] [writenote+167/200] [dump_write+28/44] [elf_core_dump+2484/2632] Apr 1 11:52:12 models kernel: [<02260228>] [tty_write+221/304] [write_chan+0/400] [sys_write+271/328] [do_no_page+0/808] [do_signal+495/632] [signal_return+18/64] Apr 1 11:52:12 models kernel: Code: 64 f3 a5 83 e3 03 89 d9 64 f3 a4 55 8b 54 24 34 8b 52 24 03 ======================================================================
Here is a sample of code that corners the bug... The code mmaps an input file, mmaps and creates and mmaps an output file, and then does a silly read from output array. (Originally the program did a memcpy to copy the input file to the output file.)
====================================================================== #include <sys/mman.h> #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> #include <stdio.h> #include <iostream.h>
main() { int ifd, ofd; struct stat st; char * icp, * ocp;
ifd = open( "mmap.cc", O_RDONLY); if( ifd < 0) { perror( "input file"); return 1; }
fstat( ifd, &st); cout << "Open " << st.st_size << " byte input file.\n"; ofd = open( "mmap.out", O_CREAT | O_RDWR, S_IRWXU); if( ofd < 0) { perror( "output file"); return 1; }
cout << "Opened output file, now truncating file at " << st.st_size << " bytes's.\n"; ftruncate( ofd, st.st_size);
cout << "Truncated file.\n";
icp = (char *)mmap( 0, st.st_size, PROT_READ, MAP_FILE | MAP_SHARED, ifd, 0);
if( icp == (char *)-1) { perror( "input memory map"); return 1; }
cout << "Mapped input file.\n";
ocp = (char *)mmap( 0, st.st_size, PROT_WRITE, MAP_FILE | MAP_SHARED, ofd, 0);
if( ocp == (char *)-1) { perror( "output memory map"); return 1; }
cout << "Mapped output file.\n";
// memcpy( ocp, icp, st.st_size); // Shove data across. cout << "Instead of copying it, I'm going to read byte 11 from the output\n\ memory array. Yip, I know there is nothing there, but that shouldn't\n\ make an killable process out of this.\n"; cout << ocp[ 10] << '\n'; cout << "Read the value.\n";
cout << "Done the mem copy.\n";
munmap( icp, st.st_size);
cout << "Unmapped input array.\n";
munmap( ocp, st.st_size);
cout << "Unmapped output array.\n";
if( close( ifd) < 0) { perror( "close input file"); return 1; }
cout << "Closed input file.\n";
if( close( ofd) < 0) { perror( "close output file"); return 1; }
cout << "Closed output file.\n"; } ======================================================================
John Carter EMail: ece@dwaf-hri.pwv.gov.za Telephone : 27-12-808-0374x194 Fax:- 27-12-808-0338
Founder of the Council for Unnatural Scientists.
| |