22

I have an mpi program and managed to compile and link it via Xcode 4. Now I want to debug it using Xcode 4.

How can I pipe the standard input to the program from a file?

In terminal I would type

mpirun -np 2 program < input.txt

I am able to run the program defining a custom executable (mpirun) in the "Info" panel of the Scheme editor, I also know that I can pass arguments in the "Arguments" panel. But Xcode 4 does not seem to accept "< input.txt" as an argument, even if I check "Use custom working directory" + add the correct directory of the input script in the "Options" panel.

This article Says it is possible to use "< input.txt" as an argument, but I guess that worked in Xcode 2 or Xcode 3, but it does not seem to work in Xcode 4 anymore.

sta
  • 456
  • 1
  • 3
  • 10
  • Can you configure Xcode to use `cat input.txt | mpirun -np 2 program` instead? It's kind of a cheap hack, so I'm not that proud to be suggesting it... – sarnold Oct 02 '11 at 23:22
  • Thank you for that hint! I didn't manage to run it yet, but this comment led me to try the sripts feature like setting variables in the script: input=$(cat input.txt) And passing $(input) as an argument. Maybe that works. I hope however there is a neat way to do that, otherwise it would be a little disappointing. Maybe someone is out there and knows better! Thank you though for that quick idea! – sta Oct 02 '11 at 23:46
  • Ha! Of course, a script will probably do the job well. :) – sarnold Oct 02 '11 at 23:47
  • Unfortunately it does not seem to be possible to use variables that I set in the script as arguments. If I use "< input.txt" as an argument it passes the strings "<" and "input.txt" instead of interpreting. – sta Oct 03 '11 at 16:29
  • Did you start your script with `#!/bin/sh` or `#!/bin/bash` in addition to setting the execute permission on the script? Perhaps if the script doesn't start with the hashbang line, the kernel will try to execute the program all the same... – sarnold Oct 03 '11 at 22:59
  • In the "Pre-actions > Run Script" section I set the shell to /bin/bash and set the variables in the text field below. It does get executed (tried that by writing to file in the script), but the variables I set cannot be accessed in the "Run program > Arguments" section. Do you mean I should start the script with #!/bin/bash? – sta Oct 05 '11 at 14:26

4 Answers4

33

In Xcode 4.5.1:

  1. Open the scheme editor (Product menu -> Edit Scheme...)
  2. Select the Run Debug scheme
  3. In the 'Info' tab panel, change the 'Launch' radio button selection from 'Automatically' to 'Wait for MyApp.app to launch'
  4. Close the scheme editor
  5. Press the Run button to build and run your target. (Xcode's status window in the toolbar will show 'Waiting for MyApp to launch')
  6. Launch Terminal and cd to your built application's folder. (It will be something like /Users/user/Library/Developer/Xcode/DerivedData/MyApp-dmzfrqdevydjuqbexdivolfeujsj/Build/Products/Debug / )
  7. Launch your app piping in whatever you want into standard input:

    echo mydata | ./MyApp.app/Contents/MacOs/MyApp
    
  8. Switch back to Xcode and the debugger will have detected your application's launch and attached to it.

user2067021
  • 4,399
  • 37
  • 44
  • 1
    That sounds like the solution I was looking for a year ago. Thanks for answering. – sta Nov 19 '12 at 11:55
  • I tried doing it like this, even though I don't have that particular situation anymore. It turns out XCode attaches to only one of the processes that I spawn with the terminal-call `mpirun -np 2 program < input.txt`. But thanks anyways, All in all I don't think anymore that XCode 4 is capable of debugging mpi programs. Since you successfully answered the "piping" part of the question, I award you the answer, event though it's not the answer I was hoping for. – sta Nov 19 '12 at 12:15
  • My problem with this is that you have to open a Terminal session every time you run. You may as well just copy and paste the contents of `mydata` to the console area every time (which is what I was trying to avoid when I went looking for this post). – Michael Dorst Oct 01 '14 at 16:20
  • 1
    In my Xcode 6.1 C++ command line tool project, if I didn't add the following line I got the dialog, "Lost connection to "My Mac". Restore the connections to "My Mac" and run "MyApp" again, or if "MyApp" is still running, you can attach to it by selecting Debug > Attach to Process > MyApp". `std::this_thread::sleep_for (std::chrono::seconds(5))` – Mark Gerrior Nov 19 '14 at 14:50
  • Thanks user2067021, this worked for me, too, in Xcode Version 9.1 (9B55). How can I debug my code using Xcode when using your method? – user1323995 Nov 23 '17 at 07:15
  • hm, xcode 10.1 in 2019 here, getting `Message from debugger: unable to attach` as soon as the command-line is issued. The app is a "command-line tool" versus a regular app, tho. – orion elenzil Feb 08 '19 at 00:19
3

Not wanting to awaken zombies, but this is still the top search result for the question.

I've managed to get this working in XCode 9.2 - but it should be backwards compatible. It uses a subshell and sleep in a pre-action script. This will pipe from a file and stick cout to a file, and supports breakpoints.

(1) Add the following preaction.sh script into your project.

#!/bin/sh
exec > ${PROJECT_DIR}/tests/result.log 2>&1
(
sleep 1
${TARGET_BUILD_DIR}/${EXECUTABLE_NAME} < ${PROJECT_DIR}/tests/file
)&

(2) Then add it to your pre-actions on the Run menu. Pre-action setting

(3) Ensure your run Waits for executable to be launched. Run setting

(4) Turn off code signing for your target!

No Codesigning Otherwise you will get an error "Message from debugger: unable to attach"

(5) Set breakpoints and run from Xcode as normal

That's all there is to it. The entire trick rests on getting the pre-action script to spawn off a sub-shell that itself delays the process until the run action is launched.

Konchog
  • 1,920
  • 19
  • 23
1

Another approach:

In the very beginning of your program, freopen input file for stdin.

    freopen( "input.txt", "r", stdin );

Conditional macro may help you.

#ifdef DEBUG
    freopen( "input.txt", "r", stdin );
    freopen( "output.txt", "w", stdout );
#endif
Satachito
  • 5,838
  • 36
  • 43
  • 1
    Nice workaround, though modifying the source is not optimal, however,given that Xcode is so clever that its unable to do the basics (Konchog's answer), this worked for me using Xcode 12.4. – gone Aug 07 '21 at 11:42
-1

Try the following pre-action run script:

mv program program.real
echo -e '#!/bin/sh\nmpirun -np 2 program.real < input.txt' > program

Maybe this will trick XCode into executing your program as you would like it to be executed.

sarnold
  • 102,305
  • 22
  • 181
  • 238