Skip to content

Commit

Permalink
[analyzer] Use absolute path to logger.so in LD_PRELOAD
Browse files Browse the repository at this point in the history
  • Loading branch information
vodorok committed May 25, 2023
1 parent a07a74a commit 3b0fcc5
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 26 deletions.
20 changes: 16 additions & 4 deletions analyzer/codechecker_analyzer/analyzer_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import os
import sys

from pathlib import Path

from codechecker_common import logger
from codechecker_common.checker_labels import CheckerLabels
from codechecker_common.singleton import Singleton
Expand Down Expand Up @@ -63,12 +65,18 @@ def __init__(self):
self.__analyzers = {}
self.__analyzer_env = None

machine = os.uname().machine

self.logger_lib_dir_path = os.path.join(
self._data_files_dir_path, 'ld_logger', 'lib')
self._data_files_dir_path, 'ld_logger', 'lib', machine)

if not os.path.exists(self.logger_lib_dir_path):
self.logger_lib_dir_path = os.path.join(
self._lib_dir_path, 'codechecker_analyzer', 'ld_logger', 'lib')
self._lib_dir_path,
'codechecker_analyzer',
'ld_logger',
'lib',
machine)

self.logger_bin = None
self.logger_file = None
Expand Down Expand Up @@ -231,8 +239,12 @@ def path_logger_bin(self):
return os.path.join(self._bin_dir_path, 'ld_logger')

@property
def path_logger_lib(self):
return self.logger_lib_dir_path
def logger_lib_path(self):
"""
Returns the absolute path to the logger library.
"""
return str(Path(self.logger_lib_dir_path,
self.logger_lib_name).absolute())

@property
def logger_lib_name(self):
Expand Down
9 changes: 1 addition & 8 deletions analyzer/codechecker_analyzer/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,7 @@ def get_log_env(logfile, original_env):

new_env[context.env_var_cc_logger_bin] = context.path_logger_bin

new_env['LD_PRELOAD'] = context.logger_lib_name

try:
original_ld_library_path = new_env['LD_LIBRARY_PATH']
new_env['LD_LIBRARY_PATH'] = context.path_logger_lib + ':' + \
original_ld_library_path
except KeyError:
new_env['LD_LIBRARY_PATH'] = context.path_logger_lib
new_env['LD_PRELOAD'] = context.logger_lib_path

# Set ld logger logfile.
new_env[context.env_var_cc_logger_file] = logfile
Expand Down
23 changes: 23 additions & 0 deletions analyzer/tests/unit/test_log_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import unittest

from codechecker_analyzer.buildlog import log_parser
from codechecker_analyzer.env import get_log_env
from codechecker_common.skiplist_handler import SkipListHandler, \
SkipListHandlers
from codechecker_common.util import load_json
Expand Down Expand Up @@ -664,3 +665,25 @@ def test_symlink(self):

self.assertEqual(len(build_actions), 3)
self.assertEqual(build_action.source, fileC_symdir)

def test_get_log_env(self):
"""
Test if get_log_env returns the correct environment
with LD_PRELOAD set to pointing to the correct directory
of the ldlogger.so lib.
"""
log_file = os.path.join(self.tmp_dir, "compile_commands.json")
original_env = os.environ.copy()
# If this asset fails, make sure that you don't have LD_PRELOAD set
# in your environment.
self.assertNotIn("LD_PRELOAD", original_env)
env = get_log_env(log_file, original_env)

# The new environment should contain the LD_PRELOAD variable.
self.assertIn("LD_PRELOAD", env)

# Make sure that the test running machine architecture is in the
# LD_PRELOAD path.
machine = os.uname().machine
self.assertTrue(env["LD_PRELOAD"].endswith(machine + "/ldlogger.so"))

3 changes: 1 addition & 2 deletions analyzer/tools/build-logger/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ make all test

Set the following environment variables:
~~~~~~~
export LD_PRELOAD=ldlogger.so
export LD_LIBRARY_PATH=`pwd`/build/lib:$LD_LIBRARY_PATH
export LD_PRELOAD=`pwd`/build/lib/`uname -m`/ldlogger.so
export CC_LOGGER_GCC_LIKE="gcc:g++:clang:clang++:cc:c++"
# The output compilation JSON file.
export CC_LOGGER_FILE=`pwd`/compilation.json
Expand Down
7 changes: 5 additions & 2 deletions analyzer/tools/build-logger/tests/unit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,13 @@ def read_actual_json(self) -> str:
return fd.read()

def get_envvars(self) -> Mapping[str, str]:
machine = os.uname().machine
return {
"PATH": os.getenv("PATH"),
"LD_PRELOAD": "ldlogger.so",
"LD_LIBRARY_PATH": os.path.join(LOGGER_DIR, "lib"),
"LD_PRELOAD": os.path.join(LOGGER_DIR,
"lib",
machine,
"ldlogger.so"),
"CC_LOGGER_GCC_LIKE": "gcc:g++:clang:clang++:cc:c++",
"CC_LOGGER_FILE": self.logger_file,
"CC_LOGGER_DEBUG_FILE": self.logger_debug_file,
Expand Down
10 changes: 0 additions & 10 deletions analyzer/tools/build-logger/tests/unit/test_paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import os
import shutil
import tempfile
from typing import Mapping
from . import BasicLoggerTest, empty_env, REPO_ROOT

AVAILABLE_GNU_COMPILERS = [
Expand All @@ -14,13 +13,6 @@
]


def append_host_LD_LIBRARY_PATH(env: Mapping[str, str]) -> Mapping[str, str]:
LD_LIBRARY_PATH = os.getenv("LD_LIBRARY_PATH")
if LD_LIBRARY_PATH:
env["LD_LIBRARY_PATH"] += ':' + LD_LIBRARY_PATH
return env


class EscapingTests(BasicLoggerTest):
def test_compiler_path1(self):
"""
Expand Down Expand Up @@ -250,7 +242,6 @@ def test_response_file(self):
"""Test clang-specific response files."""
logger_env = self.get_envvars()
# clang might need Z3
logger_env = append_host_LD_LIBRARY_PATH(logger_env)
file = self.source_file
binary = self.binary_file
clang = shutil.which("clang")
Expand Down Expand Up @@ -286,7 +277,6 @@ def test_response_file_contain_source_file(self):
"""
logger_env = self.get_envvars()
# clang might need Z3
logger_env = append_host_LD_LIBRARY_PATH(logger_env)
file = self.source_file
binary = self.binary_file
clang = shutil.which("clang")
Expand Down

0 comments on commit 3b0fcc5

Please sign in to comment.