Skip to content

pie build crashes if the SO file does not exist after the build #92

Closed

Description

@TimWolla

Running on #83:

Despite the code detecting that the .so is missing, it still attempts to use it and then emits a PHP Warnung and then crashes with a TypeError.

Build complete, but expected /root/.pie/php8.3_redacted/vendor/redacted/redacted/modules/redacted.so does not exist - however, this may be normal if this extension outputs the .so file in a different location.

Warning: hash_file(/root/.pie/php8.3_redacted/vendor/redacted/redacted/modules/redacted.so): Failed to open stream: No such file or directory in /pwd/src/BinaryFile.php on line 33

Fatal error: Uncaught TypeError: Php\Pie\BinaryFile::__construct(): Argument #2 ($checksum) must be of type string, false given, called in /pwd/src/BinaryFile.php on line 31 and defined in /pwd/src/BinaryFile.php:22
Stack trace:
#0 /pwd/src/BinaryFile.php(31): Php\Pie\BinaryFile->__construct('/root/.pie/php8...', false)
#1 /pwd/src/Building/UnixBuild.php(76): Php\Pie\BinaryFile::fromFileWithSha256Checksum('/root/.pie/php8...')
#2 /pwd/src/ComposerIntegration/InstallAndBuildProcess.php(53): Php\Pie\Building\UnixBuild->__invoke(Object(Php\Pie\Downloading\DownloadedPackage), Object(Php\Pie\Platform\TargetPlatform), Array, Object(Symfony\Component\Console\Output\ConsoleOutput))
#3 /pwd/src/ComposerIntegration/PiePackageInstaller.php(60): Php\Pie\ComposerIntegration\InstallAndBuildProcess->__invoke(Object(Composer\Composer), Object(Php\Pie\ComposerIntegration\PieComposerRequest), Object(Composer\Package\CompletePackage), '/root/.pie/php8...')
#4 /pwd/vendor/react/promise/src/Internal/FulfilledPromise.php(47): Php\Pie\ComposerIntegration\PiePackageInstaller->Php\Pie\ComposerIntegration\{closure}(NULL)
#5 /pwd/src/ComposerIntegration/PiePackageInstaller.php(38): React\Promise\Internal\FulfilledPromise->then(Object(Closure))
#6 /pwd/vendor/composer/composer/src/Composer/Installer/InstallationManager.php(467): Php\Pie\ComposerIntegration\PiePackageInstaller->install(Object(Composer\Repository\InstalledFilesystemRepository), Object(Composer\Package\CompletePackage))
#7 /pwd/vendor/composer/composer/src/Composer/Installer/InstallationManager.php(381): Composer\Installer\InstallationManager->install(Object(Composer\Repository\InstalledFilesystemRepository), Object(Composer\DependencyResolver\Operation\InstallOperation))
#8 /pwd/vendor/react/promise/src/Internal/FulfilledPromise.php(47): Composer\Installer\InstallationManager->Composer\Installer\{closure}(NULL)
#9 /pwd/vendor/composer/composer/src/Composer/Installer/InstallationManager.php(380): React\Promise\Internal\FulfilledPromise->then(Object(Closure))
#10 /pwd/vendor/composer/composer/src/Composer/Installer/InstallationManager.php(322): Composer\Installer\InstallationManager->executeBatch(Object(Composer\Repository\InstalledFilesystemRepository), Array, Array, false, true, Array)
#11 /pwd/vendor/composer/composer/src/Composer/Installer/InstallationManager.php(221): Composer\Installer\InstallationManager->downloadAndExecuteBatch(Object(Composer\Repository\InstalledFilesystemRepository), Array, Array, false, true, false, Array)
#12 /pwd/vendor/composer/composer/src/Composer/Installer.php(839): Composer\Installer\InstallationManager->execute(Object(Composer\Repository\InstalledFilesystemRepository), Array, false, true, false)
#13 /pwd/vendor/composer/composer/src/Composer/Installer.php(649): Composer\Installer->doInstall(Object(Composer\Repository\InstalledFilesystemRepository), true)
#14 /pwd/vendor/composer/composer/src/Composer/Installer.php(298): Composer\Installer->doUpdate(Object(Composer\Repository\InstalledFilesystemRepository), true)
#15 /pwd/src/ComposerIntegration/ComposerIntegrationHandler.php(69): Composer\Installer->run()
#16 /pwd/src/Command/BuildCommand.php(79): Php\Pie\ComposerIntegration\ComposerIntegrationHandler->__invoke(Object(Php\Pie\DependencyResolver\Package), Object(Composer\Composer), Object(Php\Pie\Platform\TargetPlatform), Object(Php\Pie\DependencyResolver\RequestedPackageAndVersion))
#17 /pwd/vendor/symfony/console/Command/Command.php(326): Php\Pie\Command\BuildCommand->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#18 /pwd/vendor/symfony/console/Application.php(1078): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#19 /pwd/vendor/symfony/console/Application.php(324): Symfony\Component\Console\Application->doRunCommand(Object(Php\Pie\Command\BuildCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#20 /pwd/vendor/symfony/console/Application.php(175): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#21 /pwd/bin/pie(64): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#22 {main}
  thrown in /pwd/src/BinaryFile.php on line 22

Activity

  1. self-assigned this
    on Nov 15, 2024
  2. asgrim commented on Nov 15, 2024

    @asgrim
    Contributor

    This would happen in the instance the package.xml (pecl) name does not match the output .so defined in PHP_NEW_EXTENSION(...). I did make an assumption when writing that, that the .so would always be named after the extension. Seems that is not always the case.

    Option 1: if the .so is not found, we could try to detect it. If there is only one .so we could pick it and use it (although, what if the ext builds multiple .so files, and the "actual" .so is not the one that built? If there is multiple .so how do we pick which one? Maybe prompt in this case? What if there is no .so files at all? Or it was built elsewhere than /modules/?

    Option 2: make the expected .so configurable in php-ext (if different from the ext name). I'm wary of adding config for edge cases, as it just increases complexity for maintainer authors; we'd have to be careful/explicit about naming and document something like this carefully

    Option 3: make the warning about expected .so not existing into a hard error, i.e. extension-name MUST match what is built in order to be PIE compatible. Add some documentation about the error for ext maintainers to help understanding. However, does mean that the PECL package name would be different from the ext name (e.g. a hypothetical package on PECL used to be called foo_bar but now it is called foobar), perhaps may cause some slight confusion.

    I'm personally leaning towards this latter option I think, given in theory, the ext name SHOULD be the same as the .so file name 🤔

  3. TimWolla commented on Nov 15, 2024

    @TimWolla
    MemberAuthor

    I'm personally leaning towards this latter option I think, given in theory, the ext name SHOULD be the same as the .so file name 🤔

    I agree. The PECL name is necessarily different than the composer name, because composer is namespaced. And the extension name defined in the C code differing from the .so name should be considered a bug, because it's extremely confusing to have extension=foobar in php.ini, but then extension_loaded('foo_bar') returns true.

  4. added this to the 0.2.0 milestone on Dec 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions