152 lines
6.3 KiB
Plaintext
152 lines
6.3 KiB
Plaintext
README of the Y2038 cppcheck addon
|
|
==================================
|
|
|
|
Contents
|
|
|
|
1. What is Y2038?
|
|
2. What is the Y2038 cppcheck addon?
|
|
3. How does the Y2038 cppcheck addon work?
|
|
4. How to use the Y2038 cppcheck addon
|
|
|
|
---
|
|
|
|
1. What is Y2038?
|
|
|
|
In a few words:
|
|
|
|
In Linux, the current date and time is kept as the number of seconds elapsed
|
|
since the Unix epoch, that is, since January 1st, 1970 at 00:00:00 GMT.
|
|
|
|
Most of the time, this representation is stored as a 32-bit signed quantity.
|
|
|
|
On January 19th, 2038 at 03:14:07 GMT, such 32-bit representations will reach
|
|
their maximum positive value.
|
|
|
|
What happens then is unpredictable: system time might roll back to December
|
|
13th, 1901 at 19:55:13, or it might keep running on until February 7th, 2106
|
|
at 06:28:15 GMT, or the computer may freeze, or just about anything you can
|
|
think of, plus a few ones you can't.
|
|
|
|
The workaround for this is to switch to a 64-bit signed representation of time
|
|
as seconds from the Unix epoch. This representation will work for more than 250
|
|
billion years.
|
|
|
|
Working around Y2038 requires fixing the Linux kernel, the C libraries, and
|
|
any user code around which uses 32-bit epoch representations.
|
|
|
|
There is Y2038-proofing work in progress on the Linux and GNU glibc front.
|
|
|
|
2. What is the Y2038 cppcheck addon?
|
|
|
|
The Y2038 cppcheck addon is a tool to help detect code which might need fixing
|
|
because it is Y2038-unsafe. This may be because it uses types or functions from
|
|
GNU libc or from the Linux kernel which are known not to be Y2038-proof.
|
|
|
|
3. How does the Y2038 cppcheck addon work?
|
|
|
|
The Y2038 cppcheck addon takes XML dumps produced by cppcheck from source code
|
|
files and looks for the names of types or functions which are known to be Y2038-
|
|
unsafe, and emits diagnostics whenever it finds one.
|
|
|
|
Of course, this is of little use if your code uses a Y2038-proof glibc and
|
|
correctly configured Y2038-proof time support.
|
|
|
|
This is why y2038.py takes into account two preprocessor directives:
|
|
_TIME_BITS and __USE_TIME_BITS64.
|
|
|
|
_TIME_BITS is defined equal to 64 by user code when it wants 64-bit time
|
|
support from the GNU glibc. Code which does not define _TIME_BITS equal to 64
|
|
(or defines it to something else than 64) runs a risk of not being Y2038-proof.
|
|
|
|
__USE_TIME_BITS64 is defined by the GNU glibc when it actually provides 64-bit
|
|
time support. When this is defined, then all glibc symbols, barring bugs, are
|
|
Y2038-proof (but your code might have its own Y2038 bugs, if it handles signed
|
|
32-bit Unix epoch values).
|
|
|
|
The Y2038 cppcheck performs the following checks:
|
|
|
|
1. Upon meeting a definition for _TIME_BITS, if that definition does not
|
|
set it equal to 64, this error diagnostic is emitted:
|
|
|
|
Error: _TIME_BITS must be defined equal to 64
|
|
|
|
This case is very unlikely but might result from a typo, so pointing
|
|
it out is quite useful. Note that definitions of _TIME_BITS as an
|
|
expression evaluating to 64 will be flagged too.
|
|
|
|
2. Upon meeting a definition for _USE_TIME_BITS64, if _TIME_BITS is not
|
|
defined equal to 64, this information diagnostic is emitted:
|
|
|
|
Warning: _USE_TIME_BITS64 is defined but _TIME_BITS was not
|
|
|
|
This reflects the fact that even though the glibc checked default to
|
|
64-bit time support, this was not requested by the user code, and
|
|
therefore the user code might fail Y2038 if built against a glibc
|
|
which defaults to 32-bit time support.
|
|
|
|
3. Upon meeting a symbol (type or function) which is known to be Y2038-
|
|
unsafe, if _USE_TIME_BITS64 is undefined or _TIME_BITS not properly
|
|
defined, this warning diagnostic is emitted:
|
|
|
|
Warning: <symbol> is Y2038-unsafe
|
|
|
|
This reflects the fact that the user code is referring to a symbol
|
|
which, when glibc defaults to 32-bit time support, might fail Y2038.
|
|
|
|
General note: y2038.py will handle multiple configurations, and will
|
|
emit diagnostics for each configuration in turn.
|
|
|
|
4. How to use the Y2038 cppcheck addon
|
|
|
|
The Y2038 cppcheck addon is used like any other cppcheck addon:
|
|
|
|
cppcheck --dump file1.c [ file2.c [...]]]
|
|
y2038.py file1.c [ file2.c [...]]]
|
|
|
|
Sample test C file is provided:
|
|
|
|
test/y2038-test-1-bad-time-bits.c
|
|
test/y2038-test-2-no-time-bits.c
|
|
test/y2038-test-3-no-use-time-bits.c
|
|
test/y2038-test-4-good.c
|
|
|
|
These cover the cases described above. You can run them through cppcheck
|
|
and y2038.py to see for yourself how the addon diagnostics look like. If
|
|
this README is not outdated (and if it is, feel free to submit a patch),
|
|
you can run cppcheck on these files as on any others:
|
|
|
|
cppcheck --dump addons/y2038/test/y2038-*.c
|
|
y2038.py addons/y2038/test/y2038-*.dump
|
|
|
|
If you have not installed cppcheck yet, you will have to run these
|
|
commands from the root of the cppcheck repository:
|
|
|
|
make
|
|
sudo make install
|
|
./cppcheck --dump addons/y2038/test/y2038-*.c
|
|
PYTHONPATH=addons python addons/y2038/y2038.py addons/y2038/test/y2038-*.c.dump
|
|
|
|
In both cases, y2038.py execution should result in the following:
|
|
|
|
Checking addons/y2038/test/y2038-test-1-bad-time-bits.c.dump...
|
|
Checking addons/y2038/test/y2038-test-1-bad-time-bits.c.dump, config ""...
|
|
Checking addons/y2038/test/y2038-test-2-no-time-bits.c.dump...
|
|
Checking addons/y2038/test/y2038-test-2-no-time-bits.c.dump, config ""...
|
|
Checking addons/y2038/test/y2038-test-3-no-use-time-bits.c.dump...
|
|
Checking addons/y2038/test/y2038-test-3-no-use-time-bits.c.dump, config ""...
|
|
Checking addons/y2038/test/y2038-test-4-good.c.dump...
|
|
Checking addons/y2038/test/y2038-test-4-good.c.dump, config ""...
|
|
# Configuration "":
|
|
# Configuration "":
|
|
[addons/y2038/test/y2038-test-1-bad-time-bits.c:8]: (error) _TIME_BITS must be defined equal to 64
|
|
[addons/y2038/test/y2038-inc.h:9]: (warning) _USE_TIME_BITS64 is defined but _TIME_BITS was not
|
|
[addons/y2038/test/y2038-test-1-bad-time-bits.c:10]: (information) addons/y2038/test/y2038-inc.h was included from here
|
|
[addons/y2038/test/y2038-inc.h:9]: (warning) _USE_TIME_BITS64 is defined but _TIME_BITS was not
|
|
[addons/y2038/test/y2038-test-2-no-time-bits.c:8]: (information) addons/y2038/test/y2038-inc.h was included from here
|
|
[addons/y2038/test/y2038-test-3-no-use-time-bits.c:13]: (warning) timespec is Y2038-unsafe
|
|
[addons/y2038/test/y2038-test-3-no-use-time-bits.c:15]: (warning) clock_gettime is Y2038-unsafe
|
|
|
|
Note: y2038.py recognizes option --template as cppcheck does, including
|
|
pre-defined templates 'gcc', 'vs' and 'edit'. The short form -t is also
|
|
recognized.
|