Skip to content

Commit 39a5ab9

Browse files
committed
Separate out embedding the instruction vs. printing the faulting
instruction
1 parent cb98d98 commit 39a5ab9

File tree

4 files changed

+47
-27
lines changed

4 files changed

+47
-27
lines changed

compiler-rt/lib/msan/msan.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -352,9 +352,19 @@ void __sanitizer::BufferedStackTrace::UnwindImpl(
352352

353353
using namespace __msan;
354354

355-
#define PRINT_FAULTING_INSTRUCTION(instname) \
356-
Printf("Instruction that failed the shadow check: %s\n", instname); \
357-
Printf("\n");
355+
#define PRINT_FAULTING_INSTRUCTION(instname) \
356+
if (__msan::flags()->print_faulting_instruction) { \
357+
Printf("Instruction that failed the shadow check: %s\n", instname); \
358+
Printf("\n"); \
359+
}
360+
361+
#define CANNOT_PRINT_FAULTING_INSTRUCTION \
362+
if (__msan::flags()->print_faulting_instruction) { \
363+
Printf( \
364+
"Error: print_faulting_instruction requested but code was not " \
365+
"instrumented with -mllvm -embed-faulting-instruction.\n"); \
366+
Printf("\n"); \
367+
}
358368

359369
#define MSAN_MAYBE_WARNING_INSTNAME(type, size, instname) \
360370
void __msan_maybe_warning_instname_##size(type s, u32 o, char *instname) { \
@@ -379,6 +389,7 @@ MSAN_MAYBE_WARNING_INSTNAME(u64, 8, instname)
379389
void __msan_maybe_warning_##size(type s, u32 o) { \
380390
GET_CALLER_PC_BP; \
381391
if (UNLIKELY(s)) { \
392+
CANNOT_PRINT_FAULTING_INSTRUCTION; \
382393
PrintWarningWithOrigin(pc, bp, o); \
383394
if (__msan::flags()->halt_on_error) { \
384395
Printf("Exiting\n"); \
@@ -410,6 +421,7 @@ MSAN_MAYBE_STORE_ORIGIN(u32, 4)
410421
MSAN_MAYBE_STORE_ORIGIN(u64, 8)
411422

412423
void __msan_warning() {
424+
CANNOT_PRINT_FAULTING_INSTRUCTION;
413425
GET_CALLER_PC_BP;
414426
PrintWarningWithOrigin(pc, bp, 0);
415427
if (__msan::flags()->halt_on_error) {
@@ -421,6 +433,7 @@ void __msan_warning() {
421433
}
422434

423435
void __msan_warning_noreturn() {
436+
CANNOT_PRINT_FAULTING_INSTRUCTION;
424437
GET_CALLER_PC_BP;
425438
PrintWarningWithOrigin(pc, bp, 0);
426439
if (__msan::flags()->print_stats)
@@ -430,6 +443,7 @@ void __msan_warning_noreturn() {
430443
}
431444

432445
void __msan_warning_with_origin(u32 origin) {
446+
CANNOT_PRINT_FAULTING_INSTRUCTION;
433447
GET_CALLER_PC_BP;
434448
PrintWarningWithOrigin(pc, bp, origin);
435449
if (__msan::flags()->halt_on_error) {
@@ -441,6 +455,7 @@ void __msan_warning_with_origin(u32 origin) {
441455
}
442456

443457
void __msan_warning_with_origin_noreturn(u32 origin) {
458+
CANNOT_PRINT_FAULTING_INSTRUCTION;
444459
GET_CALLER_PC_BP;
445460
PrintWarningWithOrigin(pc, bp, origin);
446461
if (__msan::flags()->print_stats)

compiler-rt/lib/msan/msan_flags.inc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ MSAN_FLAG(bool, poison_stack_with_zeroes, false, "")
2525
MSAN_FLAG(bool, poison_in_malloc, true, "")
2626
MSAN_FLAG(bool, poison_in_free, true, "")
2727
MSAN_FLAG(bool, poison_in_dtor, true, "")
28+
MSAN_FLAG(bool, print_faulting_instruction, false,
29+
"When reporting a UUM, print the name of the faulting instruction. "
30+
"Note: requires code to be instrumented with -mllvm "
31+
"-msan-embed-faulting-instruction.")
2832
MSAN_FLAG(bool, report_umrs, true, "")
2933
MSAN_FLAG(bool, wrap_signals, true, "")
3034
MSAN_FLAG(bool, print_stats, false, "")

compiler-rt/test/msan/print_faulting_inst.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
11
// Try parameter '0' (program runs cleanly)
22
// -------------------------------------------------------
3-
// RUN: %clangxx_msan -g %s -o %t && %run %t 0
3+
// RUN: env MSAN_OPTIONS=print_faulting_instruction=true %clangxx_msan -g %s -o %t && env MSAN_OPTIONS=print_faulting_instruction=true %run %t 0
44

55
// Try parameter '1'
66
// -------------------------------------------------------
7-
// RUN: %clangxx_msan -g %s -o %t && not %run %t 1 >%t.out 2>&1
7+
// RUN: %clangxx_msan -g %s -o %t && not env MSAN_OPTIONS=print_faulting_instruction=true %run %t 1 >%t.out 2>&1
88
// RUN: FileCheck --check-prefix STORE-CHECK %s < %t.out
99

10-
// RUN: %clangxx_msan -mllvm -msan-print-faulting-instruction=1 -g %s -o %t && not %run %t 1 >%t.out 2>&1
10+
// RUN: %clangxx_msan -mllvm -msan-embed-faulting-instruction=1 -g %s -o %t && not env MSAN_OPTIONS=print_faulting_instruction=true %run %t 1 >%t.out 2>&1
1111
// RUN: FileCheck --check-prefixes VERBOSE-STORE-CHECK,STORE-CHECK %s < %t.out
1212

13-
// RUN: %clangxx_msan -mllvm -msan-print-faulting-instruction=2 -g %s -o %t && not %run %t 1 >%t.out 2>&1
13+
// RUN: %clangxx_msan -mllvm -msan-embed-faulting-instruction=2 -g %s -o %t && not env MSAN_OPTIONS=print_faulting_instruction=true %run %t 1 >%t.out 2>&1
1414
// RUN: FileCheck --check-prefixes VERY-VERBOSE-STORE-CHECK,STORE-CHECK %s < %t.out
1515

1616
// Try parameter '2', with -fsanitize-memory-param-retval
1717
// -------------------------------------------------------
18-
// RUN: %clangxx_msan -fsanitize-memory-param-retval -g %s -o %t && not %run %t 2 >%t.out 2>&1
18+
// RUN: %clangxx_msan -fsanitize-memory-param-retval -g %s -o %t && not env MSAN_OPTIONS=print_faulting_instruction=true %run %t 2 >%t.out 2>&1
1919
// RUN: FileCheck --check-prefix PARAM-CHECK %s < %t.out
2020

21-
// RUN: %clangxx_msan -fsanitize-memory-param-retval -mllvm -msan-print-faulting-instruction=1 -g %s -o %t && not %run %t 2 >%t.out 2>&1
21+
// RUN: %clangxx_msan -fsanitize-memory-param-retval -mllvm -msan-embed-faulting-instruction=1 -g %s -o %t && not env MSAN_OPTIONS=print_faulting_instruction=true %run %t 2 >%t.out 2>&1
2222
// RUN: FileCheck --check-prefixes VERBOSE-PARAM-CHECK,PARAM-CHECK %s < %t.out
2323

24-
// RUN: %clangxx_msan -fsanitize-memory-param-retval -mllvm -msan-print-faulting-instruction=2 -g %s -o %t && not %run %t 2 >%t.out 2>&1
24+
// RUN: %clangxx_msan -fsanitize-memory-param-retval -mllvm -msan-embed-faulting-instruction=2 -g %s -o %t && not env MSAN_OPTIONS=print_faulting_instruction=true %run %t 2 >%t.out 2>&1
2525
// RUN: FileCheck --check-prefixes VERY-VERBOSE-PARAM-CHECK,PARAM-CHECK %s < %t.out
2626

2727
// Try parameter '2', with -fno-sanitize-memory-param-retval
2828
// -------------------------------------------------------
29-
// RUN: %clangxx_msan -fno-sanitize-memory-param-retval -g %s -o %t && not %run %t 2 >%t.out 2>&1
29+
// RUN: %clangxx_msan -fno-sanitize-memory-param-retval -g %s -o %t && not env MSAN_OPTIONS=print_faulting_instruction=true %run %t 2 >%t.out 2>&1
3030
// RUN: FileCheck --check-prefix NO-PARAM-CHECK %s < %t.out
3131

32-
// RUN: %clangxx_msan -fno-sanitize-memory-param-retval -mllvm -msan-print-faulting-instruction=1 -g %s -o %t && not %run %t 2 >%t.out 2>&1
32+
// RUN: %clangxx_msan -fno-sanitize-memory-param-retval -mllvm -msan-embed-faulting-instruction=1 -g %s -o %t && not env MSAN_OPTIONS=print_faulting_instruction=true %run %t 2 >%t.out 2>&1
3333
// RUN: FileCheck --check-prefixes VERBOSE-NO-PARAM-CHECK,NO-PARAM-CHECK %s < %t.out
3434

35-
// RUN: %clangxx_msan -fno-sanitize-memory-param-retval -mllvm -msan-print-faulting-instruction=2 -g %s -o %t && not %run %t 2 >%t.out 2>&1
35+
// RUN: %clangxx_msan -fno-sanitize-memory-param-retval -mllvm -msan-embed-faulting-instruction=2 -g %s -o %t && not env MSAN_OPTIONS=print_faulting_instruction=true %run %t 2 >%t.out 2>&1
3636
// RUN: FileCheck --check-prefixes VERY-VERBOSE-NO-PARAM-CHECK,NO-PARAM-CHECK %s < %t.out
3737

3838
#include <stdio.h>

llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -274,11 +274,12 @@ static cl::opt<bool>
274274
cl::desc("propagate shadow through ICmpEQ and ICmpNE"),
275275
cl::Hidden, cl::init(true));
276276

277-
static cl::opt<uint> ClPrintFaultingInst(
278-
"msan-print-faulting-instruction",
279-
cl::desc("If set to 1, print the name of the LLVM IR instruction that "
277+
static cl::opt<uint> ClEmbedFaultingInst(
278+
"msan-embed-faulting-instruction",
279+
cl::desc("If set to 1, embed the name of the LLVM IR instruction that "
280280
"failed the shadow check."
281-
"If set to 2, print the full LLVM IR instruction."),
281+
"If set to 2, embed the full LLVM IR instruction. "
282+
"The runtime can print the embedded instruction."),
282283
cl::Hidden, cl::init(0));
283284

284285
static cl::opt<bool>
@@ -823,7 +824,7 @@ void MemorySanitizer::createKernelApi(Module &M, const TargetLibraryInfo &TLI) {
823824
VAArgOriginTLS = nullptr;
824825
VAArgOverflowSizeTLS = nullptr;
825826

826-
if (ClPrintFaultingInst)
827+
if (ClEmbedFaultingInst)
827828
WarningFn = M.getOrInsertFunction(
828829
"__msan_warning_instname", TLI.getAttrList(C, {0}, /*Signed=*/false),
829830
IRB.getVoidTy(), IRB.getInt32Ty(), IRB.getPtrTy());
@@ -888,7 +889,7 @@ void MemorySanitizer::createUserspaceApi(Module &M,
888889
// FIXME: this function should have "Cold" calling conv,
889890
// which is not yet implemented.
890891
if (TrackOrigins) {
891-
if (ClPrintFaultingInst) {
892+
if (ClEmbedFaultingInst) {
892893
StringRef WarningFnName =
893894
Recover ? "__msan_warning_with_origin_instname"
894895
: "__msan_warning_with_origin_noreturn_instname";
@@ -903,7 +904,7 @@ void MemorySanitizer::createUserspaceApi(Module &M,
903904
IRB.getVoidTy(), IRB.getInt32Ty());
904905
}
905906
} else {
906-
if (ClPrintFaultingInst) {
907+
if (ClEmbedFaultingInst) {
907908
StringRef WarningFnName = Recover ? "__msan_warning_instname"
908909
: "__msan_warning_noreturn_instname";
909910
WarningFn =
@@ -945,7 +946,7 @@ void MemorySanitizer::createUserspaceApi(Module &M,
945946
AccessSizeIndex++) {
946947
unsigned AccessSize = 1 << AccessSizeIndex;
947948
std::string FunctionName;
948-
if (ClPrintFaultingInst) {
949+
if (ClEmbedFaultingInst) {
949950
FunctionName = "__msan_maybe_warning_instname_" + itostr(AccessSize);
950951
MaybeWarningFn[AccessSizeIndex] = M.getOrInsertFunction(
951952
FunctionName, TLI.getAttrList(C, {0, 1}, /*Signed=*/false),
@@ -1449,7 +1450,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
14491450
}
14501451
}
14511452

1452-
if (ClPrintFaultingInst) {
1453+
if (ClEmbedFaultingInst) {
14531454
if (MS.CompileKernel || MS.TrackOrigins)
14541455
IRB.CreateCall(MS.WarningFn, {Origin, InstName})->setCannotMerge();
14551456
else
@@ -1478,7 +1479,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
14781479
Value *ConvertedShadow2 =
14791480
IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
14801481
CallBase *CB;
1481-
if (ClPrintFaultingInst)
1482+
if (ClEmbedFaultingInst)
14821483
CB = IRB.CreateCall(
14831484
Fn, {ConvertedShadow2,
14841485
MS.TrackOrigins && Origin ? Origin : (Value *)IRB.getInt32(0),
@@ -1498,7 +1499,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
14981499
/* Unreachable */ !MS.Recover, MS.ColdCallWeights);
14991500

15001501
IRB.SetInsertPoint(CheckTerm);
1501-
// InstName will be ignored by insertWarningFn if ClPrintFaultingInst is
1502+
// InstName will be ignored by insertWarningFn if ClEmbedFaultingInst is
15021503
// false
15031504
insertWarningFn(IRB, Origin, InstName);
15041505
LLVM_DEBUG(dbgs() << " CHECK: " << *Cmp << "\n");
@@ -1514,19 +1515,19 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
15141515
Instruction *Instruction = InstructionChecks.front().OrigIns;
15151516

15161517
Value *InstName = nullptr;
1517-
if (ClPrintFaultingInst >= 1) {
1518+
if (ClEmbedFaultingInst >= 1) {
15181519
IRBuilder<> IRB0(Instruction);
15191520
std::string str;
15201521
StringRef InstNameStrRef;
15211522

15221523
// Dumping the full instruction is expensive because the operands etc.
15231524
// likely make the string unique per instruction instance, hence we
15241525
// offer a choice whether to only print the instruction name.
1525-
if (ClPrintFaultingInst >= 2) {
1526+
if (ClEmbedFaultingInst >= 2) {
15261527
llvm::raw_string_ostream buf(str);
15271528
Instruction->print(buf);
15281529
InstNameStrRef = StringRef(str);
1529-
} else if (ClPrintFaultingInst >= 1) {
1530+
} else if (ClEmbedFaultingInst >= 1) {
15301531
if (CallInst *CI = dyn_cast<CallInst>(Instruction)) {
15311532
if (CI->getCalledFunction()) {
15321533
Twine description = "call " + CI->getCalledFunction()->getName();

0 commit comments

Comments
 (0)