Error using Foundation Processes on Ubuntu

Hi all,

I'm using the Foundation library to start Process()-es on Ubuntu and it all works well for about 10-15 minutes after which I get the following error:

Fatal error: POSIX command failed with error: 9 -- EBADF: file /home/build-user/swift-corelibs-foundation/Sources/Foundation/Process.swift, line 925

This looks to me like an error in the swift library. Perhaps Ubuntu is not that well supported?

Many thanks.

Can you digest this down into a small test case and then post that?

The Process API has a bunch of potential pitfalls and it’s hard to tell from the info you’ve provided whether you’ve perhaps stumbled into one.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

Hi,

Apologies, for the late response, I had some other issues while trying to run/debug Swift on ubuntu and now it seems that It's (at least partially) working:

So basically I have 5-8 threads that run the following:

indent preformatted text by 4 spaces

func executeCommand(command: String, args: [String]) -> String {

        let task = Process()

        task.launchPath = command
        task.arguments = args

        let pipe = Pipe()
        task.standardOutput = pipe
        task.launch()

        let data = pipe.fileHandleForReading.readDataToEndOfFile()
        var output = NSString(data: data, encoding: String.Encoding.utf8.rawValue) 

        var output2 = output as! String;

        return output2
}



public func fuzzOne(_ group: DispatchGroup) {

    var parent = ""
    var program = ""

    var mutator = fuzzer.mutators.randomElement()
    

        program = executeCommand(
                command: "/bin/node",
                args: ["/home/adrian/Downloads/fuzzers/idl-master/parse.js", "1","/var/www/html","PROD","justjs"])

       let outcome =  execute(program, stats: &mutator.stats)

    }

Your code has plenty of things to be concerned about but I don’t see an obvious cause for this failure.

When it fails, do you get a Swift error? Or does the process die with a fatal error? An easy way to tell these apart is to set a breakpoint on swift_willThrow. Does it stop there? If so, what does the backtrace look like?

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

Thanks for the help, I must say I'm not a developer, especially not a swift developer.
This is the fatal error I get:

Fatal error: POSIX command failed with error: 9 -- EBADF: file /home/build-user/swift-corelibs-foundation/Sources/Foundation/Process.swift, line 925

This is the callstack:

indent preformatted text by 4 spaces
	_swift_runtime_on_report (@_swift_runtime_on_report:3)
_swift_stdlib_reportFatalErrorInFile (@_swift_stdlib_reportFatalErrorInFile:63)
closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in Swift._assertionFailure(_: Swift.StaticString, _: Swift.String, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never (@closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in Swift._assertionFailure(_: Swift.StaticString, _: Swift.String, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never:66)
closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in Swift._assertionFailure(_: Swift.StaticString, _: Swift.String, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never (@closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in Swift._assertionFailure(_: Swift.StaticString, _: Swift.String, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never:32)
function signature specialization <Arg[1] = [Closure Propagated : closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in Swift._assertionFailure(_: Swift.StaticString, _: Swift.String, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never, Argument Types : [Swift.StaticStringSwift.UnsafeBufferPointer<Swift.UInt8>Swift.UIntSwift.UInt32]> of generic specialization <()> of Swift.String.withUTF8<A>((Swift.UnsafeBufferPointer<Swift.UInt8>) throws -> A) throws -> A (@function signature specialization <Arg[1] = [Closure Propagated : closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in Swift._assertionFailure(_: Swift.StaticString, _: Swift.String, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never, Argument Types : [Swift.StaticStringSwift.UnsafeBufferPointer<Swift.UInt8>Swift.UIntSwift.UInt32]> of generic specialization <()> of Swift.String.withUTF8<A>((Swift.UnsafeBufferPointer<Swift.UInt8>) throws -> A) throws -> A:50)
Swift._assertionFailure(_: Swift.StaticString, _: Swift.String, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never (@Swift._assertionFailure(_: Swift.StaticString, _: Swift.String, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never:123)
Foundation.Process.run() throws -> () (@Foundation.Process.run() throws -> ():1975)
Foundation.Process.launch() -> () (@Foundation.Process.launch() -> ():15)
Fuzzilli.MutationEngine.executeCommand(command: Swift.String, args: Swift.Array<Swift.String>) -> Swift.String (/home/adrian/Downloads/fuzzers/fuzzilli/Sources/Fuzzilli/Core/MutationEngine.swift:108)
Fuzzilli.MutationEngine.fuzzOne(Dispatch.DispatchGroup) -> () (/home/adrian/Downloads/fuzzers/fuzzilli/Sources/Fuzzilli/Core/MutationEngine.swift:166)
protocol witness for Fuzzilli.FuzzEngine.fuzzOne(Dispatch.DispatchGroup) -> () in conformance Fuzzilli.MutationEngine : Fuzzilli.FuzzEngine in Fuzzilli (@protocol witness for Fuzzilli.FuzzEngine.fuzzOne(Dispatch.DispatchGroup) -> () in conformance Fuzzilli.MutationEngine : Fuzzilli.FuzzEngine in Fuzzilli:8)
Fuzzilli.Fuzzer.(fuzzOne in _54ECDA97F7E6F07CDC352895C65FED23)() -> () (/home/adrian/Downloads/fuzzers/fuzzilli/Sources/Fuzzilli/Fuzzer.swift:647)
closure #1 () -> () in Fuzzilli.Fuzzer.(fuzzOne in _54ECDA97F7E6F07CDC352895C65FED23)() -> () (/home/adrian/Downloads/fuzzers/fuzzilli/Sources/Fuzzilli/Fuzzer.swift:652)
reabstraction thunk helper from @escaping @callee_guaranteed () -> () to @escaping @callee_unowned @convention(block) () -> () (@reabstraction thunk helper from @escaping @callee_guaranteed () -> () to @escaping @callee_unowned @convention(block) () -> ():17)
_dispatch_call_block_and_release (@_dispatch_call_block_and_release:6)
_dispatch_lane_serial_drain (@_dispatch_lane_serial_drain:19)
_dispatch_lane_invoke (@_dispatch_lane_invoke:19)
_dispatch_worker_thread (@_dispatch_worker_thread:22)
start_thread (@start_thread:48)
clone (@clone:26)

I must say I'm not a developer, especially not a swift developer.

Well, I’m especially not a Linux developer, so we’re well matched (-: Seriously though, if you’re programming in Swift you are, by my standards, a Swift developer!

This is the callstack:

Thanks. Unfortunately that didn’t help. In Linux the backtrace doesn’t include line numbers, just function offsets, which makes things challenging.

What Swift version are you using? That is, what does the following print?

$ swift --version
Swift version 5.3.3 (swift-5.3.3-RELEASE)
Target: x86_64-unknown-linux-gnu

Is there any chance you can cut this down to a test project that doesn’t depend on your Node.js code? Perhaps use Process to run some other, built-in tool instead? That’ll help for a couple of reasons:

  • By cutting down the project you eliminate a bunch of dependencies, one of which might be causing this problem. For example, this might not be a bug in Process but a bug elsewhere in your project that’s accidentally closing a file descriptor (that’s an easy mistake to make). Cutting down your project might reveal that.

  • Even if it doesn’t, you’ll have a small reproducible test case that you can supply when asking for help (or when filing a bug).

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

Blockquote
Seriously though, if you’re programming in Swift you are, by my standards, a Swift developer!

Haha, thank you.

I'm now calling ls -l and same thing happens.
program = executeCommand(
command: "/bin/ls",
args: ["-l"])

Swift version

swift --version
Swift version 5.3.3 (swift-5.3.3-RELEASE)
Target: x86_64-unknown-linux-gnu

Are you able to run the strace tool on your binary? This will provide a log of the various system calls your program makes. It should tell us exactly which one is returning EBADF, and should also tell us whether you're closing an incorrect FD somewhere else in your program (hopefully).

Hi,

thanks for the tip. I got the strace log, but looks like I'm not allowed to uploaded it here. It's too large for pastebin as well...

I tried to do some debugging myself based on that, however I couldn't see any syscall returning EBADF (or code 9 as shown in the above error) when doing a grep on the strace log.

.