Passed
Push — master ( a5c131...325eda )
by Shinji
01:37
created

createContainerAwarePath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the sj-i/php-profiler package.
5
 *
6
 * (c) sji <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace PhpProfiler\Lib\Elf\Process;
15
16
use PhpProfiler\Lib\Elf\Parser\ElfParserException;
17
use PhpProfiler\Lib\Elf\SymbolResolver\SymbolResolverCreator;
18
use PhpProfiler\Lib\Process\MemoryMap\ProcessMemoryMap;
19
use PhpProfiler\Lib\Process\MemoryReader\MemoryReaderInterface;
20
21
/**
22
 * Class ProcessModuleSymbolReaderCreator
23
 * @package PhpProfiler\ProcessReader
24
 */
25
final class ProcessModuleSymbolReaderCreator
26
{
27
    private SymbolResolverCreator $symbol_resolver_creator;
28
    private MemoryReaderInterface $memory_reader;
29
30
    /**
31
     * ProcessSymbolReaderCreator constructor.
32
     *
33
     * @param SymbolResolverCreator $symbol_resolver_creator
34
     * @param MemoryReaderInterface $memory_reader
35
     */
36
    public function __construct(
37
        SymbolResolverCreator $symbol_resolver_creator,
38
        MemoryReaderInterface $memory_reader
39
    ) {
40
        $this->symbol_resolver_creator = $symbol_resolver_creator;
41
        $this->memory_reader = $memory_reader;
42
    }
43
44
    /**
45
     * @param int $pid
46
     * @param ProcessMemoryMap $process_memory_map
47
     * @param string $regex
48
     * @param int|null $tls_block_address
49
     * @return ProcessModuleSymbolReader|null
50
     * @throws ElfParserException
51
     */
52
    public function createModuleReaderByNameRegex(
53
        int $pid,
54
        ProcessMemoryMap $process_memory_map,
55
        string $regex,
56
        ?int $tls_block_address = null
57
    ): ?ProcessModuleSymbolReader {
58
        $memory_areas = $process_memory_map->findByNameRegex($regex);
59
        if ($memory_areas === []) {
60
            return null;
61
        }
62
63
        $module_name = current($memory_areas)->name;
64
        $container_aware_path = $this->createContainerAwarePath($pid, $module_name);
65
        try {
66
            $symbol_resolver = $this->symbol_resolver_creator->createLinearScanResolverFromPath($container_aware_path);
67
            return new ProcessModuleSymbolReader(
68
                $pid,
69
                $symbol_resolver,
70
                $memory_areas,
71
                $this->memory_reader,
72
                $tls_block_address
73
            );
74
        } catch (ElfParserException $e) {
75
            $symbol_resolver = $this->symbol_resolver_creator->createDynamicResolverFromPath($container_aware_path);
76
            return new ProcessModuleSymbolReader(
77
                $pid,
78
                $symbol_resolver,
79
                $memory_areas,
80
                $this->memory_reader,
81
                $tls_block_address
82
            );
83
        }
84
    }
85
86
    /**
87
     * @param int $pid
88
     * @param string $path
89
     * @return string
90
     */
91
    private function createContainerAwarePath(int $pid, string $path): string
92
    {
93
        return "/proc/{$pid}/root{$path}";
94
    }
95
}
96