dolphinsmalltalk / Dolphin

Dolphin Smalltalk Core Image
MIT License
301 stars 58 forks source link

Dolphin 7.1.24: 3 issues regarding package .../Contributions/Udo Schneider/US ExternalProcess Extensions #1177

Open bernhardkohlhaas opened 1 year ago

bernhardkohlhaas commented 1 year ago

Since all issues are with the same package Dolphin/Core/Contributions/Udo Schneider/US ExternalProcess Extensions , I am grouping them together here. I hope that is okay.

Issue 1 In the implementation of method ExternalPipe>>createPipe (found in file Dolphin/Core/Contributions/Udo Schneider/ExternalPipe.cls) , the local variable "bResult" is never set, but yet accessed. I suppose it should have been assigned the answer of the method send to KernelLibrary, which returns a boolean.

I can't give an example to reproduce, because somehow I would need to provoke an error in the pipe creation, but I'd expect this one to be obvious from looking at the code.

Issue 2 This issue is about some loose methods that the project Dolphin/Core/Contributions/Udo Schneider/US ExternalProcess Extensions adds to the class ExternalProcess.

the current implementation for the ExternalProcess>>stdoutPipe (and potentially the other stdXXXPipe and stdXXXPipe: methods as well) can lead to a system hang in certain situations, when the method #stdoutPipe (and the other stdXXXPipe methods) are invoked more than once.

To Reproduce issue 2

This code works fine, when evaluated in a workspace (it only invokes External Process>>#stdoutPipe once):

process := ExternalProcess new
        commandLine: 'cmd /c ver';
        yourself.
stdoutPipe := process stdoutPipe.
process executeSync.
Transcript show: 'Accessing stdout';cr.
stdoutString := stdoutPipe readStream upToEnd.
Transcript show: 'Accessing stdout done'; cr.
stdoutString.

The following code hangs the system, when evaluated in a workspace (it invokes External Process>>#stdoutPipe twice):

process := ExternalProcess new
        commandLine: 'cmd /c ver';
        yourself.
stdoutPipe := process stdoutPipe.
process executeSync.
Transcript show: 'Accessing stdout';cr.
stdoutString := **process** stdoutPipe readStream upToEnd.
Transcript show: 'Accessing stdout done'; cr.
stdoutString.

The reason for the hang in the 2nd code example is that in method ExternalProcess>>stdoutPipe the condition stdout isKindOf: ExternalPipe always evaluates to false, because the invocation of self stdoutPipe in that method ( ExternalProcess>>stdoutPipe: ) does actually not store the ExternalPipe object in the stdout instance variable, but the result of sending #writeStream to that pipe (which answers an StdioAnsiFileStream object.

The actual hang appears to happen in StdioFileStream>>basicPeek at crtlib fgetc: stream.

Expected behavior for issue 2 I would expect ExternalProcess>>stdoutPipe (and the other stdXXXPipe methods) to either return the identical object as before (a bit tricky, since using the instance variable probably isn't possible) or returning a different ExternalPipe object that would provide the same data that the original ExternalPipe object would. At the very minimum this should not hang the system.

Screenshot for issue 2 Debugging snapshot of the stack, when the hang happens: image

Please complete the following information):

Issue 3 At the moment the evaluation of stdoutPipe readStream upToEnd in issue #1 above always returns an AnsiString instance. I have a situation, where I am actually receiving data from stdout in UTF8 format, which makes the output look weird for certain special characters. I know that I can "coerce" the ANSI string into a UTF8 string by creating a Utf8String instance of the same byte length and then copying the result over byte by byte and then the output will look correct.

Still I'm wondering, if this is what is supposed to happen. If an example is needed (or I should create an enhancement request or a discussion item instead), please let me know.