Skip to content

Commit 73c0eb9

Browse files
committed
[vm/runtime] Call tzset() before localtime_r().
POSIX doesn't guarantee that the timezone is set correctly before calling `localtime_r()`, so we need to call `tzset()` first to ensure that the timezone information is up-to-date. As the glibc manual states: > According to POSIX.1-2001, `localtime()` is required to behave as though `tzset(3)` was called, while `localtime_r()` does not > have this requirement. For portable code, `tzset(3)` should be called before `localtime_r()`. This change doesn't apply to Android, as from Android O and later Bionic libc handles timezone changes automatically.
1 parent 9bd6cbc commit 73c0eb9

File tree

3 files changed

+8
-0
lines changed

3 files changed

+8
-0
lines changed

build/sanitizers/tsan_suppressions.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,10 @@ char kTSanDefaultSuppressions[] =
260260
// False positive in libc's tzset_internal, http://crbug.com/379738.
261261
"race:tzset_internal\n"
262262

263+
// Suppression above does not work if we don't properly symbolize
264+
// tzset_internal frame. Suppress the closest caller.
265+
"race:dart::DN_HelperDateTime_timeZoneOffsetInSeconds\n"
266+
263267
// http://crbug.com/380554
264268
"deadlock:g_type_add_interface_static\n"
265269

runtime/vm/os_android.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ intptr_t OS::ProcessId() {
102102
static bool LocalTime(int64_t seconds_since_epoch, tm* tm_result) {
103103
time_t seconds = static_cast<time_t>(seconds_since_epoch);
104104
if (seconds != seconds_since_epoch) return false;
105+
// No need to call tzset() before localtime_r() because bionic
106+
// will handle timezone changes for us (starting from Android O).
107+
// See https://android.googlesource.com/platform/bionic/+/ea87716696bf635706b6f3fa56b8a145add83aff
105108
struct tm* error_code = localtime_r(&seconds, tm_result);
106109
return error_code != nullptr;
107110
}

runtime/vm/os_linux.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ intptr_t OS::ProcessId() {
418418
static bool LocalTime(int64_t seconds_since_epoch, tm* tm_result) {
419419
time_t seconds = static_cast<time_t>(seconds_since_epoch);
420420
if (seconds != seconds_since_epoch) return false;
421+
tzset(); // Not guaranteed by POSIX to be called by `localtime_r`.
421422
struct tm* error_code = localtime_r(&seconds, tm_result);
422423
return error_code != nullptr;
423424
}

0 commit comments

Comments
 (0)