Crash when reading from a PIPE:

4 posts / 0 new
Last post
Colin Ward
Colin Ward's picture
Offline
Last seen: 1 month 1 week ago
Joined: 2025-02-08 07:36
Crash when reading from a PIPE:

Hello everyone.

I have some code that launches a child process and then reads its output. It's working fine on OS3, but on OS4, both the m68k and PPC builds crash when I call IDOS->Read(). I've written below a simplified version (with error checking removed) of the code. Can anyone spot anything silly that I'm doing wrong that would cause this crash?

  1. BPTR stdInRead = Open("Console:", MODE_OLDFILE);
  2. BPTR stdOutWrite = Open("PIPE:RADRunner", MODE_NEWFILE);
  3. BPTR stdOutRead = Open("PIPE:RADRunner", MODE_OLDFILE);
  4.  
  5. BPTR segList = LoadSeg("my_app");
  6.  
  7. struct Process *process = CreateNewProcTags(NP_Seglist, (ULONG) segList, NP_Input, stdInRead,
  8. NP_Output, stdOutWrite, NP_ExitCode, (ULONG) ExitFunction, NP_ExitData, (ULONG) &exitCode,
  9. NP_Cli, TRUE, NP_StackSize, stackSize, TAG_DONE);
  10.  
  11. do
  12. {
  13. // The crash happens here, but it works perfectly on OS3
  14. if ((bytesRead = Read(stdOutRead, buffer, (STDOUT_BUFFER_SIZE - 1))) > 0)
  15. {
  16. buffer[bytesRead] = '\0';
  17. printf("%s", buffer);
  18. m_socket->write(buffer, bytesRead);
  19. }
  20. }
  21. while (bytesRead > 0);

Does anyone have any ideas?

thomas
thomas's picture
Offline
Last seen: 6 days 17 hours ago
Joined: 2011-05-16 14:23
Re: Crash when reading from a PIPE:

What's the crash code (guru number)?

OldFart
OldFart's picture
Offline
Last seen: 6 hours 31 min ago
Joined: 2010-11-30 14:09
Re: Crash when reading from a PIPE:

Hi Colin,

First of all: check whether an action was successfull whenever possible. That is considered 'good coding pratice'.
I added some checks:

  1. BPTR stdInRead = Open("Console:", MODE_OLDFILE);
  2. BPTR stdOutWrite = Open("PIPE:RADRunner", MODE_NEWFILE);
  3. BPTR stdOutRead = Open("PIPE:RADRunner", MODE_OLDFILE);
  4.  
  5. if (stdInRead && stdOutWrite && stdOutRead)
  6. {
  7. BPTR segList = LoadSeg("my_app");
  8.  
  9. if (seglist)
  10. {
  11. struct Process *process = CreateNewProcTags(NP_Seglist, (ULONG) segList, NP_Input, stdInRead,
  12. NP_Output, stdOutWrite, NP_ExitCode, (ULONG) ExitFunction, NP_ExitData, (ULONG) &exitCode,
  13. NP_Cli, TRUE, NP_StackSize, stackSize, TAG_DONE);
  14.  
  15. if (process)
  16. {
  17. do
  18. {
  19. // The crash happens here, but it works perfectly on OS3
  20. if ((bytesRead = Read(stdOutRead, buffer, (STDOUT_BUFFER_SIZE - 1))) > 0)
  21. {
  22. buffer[bytesRead] = '\0';
  23. printf("%s", buffer);
  24. m_socket->write(buffer, bytesRead);
  25. }
  26. }
  27. while (bytesRead > 0);
  28. }
  29. else Printf("ERROR: Failed to Create New Proces\n");
  30.  
  31. }
  32. else Printf("ERROR: Failed to Load Segment\n");
  33.  
  34. }
  35. else Printf("ERROR: Failed to Open a file\n");

Try and see what happens.

Regards
OldFart

cwenzel
cwenzel's picture
Offline
Last seen: 1 month 2 weeks ago
Joined: 2021-01-12 07:05
Re: Crash when reading from a PIPE:

(Copy of hyperion list reply here...)

Where is the child process exit arbitration code ?
Who is handling the allocated resources ?
You can't just create a new distinct child process and have it
go hurtling into code that was loaded and unloaded by another
process at any time without some sort of exit or resource arbitration.

The exitcode() for example is INSIDE the loaded segment for the parent
process that is calling createnewproc(), not the child segment itself,
what will happen if the parent exits and unloads before the child process. ?
The exitcode() code will be running in someone elses freed memory.
Also, who's closing the streams and unloading the seglist - and when ?
I can't see any of that, so I can't comment on this aspect.

You need a propper exit arbitration method at least.
There are examples in the CreateNewProc() autodoc.
This low level function requires a lot of care and understanding about
process context, ie. which process is doing what and when.

The puzzling question is; why are you not just using a propper shell-handler
process to take care of all the semantics and resources ?
Just use Systemtags(), that's what it's for.

Log in or register to post comments