|
| 1 | +README of the Y2038 cppcheck addon |
| 2 | +================================== |
| 3 | + |
| 4 | +Contents |
| 5 | + |
| 6 | +1. What is Y2038? |
| 7 | +2. What is the Y2038 ccpcheck addon? |
| 8 | +3. How does the Y2038 cppcheck addon work? |
| 9 | +4. How to use the Y2038 cppcheck addon |
| 10 | + |
| 11 | +--- |
| 12 | + |
| 13 | +1. What is Y2038? |
| 14 | + |
| 15 | +In a few words: |
| 16 | + |
| 17 | +In Linux, the current date and time is kept as the number of seconds elapsed |
| 18 | +since the Unich epoch, that is, since January 1st, 1970 at 00:00:00 GMT. |
| 19 | + |
| 20 | +Most of the time, this representation is stored as a 32-bit signed quantity. |
| 21 | + |
| 22 | +On January 19th, 2038 at 03:14:07 GMT, such 32-bit representations will reach |
| 23 | +their maximum positive value. |
| 24 | + |
| 25 | +What happens then is unpredictable: system time might roll back to December |
| 26 | +13th, 1901 at 19:55:13, or it might keep running on until February 7th, 2106 |
| 27 | +at 06:28:15 GMT, or the computer may freeze, or just about anything you can |
| 28 | +think of, plus a few ones you can't. |
| 29 | + |
| 30 | +The workaround for this is to switch to a 64-bit signed representation of time |
| 31 | +as seconds from the Unix epoch. This representation will work for more than 250 |
| 32 | +billion years. |
| 33 | + |
| 34 | +Working around Y2038 requires fixing the Linux kernel, the C libraries, and |
| 35 | +any user code around which uses 32-bit epoch representations. |
| 36 | + |
| 37 | +There is Y2038-proofing work in progress on the Linux and GNU glibc front. |
| 38 | + |
| 39 | +2. What is the Y2038 ccpcheck addon? |
| 40 | + |
| 41 | +The Y2038 cppcheck addon is a tool to help detect code which might need fixing |
| 42 | +because it is Y2038-sensitive. This may be because it uses types or functions |
| 43 | +from libc or from the Linux kernel which are known not to be Y2038-proof. |
| 44 | + |
| 45 | +3. How does the Y2038 cppcheck addon work? |
| 46 | + |
| 47 | +The Y2038 cppcheck addon takes XML dumps produced by cppcheck from source code |
| 48 | +files and looks for the names of types or functions which are known to be Y2038- |
| 49 | +sensitive, and emits diagnostics whenever it finds one. |
| 50 | + |
| 51 | +Of course, this is of little use if your code uses a Y2038-proof glibc and |
| 52 | +correctly configured Y2038-proof time support. |
| 53 | + |
| 54 | +This is why y2038.py takes into account two preprocessor directives: |
| 55 | +_TIME_BITS and __USE_TIME_BITS64. |
| 56 | + |
| 57 | +_TIME_BITS is defined equal to 64 by user code when it wants 64-bit time |
| 58 | +support from the GNU glibc. Code which does not define _TIME_BITS equal to 64 |
| 59 | +(or defines it to something else than 64) runs a risk of not being Y2038-proof. |
| 60 | + |
| 61 | +__USE_TIME_BITS64 is defined by the GNU glibc when it actualy provides 64-bit |
| 62 | +time support. When this is defined, then all glibc symbols, barring bugs, are |
| 63 | +Y2038-proof (but your code might have its own Y2038 bugs, if it handles signed |
| 64 | +32-bit Unix epoch values). |
| 65 | + |
| 66 | +The Y2038 cppcheck performs the following checks: |
| 67 | + |
| 68 | + 1. Upon meeting a definition for _TIME_BITS, if that definition does not |
| 69 | + set it equal to 64, this error diagnostic is emitted: |
| 70 | + |
| 71 | + Error: _TIME_BITS must be defined equal to 64 |
| 72 | + |
| 73 | + This case is very unlikely but might result from a typo, so pointing |
| 74 | + it out is quite useful. Note that definitions of _TIME_BITS as an |
| 75 | + expression evaluating to 64 will be flagged too. |
| 76 | + |
| 77 | + 2. Upon meeting a definition for _USE_TIME_BITS64, if _TIME_BITS is not |
| 78 | + defined equal to 64, this information diagnostic is emitted: |
| 79 | + |
| 80 | + Warning: _USE_TIME_BITS64 is defined but _TIME_BITS was not |
| 81 | + |
| 82 | + This reflects the fact that even though the glibc checked default to |
| 83 | + 64-bit time support, this was not requested by the user code, and |
| 84 | + therefore the user code might fail Y2038 if built against a glibc |
| 85 | + which defaults to 32-bit time support. |
| 86 | + |
| 87 | + 3. Upon meeting a symbol (type or function) which is known to be Y2038- |
| 88 | + sensitive, if _USE_TIME_BITS64 is undefined or _TIME_BITS not properly |
| 89 | + defined, this warning diagnostic is emitted: |
| 90 | + |
| 91 | + Warning: <symbol> might be Y2038-sensitive |
| 92 | + |
| 93 | + This reflects the fact that the user code is referring to a symbol |
| 94 | + which, when glibc defaults to 32-bit time support, might fail Y2038. |
| 95 | + |
| 96 | +General note: y2038.py will handle multiple configurations, and will |
| 97 | +emit diagnostics for each configuration in turn. |
| 98 | + |
| 99 | +4. How to use the Y2038 cppcheck addon |
| 100 | + |
| 101 | +The Y2038 cppcheck addon is used like any other cppcheck addon: |
| 102 | + |
| 103 | + cppcheck --dump file1.c [ file2.c [...]]] |
| 104 | + y2038.py file1.c [ file2.c [...]]] |
| 105 | + |
| 106 | +Sample test C file is provided: |
| 107 | + |
| 108 | + test/y2038-test-1-bad-time-bits.c |
| 109 | + test/y2038-test-2-no-time-bits.c |
| 110 | + test/y2038-test-3-no-use-time-bits.c |
| 111 | + test/y2038-test-4-good.c |
| 112 | + |
| 113 | +These cover the cases described above. You can run them through cppcheck |
| 114 | +and y2038.py to see for yourself how the addon diagnostics look like. If |
| 115 | +this README is not outdated (and if it is, feel free to submit a patch), |
| 116 | +you can run cppcheck on these files as on any others: |
| 117 | + |
| 118 | + cppcheck --dump addons/y2038/test/y2038-*.c |
| 119 | + y2038.py addons/y2038/test/y2038-*.dump |
| 120 | + |
| 121 | +If you havve not installed cppcheck yet, you will have to run these |
| 122 | +commands from the root of the cppcheck repository: |
| 123 | + |
| 124 | + make |
| 125 | + sudo make install |
| 126 | + ./cppcheck --dump addons/y2038/test/y2038-*.c |
| 127 | + PYTHONPATH=addons python addons/y2038/y2038.py addons/y2038/test/y2038-*.c.dump |
| 128 | + |
| 129 | +In both cases, y2038.py execution should result in the following: |
| 130 | + |
| 131 | +Checking addons/y2038/test/y2038-test-1-bad-time-bits.c.dump... |
| 132 | +Checking addons/y2038/test/y2038-test-1-bad-time-bits.c.dump, config ""... |
| 133 | +Checking addons/y2038/test/y2038-test-2-no-time-bits.c.dump... |
| 134 | +Checking addons/y2038/test/y2038-test-2-no-time-bits.c.dump, config ""... |
| 135 | +Checking addons/y2038/test/y2038-test-3-no-use-time-bits.c.dump... |
| 136 | +Checking addons/y2038/test/y2038-test-3-no-use-time-bits.c.dump, config ""... |
| 137 | +Checking addons/y2038/test/y2038-test-4-good.c.dump... |
| 138 | +Checking addons/y2038/test/y2038-test-4-good.c.dump, config ""... |
| 139 | +# Configuration "": |
| 140 | +# Configuration "": |
| 141 | +[addons/y2038/test/y2038-test-1-bad-time-bits.c:8]: (error) _TIME_BITS must be defined equal to 64 |
| 142 | +[addons/y2038/test/y2038-inc.h:9]: (warning) _USE_TIME_BITS64 is defined but _TIME_BITS was not |
| 143 | +[addons/y2038/test/y2038-test-1-bad-time-bits.c:10]: (information) addons/y2038/test/y2038-inc.h was included from here |
| 144 | +[addons/y2038/test/y2038-inc.h:9]: (warning) _USE_TIME_BITS64 is defined but _TIME_BITS was not |
| 145 | +[addons/y2038/test/y2038-test-2-no-time-bits.c:8]: (information) addons/y2038/test/y2038-inc.h was included from here |
| 146 | +[addons/y2038/test/y2038-test-3-no-use-time-bits.c:13]: (warning) timespec might be Y2038-sensitive |
| 147 | +[addons/y2038/test/y2038-test-3-no-use-time-bits.c:15]: (warning) clock_gettime might be Y2038-sensitive |
| 148 | + |
| 149 | +Note: y2038.py recognizes option --template as cppcheck does, including |
| 150 | +pre-defined templates 'gcc', 'vs' and 'edit'. The short form -t is also |
| 151 | +recognized. |
0 commit comments