Author: kuba.brecka Date: Thu Apr 28 10:27:10 2016 New Revision: 267894 URL: http://llvm.org/viewvc/llvm-project?rev=267894&view=rev Log: Provide location information (file name, line number) in TSan reports about global variables.
Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/ lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/Makefile lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/TestTsanGlobalLocation.py lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/main.c Modified: lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/Makefile?rev=267894&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/Makefile (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/Makefile Thu Apr 28 10:27:10 2016 @@ -0,0 +1,6 @@ +LEVEL = ../../../make + +C_SOURCES := main.c +CFLAGS_EXTRAS := -fsanitize=thread -g + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/TestTsanGlobalLocation.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/TestTsanGlobalLocation.py?rev=267894&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/TestTsanGlobalLocation.py (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/TestTsanGlobalLocation.py Thu Apr 28 10:27:10 2016 @@ -0,0 +1,54 @@ +""" +Tests that TSan correctly reports the filename and line number of a racy global variable. +""" + +import os, time +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil +import json + +class TsanGlobalLocationTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)") + @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default + @skipIfRemote + @skipUnlessCompilerRt + @skipUnlessThreadSanitizer + def test (self): + self.build () + self.tsan_tests () + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + def tsan_tests (self): + exe = os.path.join (os.getcwd(), "a.out") + self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ]) + + self.runCmd("run") + + stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason() + if stop_reason == lldb.eStopReasonExec: + # On OS X 10.10 and older, we need to re-exec to enable interceptors. + self.runCmd("continue") + + # the stop reason of the thread should be breakpoint. + self.expect("thread list", "A data race should be detected", + substrs = ['stopped', 'stop reason = Data race detected']) + + self.expect("thread info -s", "The extended stop info should contain the TSan provided fields", + substrs = ["instrumentation_class", "description", "mops"]) + + output_lines = self.res.GetOutput().split('\n') + json_line = '\n'.join(output_lines[2:]) + data = json.loads(json_line) + self.assertEqual(data["instrumentation_class"], "ThreadSanitizer") + self.assertEqual(data["issue_type"], "data-race") + + self.assertTrue(data["location_filename"].endswith("/main.c")) + self.assertEqual(data["location_line"], line_number('main.c', '// global variable')) Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/main.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/main.c?rev=267894&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/main.c (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/tsan/global_location/main.c Thu Apr 28 10:27:10 2016 @@ -0,0 +1,38 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +long my_global_variable; // global variable + +void *f1(void *p) { + my_global_variable = 42; + return NULL; +} + +void *f2(void *p) { + my_global_variable = 43; + return NULL; +} + +int main (int argc, char const *argv[]) +{ + pthread_t t1; + pthread_create(&t1, NULL, f1, NULL); + + pthread_t t2; + pthread_create(&t2, NULL, f2, NULL); + + pthread_join(t1, NULL); + pthread_join(t2, NULL); + + return 0; +} Modified: lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp?rev=267894&r1=267893&r2=267894&view=diff ============================================================================== --- lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp (original) +++ lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp Thu Apr 28 10:27:10 2016 @@ -23,6 +23,8 @@ #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/Variable.h" +#include "lldb/Symbol/VariableList.h" #include "lldb/Target/InstrumentationRuntimeStopInfo.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/StopInfo.h" @@ -508,6 +510,32 @@ GetSymbolNameFromAddress(ProcessSP proce return sym_name; } +static void +GetSymbolDeclarationFromAddress(ProcessSP process_sp, addr_t addr, Declaration &decl) +{ + lldb_private::Address so_addr; + if (! process_sp->GetTarget().GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) + return; + + lldb_private::Symbol *symbol = so_addr.CalculateSymbolContextSymbol(); + if (! symbol) + return; + + ConstString sym_name = symbol->GetName(); + + ModuleSP module = symbol->CalculateSymbolContextModule(); + if (! module) + return; + + VariableList var_list; + module->FindGlobalVariables(sym_name, nullptr, true, 1U, var_list); + if (var_list.GetSize() < 1) + return; + + VariableSP var = var_list.GetVariableAtIndex(0); + decl = var->GetDeclaration(); +} + addr_t ThreadSanitizerRuntime::GetFirstNonInternalFramePc(StructuredData::ObjectSP trace) { @@ -582,7 +610,7 @@ ThreadSanitizerRuntime::GetMainRacyAddre } std::string -ThreadSanitizerRuntime::GetLocationDescription(StructuredData::ObjectSP report) +ThreadSanitizerRuntime::GetLocationDescription(StructuredData::ObjectSP report, std::string &filename, uint32_t &line) { std::string result = ""; @@ -595,6 +623,13 @@ ThreadSanitizerRuntime::GetLocationDescr addr_t addr = loc->GetAsDictionary()->GetValueForKey("address")->GetAsInteger()->GetValue(); std::string global_name = GetSymbolNameFromAddress(process_sp, addr); result = Sprintf("Location is a global '%s'", global_name.c_str()); + + Declaration decl; + GetSymbolDeclarationFromAddress(process_sp, addr, decl); + if (decl.GetFile()) { + filename = decl.GetFile().GetPath(); + line = decl.GetLine(); + } } else if (type == "heap") { addr_t addr = loc->GetAsDictionary()->GetValueForKey("start")->GetAsInteger()->GetValue(); long size = loc->GetAsDictionary()->GetValueForKey("size")->GetAsInteger()->GetValue(); @@ -634,8 +669,15 @@ ThreadSanitizerRuntime::NotifyBreakpoint report->GetAsDictionary()->AddStringItem("summary", summary); addr_t main_address = instance->GetMainRacyAddress(report); report->GetAsDictionary()->AddIntegerItem("memory_address", main_address); - std::string location_description = instance->GetLocationDescription(report); + + std::string location_filename = ""; + uint32_t location_line = 0; + std::string location_description = instance->GetLocationDescription(report, location_filename, location_line); report->GetAsDictionary()->AddStringItem("location_description", location_description); + if (location_filename != "") { + report->GetAsDictionary()->AddStringItem("location_filename", location_filename); + report->GetAsDictionary()->AddIntegerItem("location_line", location_line); + } } ProcessSP process_sp = instance->GetProcessSP(); Modified: lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h?rev=267894&r1=267893&r2=267894&view=diff ============================================================================== --- lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h (original) +++ lldb/trunk/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.h Thu Apr 28 10:27:10 2016 @@ -103,7 +103,7 @@ private: GetMainRacyAddress(StructuredData::ObjectSP report); std::string - GetLocationDescription(StructuredData::ObjectSP report); + GetLocationDescription(StructuredData::ObjectSP report, std::string &filename, uint32_t &line); lldb::addr_t GetFirstNonInternalFramePc(StructuredData::ObjectSP trace); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits