1"""Test that thread-local storage can be read correctly.""" 2 3 4import os 5import lldb 6from lldbsuite.test.decorators import * 7from lldbsuite.test.lldbtest import * 8from lldbsuite.test import lldbutil 9 10 11class TlsGlobalTestCase(TestBase): 12 def setUp(self): 13 TestBase.setUp(self) 14 15 if self.getPlatform() == "freebsd" or self.getPlatform() == "linux": 16 # LD_LIBRARY_PATH must be set so the shared libraries are found on 17 # startup 18 if "LD_LIBRARY_PATH" in os.environ: 19 self.runCmd( 20 "settings set target.env-vars " 21 + self.dylibPath 22 + "=" 23 + os.environ["LD_LIBRARY_PATH"] 24 + ":" 25 + self.getBuildDir() 26 ) 27 else: 28 self.runCmd( 29 "settings set target.env-vars " 30 + self.dylibPath 31 + "=" 32 + self.getBuildDir() 33 ) 34 self.addTearDownHook( 35 lambda: self.runCmd("settings remove target.env-vars " + self.dylibPath) 36 ) 37 38 # TLS works differently on Windows, this would need to be implemented 39 # separately. 40 @skipIfWindows 41 @skipIf(oslist=["linux"], archs=["arm", "aarch64"]) 42 @skipIf(oslist=no_match([lldbplatformutil.getDarwinOSTriples(), "linux"])) 43 @expectedFailureIf(lldbplatformutil.xcode15LinkerBug()) 44 def test(self): 45 """Test thread-local storage.""" 46 self.build() 47 exe = self.getBuildArtifact("a.out") 48 target = self.dbg.CreateTarget(exe) 49 if self.platformIsDarwin(): 50 self.registerSharedLibrariesWithTarget(target, ["liba.dylib"]) 51 52 line1 = line_number("main.c", "// thread breakpoint") 53 lldbutil.run_break_set_by_file_and_line( 54 self, "main.c", line1, num_expected_locations=1, loc_exact=True 55 ) 56 self.runCmd("run", RUN_SUCCEEDED) 57 58 # The stop reason of the thread should be breakpoint. 59 self.runCmd("process status", "Get process status") 60 self.expect( 61 "thread list", 62 STOPPED_DUE_TO_BREAKPOINT, 63 substrs=["stopped", "stop reason = breakpoint"], 64 ) 65 66 # BUG: sometimes lldb doesn't change threads to the stopped thread. 67 # (unrelated to this test). 68 self.runCmd("thread select 2", "Change thread") 69 70 # Check that TLS evaluates correctly within the thread. 71 self.expect( 72 "expr var_static", 73 VARIABLES_DISPLAYED_CORRECTLY, 74 patterns=["\(int\) \$.* = 88"], 75 ) 76 self.expect( 77 "expr var_shared", 78 VARIABLES_DISPLAYED_CORRECTLY, 79 patterns=["\(int\) \$.* = 66"], 80 ) 81 82 # Continue on the main thread 83 line2 = line_number("main.c", "// main breakpoint") 84 lldbutil.run_break_set_by_file_and_line( 85 self, "main.c", line2, num_expected_locations=1, loc_exact=True 86 ) 87 self.runCmd("continue", RUN_SUCCEEDED) 88 89 # The stop reason of the thread should be breakpoint. 90 self.runCmd("process status", "Get process status") 91 self.expect( 92 "thread list", 93 STOPPED_DUE_TO_BREAKPOINT, 94 substrs=["stopped", "stop reason = breakpoint"], 95 ) 96 97 # BUG: sometimes lldb doesn't change threads to the stopped thread. 98 # (unrelated to this test). 99 self.runCmd("thread select 1", "Change thread") 100 101 # Check that TLS evaluates correctly within the main thread. 102 self.expect( 103 "expr var_static", 104 VARIABLES_DISPLAYED_CORRECTLY, 105 patterns=["\(int\) \$.* = 44"], 106 ) 107 self.expect( 108 "expr var_shared", 109 VARIABLES_DISPLAYED_CORRECTLY, 110 patterns=["\(int\) \$.* = 33"], 111 ) 112