Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 362dfa5

Browse files
committed
Merge remote-tracking branch 'github/upstream-with-swift' into HEAD
# Conflicts: # test/lit.common.cfg
2 parents daa6759 + d2d98b7 commit 362dfa5

File tree

9 files changed

+127
-7
lines changed

9 files changed

+127
-7
lines changed

README.txt

-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,3 @@ Compiler-RT is open source software. You may freely distribute it under the
88
terms of the license agreement found in LICENSE.txt.
99

1010
================================
11-

lib/profile/InstrProfilingFile.c

+60-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <stdio.h>
1313
#include <stdlib.h>
1414
#include <string.h>
15+
#include <signal.h>
1516
#ifdef _MSC_VER
1617
/* For _alloca. */
1718
#include <malloc.h>
@@ -62,6 +63,7 @@ static const char *getPNSStr(ProfileNameSpecifier PNS) {
6263
}
6364

6465
#define MAX_PID_SIZE 16
66+
#define MAX_SIGNAL_HANDLERS 16
6567
/* Data structure holding the result of parsed filename pattern. */
6668
typedef struct lprofFilename {
6769
/* File name string possibly with %p or %h specifiers. */
@@ -83,11 +85,14 @@ typedef struct lprofFilename {
8385
* 2 profile data files. %1m is equivalent to %m. Also %m specifier
8486
* can only appear once at the end of the name pattern. */
8587
unsigned MergePoolSize;
88+
char ExitOnSignals[MAX_SIGNAL_HANDLERS];
89+
unsigned NumExitSignals;
8690
ProfileNameSpecifier PNS;
8791
} lprofFilename;
8892

8993
COMPILER_RT_WEAK lprofFilename lprofCurFilename = {0, 0, 0, 0, {0},
90-
{0}, 0, 0, 0, PNS_unknown};
94+
{0}, 0, 0, 0, {0}, 0,
95+
PNS_unknown};
9196

9297
static int getCurFilenameLength();
9398
static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf);
@@ -286,6 +291,19 @@ static void truncateCurrentFile(void) {
286291
fclose(File);
287292
}
288293

294+
static void exitSignalHandler(int sig) {
295+
(void)sig;
296+
exit(0);
297+
}
298+
299+
static void installExitSignalHandlers(void) {
300+
unsigned I;
301+
for (I = 0; I < lprofCurFilename.NumExitSignals; ++I) {
302+
lprofInstallSignalHandler(lprofCurFilename.ExitOnSignals[I],
303+
exitSignalHandler);
304+
}
305+
}
306+
289307
static const char *DefaultProfileName = "default.profraw";
290308
static void resetFilenameToDefault(void) {
291309
if (lprofCurFilename.FilenamePat && lprofCurFilename.OwnsFilenamePat) {
@@ -296,14 +314,25 @@ static void resetFilenameToDefault(void) {
296314
lprofCurFilename.PNS = PNS_default;
297315
}
298316

317+
static int isDigit(char C) { return C >= '0' && C <= '9'; }
318+
319+
static int isNonZeroDigit(char C) { return C >= '1' && C <= '9'; }
320+
299321
static int containsMergeSpecifier(const char *FilenamePat, int I) {
300322
return (FilenamePat[I] == 'm' ||
301-
(FilenamePat[I] >= '1' && FilenamePat[I] <= '9' &&
323+
(isNonZeroDigit(FilenamePat[I]) &&
302324
/* If FilenamePat[I] is not '\0', the next byte is guaranteed
303325
* to be in-bound as the string is null terminated. */
304326
FilenamePat[I + 1] == 'm'));
305327
}
306328

329+
static int containsExitOnSignalSpecifier(const char *FilenamePat, int I) {
330+
if (!isNonZeroDigit(FilenamePat[I]))
331+
return 0;
332+
return (FilenamePat[I + 1] == 'x') ||
333+
(isDigit(FilenamePat[I + 1]) && FilenamePat[I + 2] == 'x');
334+
}
335+
307336
/* Parses the pattern string \p FilenamePat and stores the result to
308337
* lprofcurFilename structure. */
309338
static int parseFilenamePattern(const char *FilenamePat,
@@ -312,6 +341,7 @@ static int parseFilenamePattern(const char *FilenamePat,
312341
char *PidChars = &lprofCurFilename.PidChars[0];
313342
char *Hostname = &lprofCurFilename.Hostname[0];
314343
int MergingEnabled = 0;
344+
char SignalNo;
315345

316346
/* Clean up cached prefix and filename. */
317347
if (lprofCurFilename.ProfilePathPrefix)
@@ -364,6 +394,22 @@ static int parseFilenamePattern(const char *FilenamePat,
364394
lprofCurFilename.MergePoolSize = FilenamePat[I] - '0';
365395
I++; /* advance to 'm' */
366396
}
397+
} else if (containsExitOnSignalSpecifier(FilenamePat, I)) {
398+
if (lprofCurFilename.NumExitSignals == MAX_SIGNAL_HANDLERS) {
399+
PROF_WARN("%%x specifier has been specified too many times in %s.\n",
400+
FilenamePat);
401+
return -1;
402+
}
403+
/* Grab the signal number. */
404+
SignalNo = FilenamePat[I] - '0';
405+
I++; /* advance to either another digit, or 'x' */
406+
if (FilenamePat[I] != 'x') {
407+
SignalNo = (SignalNo * 10) + (FilenamePat[I] - '0');
408+
I++; /* advance to 'x' */
409+
}
410+
lprofCurFilename.ExitOnSignals[lprofCurFilename.NumExitSignals] =
411+
SignalNo;
412+
++lprofCurFilename.NumExitSignals;
367413
}
368414
}
369415

@@ -407,6 +453,7 @@ static void parseAndSetFilename(const char *FilenamePat,
407453
}
408454

409455
truncateCurrentFile();
456+
installExitSignalHandlers();
410457
}
411458

412459
/* Return buffer length that is required to store the current profile
@@ -415,18 +462,24 @@ static void parseAndSetFilename(const char *FilenamePat,
415462
#define SIGLEN 24
416463
static int getCurFilenameLength() {
417464
int Len;
465+
unsigned I;
418466
if (!lprofCurFilename.FilenamePat || !lprofCurFilename.FilenamePat[0])
419467
return 0;
420468

421469
if (!(lprofCurFilename.NumPids || lprofCurFilename.NumHosts ||
422-
lprofCurFilename.MergePoolSize))
470+
lprofCurFilename.MergePoolSize || lprofCurFilename.NumExitSignals))
423471
return strlen(lprofCurFilename.FilenamePat);
424472

425473
Len = strlen(lprofCurFilename.FilenamePat) +
426474
lprofCurFilename.NumPids * (strlen(lprofCurFilename.PidChars) - 2) +
427475
lprofCurFilename.NumHosts * (strlen(lprofCurFilename.Hostname) - 2);
428476
if (lprofCurFilename.MergePoolSize)
429477
Len += SIGLEN;
478+
for (I = 0; I < lprofCurFilename.NumExitSignals; ++I) {
479+
Len -= 3; /* Drop the '%', signal number, and the 'x'. */
480+
if (lprofCurFilename.ExitOnSignals[I] >= 10)
481+
--Len; /* Drop the second digit of the signal number. */
482+
}
430483
return Len;
431484
}
432485

@@ -443,7 +496,7 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) {
443496
return 0;
444497

445498
if (!(lprofCurFilename.NumPids || lprofCurFilename.NumHosts ||
446-
lprofCurFilename.MergePoolSize)) {
499+
lprofCurFilename.MergePoolSize || lprofCurFilename.NumExitSignals)) {
447500
if (!ForceUseBuf)
448501
return lprofCurFilename.FilenamePat;
449502

@@ -476,6 +529,9 @@ static const char *getCurFilename(char *FilenameBuf, int ForceUseBuf) {
476529
J += S;
477530
if (FilenamePat[I] != 'm')
478531
I++;
532+
} else if (containsExitOnSignalSpecifier(FilenamePat, I)) {
533+
while (FilenamePat[I] != 'x')
534+
++I;
479535
}
480536
/* Drop any unknown substitutions. */
481537
} else

lib/profile/InstrProfilingUtil.c

+19
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <sys/utsname.h>
2424
#endif
2525

26+
#include <signal.h>
2627
#include <stdlib.h>
2728
#include <string.h>
2829

@@ -270,6 +271,24 @@ COMPILER_RT_VISIBILITY const char *lprofFindLastDirSeparator(const char *Path) {
270271
return Sep;
271272
}
272273

274+
COMPILER_RT_VISIBILITY void lprofInstallSignalHandler(int sig,
275+
void (*handler)(int)) {
276+
#ifdef _WIN32
277+
void (*err)(int) = signal(sig, handler);
278+
if (err == SIG_ERR)
279+
PROF_WARN("Unable to install an exit signal handler for %d (errno = %d).\n",
280+
sig, errno);
281+
#else
282+
struct sigaction sigact;
283+
memset(&sigact, 0, sizeof(sigact));
284+
sigact.sa_handler = handler;
285+
int err = sigaction(sig, &sigact, NULL);
286+
if (err)
287+
PROF_WARN("Unable to install an exit signal handler for %d (errno = %d).\n",
288+
sig, err);
289+
#endif
290+
}
291+
273292
COMPILER_RT_VISIBILITY int lprofSuspendSigKill() {
274293
#if defined(__linux__)
275294
int PDeachSig = 0;

lib/profile/InstrProfilingUtil.h

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ int lprofGetHostName(char *Name, int Len);
5959
unsigned lprofBoolCmpXchg(void **Ptr, void *OldV, void *NewV);
6060
void *lprofPtrFetchAdd(void **Mem, long ByteIncr);
6161

62+
void lprofInstallSignalHandler(int sig, void(*handler)(int));
63+
6264
/* Temporarily suspend SIGKILL. Return value of 1 means a restore is needed.
6365
* Other return values mean no restore is needed.
6466
*/

lib/tsan/rtl/tsan_rtl_thread.cc

+6-2
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,14 @@ void ThreadStart(ThreadState *thr, int tid, tid_t os_id, bool workerthread) {
275275
void ThreadFinish(ThreadState *thr) {
276276
ThreadCheckIgnore(thr);
277277
StatInc(thr, StatThreadFinish);
278-
if (thr->stk_addr && thr->stk_size)
278+
if (thr->stk_addr && thr->stk_size) {
279+
MemoryResetRange(thr, /*pc=*/ 1, thr->stk_addr, thr->stk_size);
279280
DontNeedShadowFor(thr->stk_addr, thr->stk_size);
280-
if (thr->tls_addr && thr->tls_size)
281+
}
282+
if (thr->tls_addr && thr->tls_size) {
283+
MemoryResetRange(thr, /*pc=*/ 1, thr->tls_addr, thr->tls_size);
281284
DontNeedShadowFor(thr->tls_addr, thr->tls_size);
285+
}
282286
thr->is_dead = true;
283287
ctx->thread_registry->FinishThread(thr->tid);
284288
}

test/lit.common.cfg

+3
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ if re.match(r'^x86_64.*-linux', config.target_triple):
101101
if config.have_zlib == "1":
102102
config.available_features.add("zlib")
103103

104+
if lit.util.isMacOSTriple(config.target_triple):
105+
config.available_features.add('darwin')
106+
104107
# Use ugly construction to explicitly prohibit "clang", "clang++" etc.
105108
# in RUN lines.
106109
config.substitutions.append(

test/lsan/lit.common.cfg

+5
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,8 @@ if re.search('mthumb', config.target_cflags) is not None:
7878
config.unsupported = True
7979

8080
config.suffixes = ['.c', '.cc', '.cpp', '.mm']
81+
82+
# Apple-Clang: Disable LSan
83+
if config.host_os == 'Darwin':
84+
lit_config.note('Disabling LSan tests on Darwin')
85+
config.unsupported = True
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %clang_profgen -o %t %s
2+
//
3+
// Verify SIGTERM handling.
4+
// RUN: %run LLVM_PROFILE_FILE="%15x%t.profraw" %t 15
5+
// RUN: llvm-profdata show %t.profraw | FileCheck %s
6+
//
7+
// Verify SIGUSR1 handling.
8+
// RUN: %run LLVM_PROFILE_FILE="%30x%t.profraw" %t 30
9+
// RUN: llvm-profdata show %t.profraw | FileCheck %s
10+
11+
#include <stdlib.h>
12+
#include <signal.h>
13+
#include <unistd.h>
14+
15+
// CHECK: Total functions: 1
16+
int main(int argc, char **argv) {
17+
(void)argc;
18+
19+
int sig = atoi(argv[1]);
20+
kill(getpid(), sig);
21+
22+
while (1) {
23+
/* loop forever */
24+
}
25+
return 1;
26+
}

test/sanitizer_common/lit.common.cfg

+6
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,9 @@ config.suffixes = ['.c', '.cc', '.cpp']
7070

7171
if config.host_os not in ['Linux', 'Darwin', 'NetBSD', 'FreeBSD']:
7272
config.unsupported = True
73+
74+
# Apple-internal: Disable LSan sanitizer_common tests
75+
# because AppleClang doesn't support LSan (rdar://problem/47381908).
76+
if config.tool_name == 'lsan' and config.host_os == 'Darwin':
77+
lit_config.note('LSan sanitizer_common tests disabled')
78+
config.unsupported = True

0 commit comments

Comments
 (0)