blob: 78046125860bf5817d488ddbbf07e0f1b448f5ac [file] [edit]
"""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)