[Toybox] Debugging "infrastructure" breakage, an example.
Rob Landley
rob at landley.net
Tue Jul 16 22:06:54 PDT 2013
I'm adding a new command, timeout, cloned from sleep.c instead of
hello.c.
(Somebody did a bug report on the busybox list about timeout, and I went
"there's a timeout command now?" Hey, means I can yank more/timeout.sh
in
Aboriginal Linux, I'm all for it.)
Initially I tried to do it as an OLDTOY() alias of sleep (to re-use the
seconds/minutes/hours/days fractional parsing logic), but wound
up factoring common code out into lib/ instead, and making timeout its
own command with its own toys/other/timeout.c file.
The build broke, even after doing "make defconfig", and that usually
means I'm
missing a semicolon after a function I added to lib/lib.h or something.
And _when_ the toybox build breaks in the generated/* shared
infrastructure,
you get pages of nonsense.
Here's how you fix it. The trick is:
make 2>&1 | less
And then look at the _first_ break. Due to the "gcc lib/*.c toys/*/*.c"
nature
of the build, it's going to give pages and pages and pages of errors
for anything
wrong in the infrastructure, losing its marbles in the middle of
parsing large
tables and deciding everything after that is out to get it.
But the first failure is the one confusing it. The rest is just flying
shrapnel.
In this case,
Compile toybox...
In file included from toys.h:65:0,
from main.c:6:
generated/newtoys.h:113:1: warning: return type defaults to 'int'
"This is just a warning," you say? But it's pointing out where we went
wrong.
In generated/newtoys.h line 113 we have:
USE_TIMEOUT(NEWTOY(timeout, "<2k:s: ", TOYFLAG_BIN))
This macro is expanded in several different places to mean several
different things. In the warning we got there through toys.h line 65,
which is the first include in:
// Get list of function prototypes for all enabled command_main()
functions.
#define NEWTOY(name, opts, flags) void name##_main(void);
#define OLDTOY(name, oldname, opts, flags)
#include "generated/newtoys.h"
#include "generated/globals.h"
A prototype should _not_ be giving us a warning, which that implies
that the
USE_TIMEOUT() macro isn't converting into a prototype, most likely
because
the macro isn't actually being defined (so the compiler thinks it's a
function
call, and warns us we didn't prototype that function call).
A grep of generated/config.h confirms this: USE_TIMEOUT is not there.
The macro is generated from the config symbol, and _that_ means I
probably
typoed the config symbol name. Which I did: I still have it as
SLEEP_TIMEOUT
from when it was an alias of sleep. I used USE_TIMEOUT in the NEWTOY
line
but no config symbol is providing USE_TIMEOUT, hence it thinks there's a
function call in the middle of the function prototype list for all the
command_main() prototypes, and hilarity ensues.
(Note that for a standlone file the top config symbol has to match the
name
of the C file we're building so the makefile can select which source
files
out of toys to build, and so what NEWTOY() and such are defining line
up.
Since the config doesn't contain a TIMEOUT=y, it won't include
toys/*/timeout.c
in the gcc command line, and thus the link would fail with no
timeout_main()
assumign we could get that far. But we don't get that far because the
macro
doesn't resolve, so the build breaks way earlier.)
The fix is to rename the config symbol to what it should be, and upon
fixing that:
Compile toybox...
toys/posix/sleep.c: In function 'sleep_main':
toys/posix/sleep.c:34:3: warning: passing argument 2 of 'xparsetime'
makes integer from pointer without a cast [enabled by default]
./lib/lib.h:123:6: note: expected 'long int' but argument is of type
'long int *'
toys/posix/sleep.c:34:3: error: too few arguments to function
'xparsetime'
./lib/lib.h:123:6: note: declared here
toys/other/timeout.c: In function 'timeout_main':
toys/other/timeout.c:36:23: warning: unused variable 'vcr'
[-Wunused-variable]
toys/other/timeout.c:36:19: warning: unused variable 'tv'
[-Wunused-variable]
Errors, but normal "unfinished C code, a bit of damage from splitting
code out
of sleep, and some rough edges in the lib code I added". Not the pages
of
hysterical infrastructure messages from a badly confused gcc.
Rob
1374037614.0
More information about the Toybox
mailing list