[PB 6.30b5] ProgramExitCode() seemingly fails -1 randomly

Post bugreports for the Linux version here
ColeopterusMaximus
User
User
Posts: 69
Joined: Fri Oct 29, 2010 11:29 am

[PB 6.30b5] ProgramExitCode() seemingly fails -1 randomly

Post by ColeopterusMaximus »

I can reproduce this in PB6.20 and PB6.30 beta on Xubuntu18.04, Arch and Debian 12/13

The ProgramExitCode() function returns -1 at random, the shell program executes correctly, both stderr and stdout appear to be captured correctly however ProgramExitCode() throws a -1 at the exit code randomly, this has been driving me mad for a week until I realised it was a random occurrence

Sometimes it takes a few attempts to trigger it, some times thousands of attempts, it happens with any command, the example belows uses the ls and the route command the problem can happen after a few runs or after many thousands of rounds.

If someone else could please validate this and confirm it would be great.

Code: Select all

EnableExplicit

OpenConsole()

; Shell output
Structure uds_shell_output
    List lst_std_output.s()
    List lst_err_output.s()
EndStructure

; Just prints out a list to the console
; Permits prefix and suffixes to the output
Procedure.i ListPrint(List lst_lines.s(), str_prefix.s = "", str_suffix.s = "")
    ForEach lst_lines()
        PrintN(str_prefix + lst_lines() + str_suffix)
    Next
    ProcedureReturn #True
EndProcedure

; Runs a program and captures its output in a list
; asyncronously waiting for the program to finish on its own
; the program's exit code is returned by the function return
; value
Procedure.i get_RunOutputSync(str_program.s, str_parameters.s, *udt_shell_output.uds_shell_output)
    Protected int_pbprocessid.i = 0
    Protected int_exitcode.i    = 0
    Protected int_result.i      = 0
    Protected str_stdout.s      = ""
    Protected str_stderr.s      = ""

    ; Cleanup the output lists if they contain any data
    If ListSize(*udt_shell_output\lst_std_output())
        ClearList(*udt_shell_output\lst_std_output())
    EndIf
    If ListSize(*udt_shell_output\lst_err_output())
        ClearList(*udt_shell_output\lst_err_output())
    EndIf

    int_pbprocessid = RunProgram(str_program, str_parameters, "", #PB_Program_Open | #PB_Program_Read | #PB_Program_Error | #PB_Program_UTF8)
    If int_pbprocessid < 0
        PrintN("Peeky PID: " + int_pbprocessid) ; DEBUG DEBUG DEBUG
    EndIf
    If int_pbprocessid
        While ProgramRunning(int_pbprocessid)
            ; stderr has to be read first or it will fail
            str_stderr = ReadProgramError(int_pbprocessid)
            If str_stderr
                AddElement(*udt_shell_output\lst_err_output())
                *udt_shell_output\lst_err_output() + str_stderr
            EndIf
            If AvailableProgramOutput(int_pbprocessid)
                str_stdout = ReadProgramString(int_pbprocessid)
                If str_stdout
                    AddElement(*udt_shell_output\lst_std_output())
                    *udt_shell_output\lst_std_output() = str_stdout
                EndIf
            EndIf
        Wend
        int_result = WaitProgram(int_pbprocessid, 30000) ; 30s
        If int_result
            int_exitcode = ProgramExitCode(int_pbprocessid)
            PrintN("Peeky exit code2: " + int_exitcode)
            If int_pbprocessid < 0
                PrintN("Peeky exit code1: " + int_exitcode) ; DEBUG DEBUG DEBUG
            EndIf
        Else
            ; Timeout
            int_exitcode = -2000
        EndIf
        CloseProgram(int_pbprocessid) ; Close the connection to the program
    Else
        ; If we can't run the program
        int_exitcode = -1000
    EndIf

    ListPrint(*udt_shell_output\lst_std_output(), "std: ")
    ListPrint(*udt_shell_output\lst_err_output(), "stderr: ")

    ; We return the program exit code we use values >= 1000 to be 100% sure the errors are ours
    ProcedureReturn int_exitcode
EndProcedure

Define udt_route_output.uds_shell_output

Define int_return_code.i = 0
Define qua_counter.q = 0
Define str_error.s = ""

Repeat
    qua_counter + 1
    PrintN("Run: " + StrD(qua_counter))

    ; Run the command
    ;int_return_code = get_RunOutputSync("ls", "-l /etc", @udt_route_output)
    int_return_code = get_RunOutputSync("route", "-n", @udt_route_output)
   
    ; If error code
    If int_return_code
        Select int_return_code
            Case -1000
                str_error = "ERROR: Command not available aborting."
                Break
            Case -2000
                str_error = "ERROR: Command timed out on execution."
                Break
            Default
                str_error = "ERROR: Cmmand returned non 0 error code: " + Str(int_return_code) + " aborting."
                Break
        EndSelect
    EndIf
ForEver

CompilerIf #PB_Compiler_Debugger
    PrintN(Chr(10) + Chr(10) + "--- Program ended, Press esc to exit ---")
    Define str_keypress.s = ""
    Repeat
        Delay(20)
        str_keypress = Inkey()
    Until str_keypress = Chr(27)
CompilerEndIf
PeDe
Enthusiast
Enthusiast
Posts: 331
Joined: Sun Nov 26, 2017 3:13 pm

Re: [PB 6.30b5] ProgramExitCode() seemingly fails -1 randomly

Post by PeDe »

PB v6.30b5 arm64, Raspberry Pi OS (Trixie), P500

Aborted with -1 after 1300 runs. Then I inserted a delay(100) into the repeat loop, and the code aborted after 8752 runs.

Peter
ColeopterusMaximus
User
User
Posts: 69
Joined: Fri Oct 29, 2010 11:29 am

Re: [PB 6.30b5] ProgramExitCode() seemingly fails -1 randomly

Post by ColeopterusMaximus »

PeDe wrote: Fri Dec 12, 2025 3:15 pm PB v6.30b5 arm64, Raspberry Pi OS (Trixie), P500

Aborted with -1 after 1300 runs. Then I inserted a delay(100) into the repeat loop, and the code aborted after 8752 runs.

Peter
Thank you so much for checking.
Post Reply