Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 May 1997 16:05:49 -0700 (PDT)
From:      "Jin Guojun[ITG]" <jin@iss-p4.lbl.gov>
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   kern/3594: EAGAIN and garbage data when reading socket via libc_r
Message-ID:  <199705132305.QAA04151@iss-p4.lbl.gov>
Resent-Message-ID: <199705132310.QAA23060@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         3594
>Category:       kern
>Synopsis:       EAGAIN and garbage data when reading socket via libc_r
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue May 13 16:10:01 PDT 1997
>Last-Modified:
>Originator:     Jin Guojun[ITG]
>Organization:
>Release:        FreeBSD 2.2.1-RELEASE i386
>Environment:

	use libc_r under 2.2.1-RELEASE

>Description:

	When reading socket via the libc_r, the read() return EAGAIN
	(errno = 35) at most time (during heavy data transfer).
	Also, read() returns some garbage data at the begining of the buffer
	in quite-high freqency.

------------- printf in uthread_read.c ---------------

# at socket init status
v = c c000000[26e000], ret 8192[0], err #22:0, status 0
v = 1 84040000[26e000], ret 5036[0], err #22:0, status 135438432
v = 23207468 69207369[26e000], ret 3552[0], err #9:0, status -232977920
v = 23207468 69207369[26e000], ret 0[0], err #9:0, status 11
v = 23202449 68203a64[276000], ret 225[0], err #2:0, status -232977920
v = 23202449 68203a64[276000], ret 0[0], err #2:0, status 135438432
v = 646f6d61 6c096e69[275000], ret 63[0], err #9:0, status -232977920
v = 646f6d61 6c096e69[275000], ret 0[0], err #9:0, status 135438432
v = 24 fffefeff[efbfd060], ret 4[0], err #35:1, status 0
v = 1 1000000[275000], ret 36[0], err #35:1, status 0
NO CONNECTIONS!!!	# below is heavy data transfer

( 0 .. 4e are omitted)

v = 30 30[efbfd04c], ret 4[4], err #35:0, status 251036
v = 4f d000000[31d140], ret 48[4], err #35:0, status 135267194
v = 30 30[efbfd04c], ret 4[4], err #35:0, status 251036
v = 50 d000000[31d140], ret 48[4], err #35:0, status 135267194
v = 30 30[efbfd04c], ret 4[4], err #35:0, status 251036
v = 51 d000000[31d140], ret 48[4], err #35:0, status 135267194
v = 49 e000000[31d140], ret 48[4], err #35:0, status 254166
v = 30 30[efbfd04c], ret 4[4], err #35:0, status 251036
v = 65000000 4a[31d140], ret 48[4], err #35:0, status 135267194
v = b0000000 30[efbfd04c], ret 4[4], err #35:0, status 251036
                                             ^ # of time errors during one rad
                                          ^ errno
                                 ^ nonblock fd flag
                               ^ # byte read
                  ^ user addr
              ^ second word
    ^ 1st word

Program received signal SIGSEGV, Segmentation fault.
0x3bff1 in luBlockMapRecords (skt=17, dir=XDR_DECODE, bm_p=0x26ba00)

------------------ end of printf ---------------------

This is a simple program which is sending two packets repeatly.
(1) a size = 48 (0x30)
(2) a 48-byte block start with a squence ID (0 - N).

We can see, at packet 74 (0x4a), a 4-byte word has been inserted (65000000),
and the squence ID -- 4a -- has been shifted to the second word.

I try to search the EAGAIN in lib/libc and sys/kern directories, it seems
that nowhere can return EAGAIN for reading socket:

# cd /sys
# grep EAGAIN */*.c
kern/kern_fork.c:               return (EAGAIN);
kern/kern_fork.c:               return (EAGAIN);
kern/kern_lockf.c:                      printf("EAGAIN in flock\n");
kern/kern_lockf.c:                      return (EAGAIN);
kern/kern_proc.c:               return EAGAIN;
kern/kern_proc.c:               return EAGAIN;
kern/kern_sysctl.c:     } while (error == EAGAIN);
kern/sys_pipe.c:                                error = EAGAIN;
kern/sys_pipe.c:                                printf("EAGAIN in pipe_read\n");
kern/sys_pipe.c:                                error = EAGAIN;
kern/sysv_msg.c:                                return(EAGAIN);
kern/sysv_msg.c:                        return(EAGAIN);
kern/sysv_sem.c:                 * NOWAIT flag set then return with EAGAIN.
kern/sysv_sem.c:                        return(EAGAIN);
kern/sysv_shm.c:                return EAGAIN;
kern/sysv_shm.c:                        if (error == EAGAIN)
vm/vm_mmap.c:           return (EAGAIN);
vm/vm_mmap.c:           return (EAGAIN);


BTW: above print out has very few EAGAIN error because the printf slow down
	the read() process. However, slow down data receiving rate will
	not affect the garbage been placed in the user buffer.

	So, they could be two seperated problems.

>How-To-Repeat:

	write a simple TCP socket program and try to transmit above data.
	be sure to use -lc_r to link the program.

>Fix:
	
	If someone can point me where the EAGAIN happened, I will track down
	the problem further; otherwise, I have no clue how to fix it.

>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199705132305.QAA04151>