develooper Front page | perl.perl5.porters | Postings from March 2016

[perl #127517] h2ph should emit code that at least warns if asizeof() entry is missing

Thread Previous
From:
James E Keenan via RT
Date:
March 29, 2016 22:34
Subject:
[perl #127517] h2ph should emit code that at least warns if asizeof() entry is missing
Message ID:
rt-4.0.18-16131-1459290846-1071.127517-15-0@perl.org
On Thu Feb 11 05:00:42 2016, kentfredric wrote:
> This is a bug report for perl from kentnl@cpan.org,
> generated with the help of perlbug 1.40 running under perl 5.22.1.
> 
> 
> -----------------------------------------------------------------
> [Please describe your issue here]
> 
> TL;DR Version:
> 
> $sizeof{'struct fiemap'}  # should go bang in generated code if nobody
> has set it yet
>                           # because 0 + 'sizeof FOO' returning '0' is
> rarely, if ever, useful.
> 
> And while we're at it, a better coverage of this issue and how to
> manually resolve it would be a helpful addition to h2ph's
> documentation, which the "please fix this" error should point to.
> 
> Something like:
> 
> echo 'void main(){ printf("%#lx\n", sizeof(struct fiemap)); }' |\
>   gcc -x c -include stdio.h -include linux/fiemap.h - -o /tmp/a.out &&
> /tmp/a.out
> 
> 0x20
> 
> With instructions on where to put that value so it can be expected to
> work would be a start.
> 
> Grandpa Simpson Story Version:
> 
> There's a nice bug that you don't even know is a bug until you spend a
> bunch of time wondering why
> 
> ioctl( $handle, FS_IO_FIEMAP, $buffer );
> 
> is dying with "Invalid ioctl" stuff.
> 
> Its documented in `ioctl` that using `.ph` files is the "recommended"
> option, it says "non trivial", but doesn't say "Probably broken by
> default and silently broken at that".
> 
> --[ h2ph ]--
> BUGS
>    Doesn't construct the %sizeof array for you.
> ----
> 
> This doesn't seem obvious that it would be a problem, until you go
> digging though the .ph files and realise FS_IO_FIEMAP ( and a huge
> number of other ioctls ) are implemented in terms of one of the
> following defines:
> 
> --[ /usr/include/asm-generic/ioctl.h ]--
> #define _IOC_TYPECHECK(t) (sizeof(t))
> 
> /* used to create numbers */
> #define _IO(type,nr)            _IOC(_IOC_NONE,(type),(nr),0)
> #define _IOR(type,nr,size)
> _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
> #define _IOW(type,nr,size)
> _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
> #define _IOWR(type,nr,size)
> _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
> #define _IOR_BAD(type,nr,size)
> _IOC(_IOC_READ,(type),(nr),sizeof(size))
> #define _IOW_BAD(type,nr,size)
> _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
> #define _IOWR_BAD(type,nr,size)
> _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
> 
> ---
> grep -E '#define.*\s_IO(C|R|W|WR)' -r /usr/include/linux/ | wc -l
> 1033
> 
> grep -E '^#define.*\s_IO(C|R|W|WR)' -r /usr/include/ | wc -l
> 1461
> ----
> 
> This block of code here: https://metacpan.org/source/SHAY/perl-
> 5.22.1/utils/h2ph.PL#L445-468
> 
> Merely maps
> 
> sizeof(struct foo)
> 
> to
> 
> $sizeof{'struct foo'}
> 
> But does not guard against the likely possibility that value is
> undefined a the time the generated symbol is evaluated.
> 
> More over, as generated symbols are compound expressions, there's no
> way to tell an undef happened by looking at what they return, you have
> to know what the expected value is and compare the expected value with
> the one you got and go "that's wrong" and then work out why.
> 
> #define SAMPLE_SZ 5 + (sizeof sample)
> 
> perl: say SAMPLE_SZ; # 5
> C: printf "%ld\n", SAMPLE_SZ;  # 13
> 
> Which in the case of FS_IOC_FIEMAP is quite a few layers deep, because
> the innocuous
> 
> #define FS_IOC_FIEMAP                   _IOWR('f', 11, struct fiemap)
> 
> Turns into this under the C-Preprocessor:
> 
> (((2U|1U) << (((0 +8)+8)+14)) | ((('f')) << (0 +8)) | (((11)) << 0) |
> ((((sizeof(struct fiemap)))) << ((0 +8)+8)))
> 
> 
> The attached files demonstrate this issue:
> 
> 1. echo 'int main(){ printf("%ld\n", sample_sz); return 0;}' | gcc
> -include stdio.h -include test.h -x c - -o test.o && ./test.o
> 
> > 13
> 
> 2. mkdir out && h2ph -d out test.h && perl test.pl
> 
> > 5
> 
> Given the generated code by h2ph silently emits an entirely wrong
> constant, it would be better if it gave up and demanded somebody
> provide the appropriate values of $sizeof{} somehow.
> 
> Now, about that onion in my belt ....
> 

What I got when I tried this out (renaming the files provide to reflect the RT #):

#####
$> echo 'int main(){ printf("%ld\n", sample_sz); return 0;}' | gcc -include stdio.h -include 127517-test.h -x c - -o 127517-test.o && ./127517-test.o
13

$> mkdir -p out && h2ph -d out 127517-test.h && perl 127517-test.pl127517-test.h -> 127517-test.ph
Undefined subroutine &main::sample_sz called at 127517-test.pl line 6.
#####

Am I missing something?

Thank you very much.

-- 
James E Keenan (jkeenan@cpan.org)

---
via perlbug:  queue: perl5 status: new
https://rt.perl.org/Ticket/Display.html?id=127517

Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About