Open p5pRT opened 8 years ago
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 ....
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)
The RT System itself - Status changed from 'new' to 'open'
On Tue Mar 29 15:34:06 2016\, jkeenan wrote:
$> 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?
I suspect when you renamed the .h files from their default\, you didn't update the test.pl to reflect the new .ph name. ( which it states explicitly by filename ).
Attached is a script that\, for me\, makes it work as expected pulling directly from rt sources\, renaming to your names.
Commenting out the "sed" line replicates your issue.
Bah. Didn't notice minor bug in `chdir` .... what language is this again? -_-.
Should work now even when you aren't already in a dir with a fixed test.pl + test.ph :P
Migrated from rt.perl.org#127517 (status was 'open')
Searchable as RT127517$