From: Prakash on
Hello,

I am migrating an c application from Solaris to RHEL 5.x x86_64
platform.

Here are the platform details:
-------------------------------------------
1. OS: Red Hat Linux 5.x, kernel 2.6.x
2. gcc compiler : 4.1.2.x V

ioctl() call on Linux returning "Bad Address". I have
simulated the problem with below sample program. Can I know what is
going wrong on Linux with this program.

1. Here is the sample program to simulate the problem

/* Sample program to test the ioctl() call which sets the read mode to
message-nondiscard mode.
* For some reason this sample is not working on Linux x84_64, gcc :
4.1.x V and Red Hat 5.x.
* However this code works on Solaris SPARC.
*/

# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <fcntl.h>
# include <sys/ioctl.h>
# include <sys/socket.h>
# include <sys/types.h>
# include <errno.h>
# include <stropts.h> /* macros I_SRDOPT and RMSGN are defined */

int
main(){

int fd[2];

int fd_read;
int fd_write;

fd_read= fd_write = -1; /* Initila value */

/* Create unnamed socket pairs */
if ( socketpair(AF_UNIX, SOCK_STREAM,0,fd) == -1 ){
perror("socketpair");
exit(1);
}

fd_read = fd[0];
fd_write = fd[1];

/* fcntl code comes here to set non blocking read */

/* set read mode to message -nondiscard mode */
if ( ioctl(fd_read, I_SRDOPT, RMSGN ) )
perror("ioctl");

return 0;

}/* main() ends */
~
========================================================

2. I ran the program using strace. Here is the output.
=========================================================
strace ./a.out
execve("./a.out", ["./a.out"], [/* 23 vars */]) = 0
uname({sys="Linux", node="smt-linux2", ...}) = 0
brk(0) = 0x8b18000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or
directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=71234, ...}) = 0
old_mmap(NULL, 71234, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f21000
close(3) = 0
open("/lib/tls/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\320\36h
\0004\0\0\0"..., 512) = 512 fstat64(3, {st_mode=S_IFREG|0755,
st_size=1529136, ...}) = 0 old_mmap(0x66d000, 1227964, PROT_READ|
PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x66d000
old_mmap(0x793000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|
MAP_DENYWRITE, 3, 0x125000) = 0x793000 old_mmap(0x797000, 7356,
PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) =
0x797000
close(3) = 0
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
-1, 0) = 0xb7f20000
mprotect(0x793000, 8192, PROT_READ) = 0
mprotect(0x669000, 4096, PROT_READ) = 0
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7f20940, limit:
1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1,
seg_not_present:0, useable:1}) = 0
munmap(0xb7f21000, 71234) = 0
socketpair(PF_FILE, SOCK_STREAM, 0, [3, 4]) = 0
ioctl(3, CDROMREADTOCENTRY, 0x2) = -1 EFAULT (Bad address)
dup(2) = 5
fcntl64(5, F_GETFL) = 0x8002 (flags O_RDWR|
O_LARGEFILE)
brk(0) = 0x8b18000
brk(0x8b39000) = 0x8b39000
fstat64(5, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,
0) = 0xb7f32000
_llseek(5, 0, 0xbfe58830, SEEK_CUR) = -1 ESPIPE (Illegal seek)
write(5, "ioctl: Bad address\n", 19ioctl: Bad address
) = 19
close(5) = 0
munmap(0xb7f32000, 4096) = 0
exit_group(0) = ?
========================================================

3. Output of valgrind
=========================================================
valgrind ./a.out
==27421== Memcheck, a memory error detector.
==27421== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et
al.
==27421== Using LibVEX rev 1575, a library for dynamic binary
translation.
==27421== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP.
==27421== Using valgrind-3.1.1, a dynamic binary instrumentation
framework.
==27421== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et
al.
==27421== For more details, rerun with: -v ==27421== ==27421== Syscall
param ioctl(CDROMREADTOCENTRY (cdte_format, char)) points to
unaddressable byte(s)
==27421== at 0x72E249: ioctl (in /lib/tls/libc-2.3.4.so)
==27421== by 0x681DE2: (below main) (in /lib/tls/libc-2.3.4.so)
==27421== Address 0x4 is not stack'd, malloc'd or (recently) free'd
==27421== ==27421== Syscall param ioctl(CDROMREADTOCENTRY (cdte_track,
char)) points to unaddressable byte(s)
==27421== at 0x72E249: ioctl (in /lib/tls/libc-2.3.4.so)
==27421== by 0x681DE2: (below main) (in /lib/tls/libc-2.3.4.so)
==27421== Address 0x2 is not stack'd, malloc'd or (recently) free'd
==27421== ==27421== Syscall param ioctl(CDROMREADTOCENTRY) points to
unaddressable byte(s)
==27421== at 0x72E249: ioctl (in /lib/tls/libc-2.3.4.so)
==27421== by 0x681DE2: (below main) (in /lib/tls/libc-2.3.4.so)
==27421== Address 0x2 is not stack'd, malloc'd or (recently) free'd
ioctl: Bad address
==27421==
==27421== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 12 from
1) ==27421== malloc/free: in use at exit: 0 bytes in 0 blocks.
==27421== malloc/free: 1 allocs, 1 frees, 352 bytes allocated.
==27421== For counts of detected errors, rerun with: -v ==27421== All
heap blocks were freed -- no leaks are possible.
=====================================================================

I hope this extra info will help you understand the problem.

Please let me know your thoughts on this.

Thanks in advance.
Prakash
From: Ian Collins on
On 05/ 4/10 01:20 PM, Prakash wrote:

<snip>
>
> /* set read mode to message -nondiscard mode */
> if ( ioctl(fd_read, I_SRDOPT, RMSGN ) )
> perror("ioctl");

> ioctl(3, CDROMREADTOCENTRY, 0x2) = -1 EFAULT (Bad address)

Looks like a broken header? CDROMREADTOCENTRY expects an address.

--
Ian Collins
From: Prakash on
On May 3, 9:36 pm, Ian Collins <ian-n...(a)hotmail.com> wrote:
> On 05/ 4/10 01:20 PM, Prakash wrote:
>
> <snip>
>
>
>
> >          /* set read mode to message -nondiscard mode */
> >          if ( ioctl(fd_read, I_SRDOPT, RMSGN  )  )
> >                  perror("ioctl");
> > ioctl(3, CDROMREADTOCENTRY, 0x2)        = -1 EFAULT (Bad address)
>
> Looks like a broken header? CDROMREADTOCENTRY expects an address.
>
> --
> Ian Collins

thanks Ian...any clue to fix this issue.

Thanks.
Prakash
From: Ian Collins on
On 05/ 4/10 01:54 PM, Prakash wrote:
> On May 3, 9:36 pm, Ian Collins<ian-n...(a)hotmail.com> wrote:
>> On 05/ 4/10 01:20 PM, Prakash wrote:
>>
>> <snip>
>>
>>
>>
>>> /* set read mode to message -nondiscard mode */
>>> if ( ioctl(fd_read, I_SRDOPT, RMSGN ) )
>>> perror("ioctl");
>>> ioctl(3, CDROMREADTOCENTRY, 0x2) = -1 EFAULT (Bad address)
>>
>> Looks like a broken header? CDROMREADTOCENTRY expects an address.
>>
> thanks Ian...any clue to fix this issue.

Not really. Check out the definitions for I_SRDOPT and
CDROMREADTOCENTRY in the appropriate headers, it might just be a bug in
strace.

--
Ian Collins