Commit 3abf7f5f authored by Sasha Goldshtein's avatar Sasha Goldshtein

tests: Test debuginfo through debuglink and build-id sections

This commit introduces support for tests of the new debuglink and
build-id debuginfo resolution functionality. The tests build a
dummy.c file with a debuglink section, and again with a build-id
section, and make sure that the symbol resolution code can locate
the debug information correctly (in the binary's directory for
debuglink, and in /usr/lib/debug/.build-id for the build-id).
parent 03ab5e8f
...@@ -36,6 +36,8 @@ add_test(NAME py_test_trace4 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ...@@ -36,6 +36,8 @@ add_test(NAME py_test_trace4 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${TEST_WRAPPER} py_trace4 sudo ${CMAKE_CURRENT_SOURCE_DIR}/test_trace4.py) COMMAND ${TEST_WRAPPER} py_trace4 sudo ${CMAKE_CURRENT_SOURCE_DIR}/test_trace4.py)
add_test(NAME py_test_probe_count WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} add_test(NAME py_test_probe_count WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${TEST_WRAPPER} py_probe_count sudo ${CMAKE_CURRENT_SOURCE_DIR}/test_probe_count.py) COMMAND ${TEST_WRAPPER} py_probe_count sudo ${CMAKE_CURRENT_SOURCE_DIR}/test_probe_count.py)
add_test(NAME py_test_debuginfo WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${TEST_WRAPPER} py_test_debuginfo sudo ${CMAKE_CURRENT_SOURCE_DIR}/test_debuginfo.py)
add_test(NAME py_test_brb WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} add_test(NAME py_test_brb WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${TEST_WRAPPER} py_brb_c sudo ${CMAKE_CURRENT_SOURCE_DIR}/test_brb.py test_brb.c) COMMAND ${TEST_WRAPPER} py_brb_c sudo ${CMAKE_CURRENT_SOURCE_DIR}/test_brb.py test_brb.c)
add_test(NAME py_test_brb2 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} add_test(NAME py_test_brb2 WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
...@@ -60,6 +62,5 @@ add_test(NAME py_test_utils WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ...@@ -60,6 +62,5 @@ add_test(NAME py_test_utils WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${TEST_WRAPPER} py_test_utils sudo ${CMAKE_CURRENT_SOURCE_DIR}/test_utils.py) COMMAND ${TEST_WRAPPER} py_test_utils sudo ${CMAKE_CURRENT_SOURCE_DIR}/test_utils.py)
add_test(NAME py_test_percpu WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} add_test(NAME py_test_percpu WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${TEST_WRAPPER} py_test_percpu sudo ${CMAKE_CURRENT_SOURCE_DIR}/test_percpu.py) COMMAND ${TEST_WRAPPER} py_test_percpu sudo ${CMAKE_CURRENT_SOURCE_DIR}/test_percpu.py)
add_test(NAME py_test_dump_func WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} add_test(NAME py_test_dump_func WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${TEST_WRAPPER} py_dump_func simple ${CMAKE_CURRENT_SOURCE_DIR}/test_dump_func.py) COMMAND ${TEST_WRAPPER} py_dump_func simple ${CMAKE_CURRENT_SOURCE_DIR}/test_dump_func.py)
#include <unistd.h>
#include <stdio.h>
static __attribute__((noinline)) int some_function(int x, int y) {
volatile int z = x + y;
return z;
}
int main() {
printf("%p\n", &some_function);
fflush(stdout);
printf("result = %d\n", some_function(42, 11));
sleep(1000);
return 0;
}
#!/usr/bin/env python
# Copyright (c) Sasha Goldshtein
# Licensed under the Apache License, Version 2.0 (the "License")
import os
import subprocess
from bcc import SymbolCache
from unittest import main, TestCase
class Harness(TestCase):
def setUp(self):
self.build_command()
subprocess.check_output('objcopy --only-keep-debug dummy dummy.debug'
.split())
self.debug_command()
subprocess.check_output('strip dummy'.split())
self.process = subprocess.Popen('./dummy', stdout=subprocess.PIPE)
# The process prints out the address of some symbol, which we then
# try to resolve in the test.
self.addr = int(self.process.stdout.readline().strip(), 16)
self.syms = SymbolCache(self.process.pid)
def tearDown(self):
self.process.kill()
def resolve_addr(self):
sym, offset, module = self.syms.resolve(self.addr)
self.assertEqual(sym, 'some_function')
self.assertEqual(offset, 0)
self.assertTrue(module[-5:] == 'dummy')
def resolve_name(self):
script_dir = os.path.dirname(os.path.realpath(__file__))
addr = self.syms.resolve_name(os.path.join(script_dir, 'dummy'),
'some_function')
self.assertEqual(addr, self.addr)
pass
class TestDebuglink(Harness):
def build_command(self):
subprocess.check_output('gcc -o dummy dummy.c'.split())
def debug_command(self):
subprocess.check_output('objcopy --add-gnu-debuglink=dummy.debug dummy'
.split())
def tearDown(self):
subprocess.check_output('rm dummy dummy.debug'.split())
def test_resolve_addr(self):
self.resolve_addr()
def test_resolve_name(self):
self.resolve_name()
class TestBuildid(Harness):
def build_command(self):
subprocess.check_output(('gcc -o dummy -Xlinker ' + \
'--build-id=0x123456789abcdef0123456789abcdef012345678 dummy.c')
.split())
def debug_command(self):
subprocess.check_output('mkdir -p /usr/lib/debug/.build-id/12'.split())
subprocess.check_output(('mv dummy.debug /usr/lib/debug/.build-id' + \
'/12/3456789abcdef0123456789abcdef012345678.debug').split())
def tearDown(self):
subprocess.check_output('rm dummy'.split())
subprocess.check_output(('rm /usr/lib/debug/.build-id/12' +
'/3456789abcdef0123456789abcdef012345678.debug').split())
def test_resolve_name(self):
self.resolve_addr()
def test_resolve_addr(self):
self.resolve_name()
if __name__ == "__main__":
main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment