Passed
Push — master ( c2a6de...b42a4e )
by Shinji
01:35
created

GetCurrentFunctionNameCommand::writeError()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
c 0
b 0
f 0
nc 2
nop 2
dl 0
loc 4
rs 10
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\Command\Inspector;
15
16
use PhpProfiler\Command\CommandSettingsException;
17
use PhpProfiler\Command\Inspector\Settings\LoopSettings;
18
use PhpProfiler\Command\Inspector\Settings\TargetProcessSettings;
19
use PhpProfiler\Lib\Elf\Parser\ElfParserException;
20
use PhpProfiler\Lib\Elf\Process\ProcessSymbolReaderException;
21
use PhpProfiler\Lib\Elf\Tls\TlsFinderException;
22
use PhpProfiler\Lib\PhpProcessReader\PhpGlobalsFinder;
23
use PhpProfiler\Lib\Process\MemoryReader\MemoryReaderException;
24
use PhpProfiler\Lib\PhpProcessReader\PhpMemoryReader\ExecutorGlobalsReader;
25
use Symfony\Component\Console\Command\Command;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Command\Command was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
26
use Symfony\Component\Console\Input\InputInterface;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Input\InputInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
27
use Symfony\Component\Console\Input\InputOption;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Input\InputOption was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28
use Symfony\Component\Console\Output\OutputInterface;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Output\OutputInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
29
30
final class GetCurrentFunctionNameCommand extends Command
31
{
32
    private PhpGlobalsFinder $php_globals_finder;
33
    private ExecutorGlobalsReader $executor_globals_reader;
34
    private TraceLoopProvider $loop_provider;
35
36
    /**
37
     * GetCurrentFunctionNameCommand constructor.
38
     *
39
     * @param PhpGlobalsFinder $php_globals_finder
40
     * @param ExecutorGlobalsReader $executor_globals_reader
41
     * @param TraceLoopProvider $loop_provider
42
     */
43
    public function __construct(
44
        PhpGlobalsFinder $php_globals_finder,
45
        ExecutorGlobalsReader $executor_globals_reader,
46
        TraceLoopProvider $loop_provider
47
    ) {
48
        parent::__construct();
49
        $this->php_globals_finder = $php_globals_finder;
50
        $this->executor_globals_reader = $executor_globals_reader;
51
        $this->loop_provider = $loop_provider;
52
    }
53
54
    public function configure(): void
55
    {
56
        $this->setName('inspector:current_function')
57
            ->setDescription('periodically get running function name from an outer process or thread')
58
            ->addOption('pid', 'p', InputOption::VALUE_REQUIRED, 'process id')
59
            ->addOption(
60
                'sleep-ns',
61
                's',
62
                InputOption::VALUE_OPTIONAL,
63
                'nanoseconds between traces (default: 1000 * 1000 * 10)'
64
            );
65
    }
66
67
    /**
68
     * @param InputInterface $input
69
     * @param OutputInterface $output
70
     * @return int
71
     * @throws MemoryReaderException
72
     * @throws ProcessSymbolReaderException
73
     * @throws ElfParserException
74
     * @throws TlsFinderException
75
     * @throws CommandSettingsException
76
     */
77
    public function execute(InputInterface $input, OutputInterface $output): int
78
    {
79
        $target_process_settings = TargetProcessSettings::fromConsoleInput($input);
80
        $loop_settings = LoopSettings::fromConsoleInput($input);
81
82
        $pid = $target_process_settings->pid;
83
        $eg_address = $this->php_globals_finder->findExecutorGlobals($pid);
84
85
        $this->loop_provider->getMainLoop(
86
            function () use ($pid, $eg_address, $output): bool {
87
                $output->writeln(
88
                    $this->executor_globals_reader->readCurrentFunctionName($pid, $eg_address)
89
                );
90
                return true;
91
            },
92
            $loop_settings
93
        )->invoke();
94
95
        return 0;
96
    }
97
}
98