[Toybox] "bad xform" not very helpful

Rob Landley rob at landley.net
Sat Aug 27 06:08:44 PDT 2022


On 8/18/22 11:24, enh wrote:
> On Thu, Aug 18, 2022 at 3:45 AM Rob Landley <rob at landley.net
> <mailto:rob at landley.net>> wrote:
> 
>     On 8/17/22 16:25, enh wrote:
>     >     Alright, let me try it in the android checkout directory... Still had
>     to run
>     >     oldconfig... And it ran fine for me.
>     >
>     >     Something different about the build environment.
>     >
>     > but it's consistent across multiple users on multiple OSes, so i think it's
>     > _your_ setup that's the odd one out so far :-)
>     >
>     > i've made Android's host tools consistent with the device tools for now, but
>     > there's probably _something_ for you to look into here...
> 
>     Oh definitely, I want to reproduce this. I'm just trying to figure out how...
> 
>     I dug up a Fedora live CD and it's reproduced under that. Trying to track it
>     down now...
> 
> 
> ?!
> 
> i'm definitely curious to hear how this story ends, and why it didn't repro
> trivially for you!

Did you know that if you change the font size in a fedora terminal window it's
tracked per-tab, so that when you switch tabs it resizes the window? Why would
they do that? And I am just so USED to xfce's terminal showing me the width and
height in characters while I'm resizing a terminal that it didn't occur to me
that the Fedora one _wouldn't_...

Right, Linux on the Desktop. Smell the usability...

The problem is that getdelim() is returning 22 (EINVAL) when called with

  char *line = 0;
  ssize_t len = 0;

  len = getdelim(&line, (void *)&len, 10, stdin);

According to strace it's never actually trying to read from fd 0, so something
internal to getdelim/stdin is failing. According to ltrace, the call to
getdelim() looks normal, ferror(stdin) is returning 0 before the call. I haven't
yet worked out how to get visibility INTO glibc to see what exactly it's
complaining about here, but the only EINVAL in glibc's libio/iogetdelim.c is:

  if (lineptr == NULL || n == NULL)
    {
      __set_errno (EINVAL);
      return -1;
    }

(That's the pointer TO the line and len values, not the value AT the line and
len values. And yes I'm getting the indirection right, that was what ltrace
confirmed.)

I did earlier swap out what fd 0 points to (via dup2), but that was an atomic
operation that didn't modify the stdin object, and it hasn't read from the
filehandle since? I also _can't_ modify the global stdin instance to point
somewhere else via FILE * because while there is a freopen() command, it takes a
path. There's no fdreopen() that I can find. (I suppose I could
freopen("/proc/self/fd/0") but this seems to add a gratuitous /proc dependency
for no reason? Another instance where the ANSI C committee doesn't have pipe()
and ignore sanything filehandle-ish because snobbery.)

Still poking at it. This is wandering into "single step through the assembly
with glibc" territory, since R-HELL is essentially binary only proprietary
nonsense and the failure is INSIDE glibc, been a sane-looking library call and
its failure to make a system call. (Hmmm, maybe I can reproduce this under a
Linux from scratch build? THAT I could stick printfs in...)

Rob


More information about the Toybox mailing list