Currently, it is unclear if a test that is skipped is either:
- Unsupported because it will never run (macosx tests should not run on
Windows).
- Skipped because it's supposed to work but does not yet.
`@expectedFailure` is not always an option because a test might be
timing out and waiting 600s for it to fail is not acceptable.
This patch introduces 2 new decorators to differentiate those tests:
- `@requireX` meaning the tests require X to run (e.g `@requireDarwin`).
- `@requireNotX` meaning the tests requires anything but `X` to run (e.g
`@requireNotDarwin`).
In the tests results summary, this introduces a new category: `skipped`
tests:
- `@requireX` -> `UNSUPPORTED`
- `@skipIfX` -> `SKIPPED`
Here is how they can and cannot be stacked:
This will never run:
```py3
@requireDarwin
@requireWindows
def test():
...
```
This will not run on Linux, because `@requireWindows` is not satisfied.
```py3
@requireNotDarwin
@requireWindows
def test():
...
```
For "require Darwin or Windows", you need:
```py3
@requirePlatform(["darwin", "windows"])
def test():
...
```
For "require Darwin on ARM64 or Windows on ARM64", you need:
```py3
@requireARM64
@requirePlatform(["darwin", "windows"])
def test():
...
```
This patch also converts the tests in
`lldb/tests/API/{macosx,linux,windows}` to use these decorators. Patches
to convert the rest of the tests will follow.
150 lines
5.3 KiB
Python
150 lines
5.3 KiB
Python
"""Test that lldb will read additional registers from Mach-O LC_NOTE metadata."""
|
|
|
|
import os
|
|
import re
|
|
import subprocess
|
|
|
|
import lldb
|
|
from lldbsuite.test.decorators import *
|
|
from lldbsuite.test.lldbtest import *
|
|
from lldbsuite.test import lldbutil
|
|
|
|
|
|
class TestMetadataRegisters(TestBase):
|
|
NO_DEBUG_INFO_TESTCASE = True
|
|
|
|
@requireDarwin
|
|
@skipIfRemote
|
|
def test_add_registers_via_metadata(self):
|
|
self.build()
|
|
self.aout_exe = self.getBuildArtifact("a.out")
|
|
lldb_corefile = self.getBuildArtifact("lldb.core")
|
|
metadata_corefile = self.getBuildArtifact("metadata.core")
|
|
bad_metadata1_corefile = self.getBuildArtifact("bad-metadata1.core")
|
|
bad_metadata2_corefile = self.getBuildArtifact("bad-metadata2.core")
|
|
add_lcnote = self.getBuildArtifact("add-lcnote")
|
|
|
|
(target, process, t, bp) = lldbutil.run_to_source_breakpoint(
|
|
self, "break here", lldb.SBFileSpec("main.c")
|
|
)
|
|
|
|
self.assertTrue(process.IsValid())
|
|
|
|
if self.TraceOn():
|
|
self.runCmd("bt")
|
|
self.runCmd("reg read -a")
|
|
|
|
self.runCmd("process save-core " + lldb_corefile)
|
|
process.Kill()
|
|
target.Clear()
|
|
|
|
cmd = (
|
|
add_lcnote
|
|
+ " -r"
|
|
+ " -i '%s'" % lldb_corefile
|
|
+ " -o '%s'" % metadata_corefile
|
|
+ " -n 'process metadata' "
|
|
+ " -s '"
|
|
+ """{"threads":[{"register_info":
|
|
{"sets":["Special Registers", "General Purpose Registers"],
|
|
"registers":[
|
|
{"name":"jar", "value":10, "bitsize": 32, "set": 0},
|
|
{"name":"bar", "value":65537, "bitsize":16, "set":0},
|
|
{"name":"mar", "value":65537, "bitsize":32, "set":0},
|
|
{"name":"anotherpc", "value":55, "bitsize":64, "set": 1}]}}]}"""
|
|
+ "'"
|
|
)
|
|
call(cmd, shell=True)
|
|
|
|
cmd = (
|
|
add_lcnote
|
|
+ " -r"
|
|
+ " -i '%s'" % lldb_corefile
|
|
+ " -o '%s'" % bad_metadata1_corefile
|
|
+ " -n 'process metadata' "
|
|
+ " -s '"
|
|
+ """{lol im bad json}"""
|
|
+ "'"
|
|
)
|
|
call(cmd, shell=True)
|
|
|
|
cmd = (
|
|
add_lcnote
|
|
+ " -r"
|
|
+ " -i '%s'" % lldb_corefile
|
|
+ " -o '%s'" % bad_metadata2_corefile
|
|
+ " -n 'process metadata' "
|
|
+ " -s '"
|
|
+ """{"threads":[
|
|
{"register_info":
|
|
{"sets":["a"],"registers":[{"name":"a", "value":1, "bitsize": 32, "set": 0}]}},
|
|
{"register_info":
|
|
{"sets":["a"],"registers":[{"name":"a", "value":1, "bitsize": 32, "set": 0}]}}
|
|
]}"""
|
|
+ "'"
|
|
)
|
|
call(cmd, shell=True)
|
|
|
|
# Now load the corefile
|
|
target = self.dbg.CreateTarget("")
|
|
process = target.LoadCore(metadata_corefile)
|
|
self.assertTrue(process.IsValid())
|
|
if self.TraceOn():
|
|
self.runCmd("bt")
|
|
self.runCmd("reg read -a")
|
|
|
|
thread = process.GetSelectedThread()
|
|
frame = thread.GetFrameAtIndex(0)
|
|
|
|
# Register sets will be
|
|
# from LC_THREAD:
|
|
# General Purpose Registers
|
|
# Floating Point Registers
|
|
# Exception State Registers
|
|
# from LC_NOTE metadata:
|
|
# Special Registers
|
|
self.assertEqual(frame.registers[0].GetName(), "General Purpose Registers")
|
|
self.assertEqual(frame.registers[3].GetName(), "Special Registers")
|
|
|
|
anotherpc = frame.registers[0].GetChildMemberWithName("anotherpc")
|
|
self.assertTrue(anotherpc.IsValid())
|
|
self.assertEqual(anotherpc.GetValueAsUnsigned(), 0x37)
|
|
|
|
jar = frame.registers[3].GetChildMemberWithName("jar")
|
|
self.assertTrue(jar.IsValid())
|
|
self.assertEqual(jar.GetValueAsUnsigned(), 10)
|
|
self.assertEqual(jar.GetByteSize(), 4)
|
|
|
|
bar = frame.registers[3].GetChildMemberWithName("bar")
|
|
self.assertTrue(bar.IsValid())
|
|
self.assertEqual(bar.GetByteSize(), 2)
|
|
|
|
mar = frame.registers[3].GetChildMemberWithName("mar")
|
|
self.assertTrue(mar.IsValid())
|
|
self.assertEqual(mar.GetValueAsUnsigned(), 0x10001)
|
|
self.assertEqual(mar.GetByteSize(), 4)
|
|
|
|
# bad1 has invalid JSON, no additional registers
|
|
target = self.dbg.CreateTarget("")
|
|
process = target.LoadCore(bad_metadata1_corefile)
|
|
self.assertTrue(process.IsValid())
|
|
thread = process.GetSelectedThread()
|
|
frame = thread.GetFrameAtIndex(0)
|
|
gpr_found = False
|
|
for regset in frame.registers:
|
|
if regset.GetName() == "General Purpose Registers":
|
|
gpr_found = True
|
|
self.assertTrue(gpr_found)
|
|
|
|
# bad2 has invalid JSON, more process metadata threads than
|
|
# LC_THREADs, and should be rejected.
|
|
target = self.dbg.CreateTarget("")
|
|
process = target.LoadCore(bad_metadata2_corefile)
|
|
self.assertTrue(process.IsValid())
|
|
thread = process.GetSelectedThread()
|
|
frame = thread.GetFrameAtIndex(0)
|
|
metadata_regset_found = False
|
|
for regset in frame.registers:
|
|
if regset.GetName() == "a" or regset.GetName() == "b":
|
|
metadata_regset_found = True
|
|
self.assertFalse(metadata_regset_found)
|