Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Trouble executing example translator from Hurd Hacking Guide

1 view
Skip to first unread message

Andrew Eggenberger

unread,
Jul 26, 2019, 9:36:33 PM7/26/19
to help...@gnu.org
I've been trying to compile and run the trivfs example [1] in the Hurd
Hacking Guide. It compiles with the slightly amended command:

gcc -g -o one -ltrivfs -lports

But when I try to set it on a file using `settrans -ac foo one` and then
`cat foo`, the translator crashes. GDB finds an unknown rpc call. The
trouble appears to be in the following function.


error_t
trivfs_S_io_read (struct trivfs_protid *cred,
mach_port_t reply, mach_msg_type_name_t reply_type,
vm_address_t *data, mach_msg_type_number_t *data_len,
off_t offs, mach_msg_type_number_t amount)
{
/* Deny access if they have bad credentials. */
if (!cred)
return EOPNOTSUPP;
else if (!(cred->po->openmodes & O_READ))
return EBADF;

if (amount > 0)
{
int i;

/* Possibly allocate a new buffer. */
if (*data_len < amount)
*data = (vm_address_t) mmap (0, amount, PROT_READ|PROT_WRITE,
MAP_ANON, 0, 0);

/* Copy the constant data into the buffer. */
for (i = 0; i < amount; i++)
((char *) *data)[i] = 1;
}

*data_len = amount;
return 0;
}

mmap fails to allocate memory. When I checked the errno string, it said
there was an invalid argument. The mmap manual says MAP_SHARED or
MAP_PRIVATE need to appear in the flags argument (the fourth one). I
tried adding each and the error persisted. Another possible reason for
the error according to the man page is an amount that is too high. I
checked the variable and it is a large number, but I don't know how to
check to see how much is too much. Anyway I'm stuck on this. Once I get
it working I hope to update the guide so that other interested newcomers
don't run into the same trouble.

By the way, that call to mmap is virtually identical to the one in the
translator hello.c that's part of the hurd source code. It's also
missing the MAP_SHARED or MAP_PRIVATE flag. The reason it doesn't crash
is I think because *data_len is always greater than the amount and never
runs.

[1]: https://www.gnu.org/software/hurd/hacking-guide/hhg.html#An-Example-using-trivfs
--
Andrew Eggenberger

Samuel Thibault

unread,
Jul 27, 2019, 5:10:06 AM7/27/19
to Andrew Eggenberger, help...@gnu.org, bug-...@gnu.org
Hello,

Andrew Eggenberger, le ven. 26 juil. 2019 20:36:20 -0500, a ecrit:
> I've been trying to compile and run the trivfs example [1] in the Hurd
> Hacking Guide. It compiles with the slightly amended command:
>
> gcc -g -o one -ltrivfs -lports

Indeed, it is using a libports function and nowadays tools don't let
that implicitly taken from libtrivfs.

> mmap fails to allocate memory. When I checked the errno string, it said
> there was an invalid argument. The mmap manual says MAP_SHARED or
> MAP_PRIVATE need to appear in the flags argument (the fourth one).

MAP_PRIVATE is actually #defined to 0, so it's not actually "mandatory".
The idea here is that MAP_ANON means MAP_PRIVATE anyway, so people were
not putting the latter.

> I tried adding each and the error persisted. Another possible reason
> for the error according to the man page is an amount that is too
> high. I checked the variable and it is a large number, but I don't
> know how to check to see how much is too much.

Print it in hex:

gdb> p/x amount
0xffffffff

That is way too much (2^32-1) for the 32bit address space. That's where
the problem comes from.

The issue here is actually that the source code is missing

#define _FILE_OFFSET_BITS 64

at the very top of the file. It seems that compatibility symbols have
not been introduced, and thus your translator was using 32bit off_t
while libtrivfs uses 64bit off_t. Recompile with that #define and it
should work.

I have updated the webpage, I guess that will show up after mirrors
catch up.

Samuel

Samuel Thibault

unread,
Jul 27, 2019, 5:32:55 AM7/27/19
to Andrew Eggenberger, help...@gnu.org, bug-...@gnu.org
Samuel Thibault, le sam. 27 juil. 2019 11:09:56 +0200, a ecrit:
> The issue here is actually that the source code is missing
>
> #define _FILE_OFFSET_BITS 64
>
> at the very top of the file.

Or you can make the hooks use loff_t instead of off_t.

Samuel

Andrew Eggenberger

unread,
Jul 28, 2019, 5:21:24 AM7/28/19
to bug-...@gnu.org, Andrew Eggenberger, help...@gnu.org

Thanks Samuel,

It's working now, with a few small tweaks. Both putting #define
_FILE_OFFSET_BITS 64 and switching the offset type in the read function
to loff_t caused the translator to output what appears to be the
contents of some memory instead of a string of '1's. But compiling with
-D_FILE_OFFSET_BITS=64 worked. There's also a small bug in the program
itself. Instead of assigning the char '1' in the for loop, it's
assigning the int 1, causing it to output the character with the ascii
code 1.
--
Andrew Eggenberger

Samuel Thibault

unread,
Jul 28, 2019, 5:33:25 AM7/28/19
to Andrew Eggenberger, bug-...@gnu.org, help...@gnu.org
Hello,

Andrew Eggenberger, le dim. 28 juil. 2019 04:21:21 -0500, a ecrit:
> It's working now,

Good :)

> Both putting #define _FILE_OFFSET_BITS 64 and switching the offset
> type in the read function to loff_t

? Only one of the two should be needed. Note that the #define needs to
be very first, before #includes, since it's driving what includes are
supposed to do.

> There's also a small bug in the program itself. Instead of assigning
> the char '1' in the for loop, it's assigning the int 1, causing it to
> output the character with the ascii code 1.

AIUI that was the purpose, but apparently it would be less surprising to
emit '1' chars, so I changed that too.

Samuel

Andrew Eggenberger

unread,
Jul 28, 2019, 5:48:44 AM7/28/19
to bug-...@gnu.org, Andrew Eggenberger, help...@gnu.org

Thank you. Yes, I misunderstood. All three methods work (independently) now.
--
Andrew Eggenberger

0 new messages