What is the exact meaning / purpose of the J and R flags in jshell? - runtime

From the help information:
-J<flag> Pass <flag> directly to the runtime system.
Use one -J for each runtime flag or flag argument
-R<flag> Pass <flag> to the remote runtime system.
Use one -R for each remote flag or flag argument
I cannot find an explanation in both the tools documentation and jshell user guide.
Also, what is "the remote runtime system" in the context of jshell?

As I understand it, JShell has 3 main 'places' to execute code:
In the current process (see DirectExecutionControl)
In the same JVM as the JShell client (see LocalExecutionControl)
On the remote agent (see JdiDefaultExecutionControl)
Using jshell tool, we have no current process before launch, so we have only two options - use one JVM (locally), or use two JVMs - one for JShell client (locally) and another for the execution engine (possibly remotely).
The interesting thing is, JShell always launch two JVMs by default, as the hard-coded --execution key is "failover:0(jdi:hostname(" + loopback + ")),1(jdi:launch(true)), 2(jdi)" (see JShell class source code).
Closer to the point. I've made a couple of experiments with -verbose option and checked JVM options in runtime with ManagementFactory.getRuntimeMXBean().getInputArguments().
jshell -J-verbose command
Printed -verbose output in the console.
No -verbose option in the input arguments: [-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:63305]
jshell -R-verbose command
No -verbose output in the console.
Printed -verbose option in the input arguments: [-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:63339, -verbose]
jshell --execution="local" -J-verbose command
Printed -verbose output in the console.
Printed -verbose option in the input arguments: [-Dapplication.home=C:\Program Files\Java\jdk-9, -Xms8m, -verbose, -Djdk.module.main=jdk.jshell]
jshell --execution="local" -R-verbose
No -verbose output in the console.
No -verbose option in the input arguments: [-Dapplication.home=C:\Program Files\Java\jdk-9, -Xms8m, -Djdk.module.main=jdk.jshell]
TL;DR
Remote execution (default case, execution over JDI)
-J<flag> passes option to the JShell client JVM
-R<flag> passes option to the execution engine JVM
Local execution (--execution="local")
-J<flag> passes option to the only present JVM
-R<flag> does nothing

I still find the scope of explaining the usage of the flags used in both the attributes for the question to be answered completely, hence putting that in words here.
➜ -J flag is used to provide a runtime argument to the JShell which is similar to the way one provides while performing via an IDE under Run -> Configuration to specify arguments as -Dkey=value.
The usage of the attribute is documented and quite similar to ones illustrated for the flag -C just that the -J flags are instead the java command line options.
For example, using the -XX:+PrintCommandLineFlags would detail out the runtime flags used by the current JVM.
So, the default values of command line flags used by your JShell instance(without setting any additional flag) could be as:-
But let's say you don't want to make use of the CompactStrings of Java9 in your JShell execution you can tell the JVM using the -J flag and -XX:-CompactStrings attribute to do so, as -
jshell -R-XX:+PrintCommandLineFlags -R-XX:-CompactStrings
would list out the following output:
➜ Similar java command line options/flags, when attached with and used to start JShell on a remote JVM, are linked to -R attribute of the JShell during remote execution.
jshell -R-XX:+PrintCommandLineFlags -R-XX:-CompactStrings
Anatoly's answer has got some good amount of research attached to it and I would suggest that to be read to understand about control and execution engine of the JShell for local Vs remote execution.

Related

Using DTrace to get stack traces / profiling data on Rust

I'm trying to get a nice flamegraph of my Rust code. Unfortunately, Xcode 8.3 doesn't support exporting profiling data anymore, so I've been trying to use DTrace to get the profiling data.
I have enabled debug info in my Cargo.toml for the release binaries:
[profile.release]
debug = true
Then I run the release binary (mybinaryname), and sample stack traces using DTrace:
sudo dtrace -n 'profile-997 /execname == "mybinaryname"/ { #[ustack(100)] = count(); }' -o out.user_stacks
The end result is something like this:
0x10e960500
0x10e964632
0x10e9659e0
0x10e937edd
0x10e92aae2
0x10e92d0d7
0x10e982c8b
0x10e981fc1
0x7fff93c70235
0x1
1
For comparison, getting traces of iTerm2 gets me nice traces like this:
CoreFoundation`-[__NSArrayM removeAllObjects]
AppKit`_NSGestureRecognizerUpdate+0x769
CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__+0x17
CoreFoundation`__CFRunLoopDoObservers+0x187
CoreFoundation`__CFRunLoopRun+0x4be
CoreFoundation`CFRunLoopRunSpecific+0x1a4
HIToolbox`RunCurrentEventLoopInMode+0xf0
HIToolbox`ReceiveNextEventCommon+0x1b0
HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter+0x47
AppKit`_DPSNextEvent+0x460
AppKit`-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:]+0xaec
AppKit`-[NSApplication run]+0x39e
AppKit`NSApplicationMain+0x4d5
iTerm2`main+0x6e
libdyld.dylib`start+0x1
iTerm2`0x1
1
Is it possible to get stack traces with debug info in Rust code? (Xcode's Instruments for sure can see the function names, so they are there!) If it is possible, do I need to do take some additional steps, or am I just doing something wrong?
I found a workaround and got some insight why it might not have worked, but the reason why is not 100% clear.
The debug symbols that rustc produces can be found in target/release/deps/mybinaryname-hashcode.dSYM. In the same directory there is a binary file target/release/deps/mybinaryname-hashcode to which the symbols correspond to.
The debug symbol finding library on MacOS is highly magical – as is mentioned in the LLDB docs, symbols are found using various methods, including Spotlight search. I'm not even sure which Frameworks are the ones being used by Xcode's Instruments and the bundled DTrace. (There are mentions about frameworks called DebugSymbols.framework and CoreSymbolication.framework.) Because of this magic, I gave up trying to understand why didn't it work.
The workaround is to pass dtrace the -p option along with the PID of the inspected process:
sudo dtrace -p $PID -n 'profile-997 /pid == '$PID'/ { #[ustack(100)] = count(); }' -o $TMPFILE &>/dev/null
Here's the man of -p:
Grab the specified process-ID pid, cache its symbol tables, and exit upon its completion. If more than one -p option is present on the command line, dtrace exits when all commands have exited, reporting the exit status for each process as it terminates. The first process-ID is made available to any D programs specified on the command line or using the -s option through the $target macro variable.
It's not clear why the debug info of various other binaries is shown by default, or why Rust binaries need the -p option, but it does its job as a workaround.

How to give interactive inputs in a single line for .exe windows

I am trying to automate one process which involves giving interactive input to a .exe utility. It expects the user-input for each step. I wanted to give all those values at single time while giving that command only. For eg: ./test.exe 8\n1\n0 etc. I have tried multiple ways to give input to the 'test.exe' utility like 8\n1\n0 | ./test.exe and 8,1,2 | ./test.exe. None of these worked. Any help how to pass these options 8,1,2 to the interactive utility test.exe in single line so that it will be helpful for my automation
There is no set way to automate a 3rd party program with Powershell. Not all utilities even offer the ability to do so.
I'd look in the utility documentation for any switches.
Try the following to see if you can get any built in help: test.exe -h, test.exe /h, test.exe /?, test.exe -?
use the sysinternals strings utility to try and find anything that look like command line switches inside the exe that you can take advantage of.
https://technet.microsoft.com/en-us/sysinternals/strings.aspx?f=255&MSPPError=-2147217396
The answer depends entirely on how your executable works.
If the executable reads from standard input, you can redirect input to it as follows (PowerShell):
PS C:\> 8,1,2 | .\test.exe
This won't work if the executable doesn't read from standard input or if it clears the console input buffer.
The executable may also let you provide command-line arguments that specify the needed input, but this depends on the executable.

Command line interaction using Ruby

I have a Rails application and am trying to communicate with a Java program via the CLI.
When I run the Java code using system:
system "java askQuestion"
it prompts for user input and waits for an answer, such as "What is your age?"
I want to pass a value in from a variable, and capture the output.
How can I interact with the CLI and run the command?
I did research but I couldn't find anything or I missed the correct term to search.
Solution: IO.popen
update -->
I found here what exactly I want and share maybe help someone else too , http://ruby.bastardsbook.com/chapters/external-programs/
Kernel#system just executes the command in a subshell, returning the result (true/false) of process start.
To catch the output, use backticks (or %x||).
To interact with a shell, one might use IO#popen, but in your case I would just stick to executing
output = `echo 37 | java askQuestion`
The above will pass the output of echo (37 in this particular case) to the Java process. The response of the Java process will be stored in the output variable.

Xeon Phi cannot execute binary file

I am trying to execute a binary file on a xeon phi coprocessor, and it is coming back with "bash: cannot execute binary file". So I am trying to find how to either view an error log or have it display what's happening when I tell it to execute that is causing it not work. I have already tried bash --verbose but it didn't display any additional information. Any ideas?
You don't specify where you compiled your executable nor where you tried to execute from.
To compile a program on the host system to be executed directly on the coprocessor, you must either:
if using one of the Intel compilers, add -mmic to the compiler
command line
if using gcc, use the cross-compilers provided with the MPSS
(/usr/linux-k1om-4.7) - note, however, that the gcc compiler does not
take advantage of vectorization on the coprocessor
If you want to compile directly on the coprocessor, you can install the necessary files from the additional rpm files provided for the coprocessor (found in mpss-/k1om) using the directions from the MPSS user's guide for installing additional rpm files.
To run a program on the coprocessor, if you have compiled it on the host, you must either:
copy your executable file and required libraries to the coprocessor
using scp before you ssh to the coprocessor yourself to execute the
code.
use the micnativeloadex command on the host - you can find a man page
for that on the host.
If you are writing a program using the offload model (part of the work is done using the host then some of the work is passed off to the coprocessor), you can compile on the host using the Intel compilers with no special options.
Note, however, that, regardless of what method you use, any libraries to be used with an executable for the coprocessor will need themselves to be built for the coprocessor. The default libraries exist but any libraries you add, you need to build a version for the coprocessor in addition to any version you make for the host system.
I highly recommend the articles you will find under https://software.intel.com/en-us/articles/programming-and-compiling-for-intel-many-integrated-core-architecture. These articles are written by people who develop and/or support the various programming tools for the coprocessor and should answer most of your questions.
Update: What's below does NOT answer the OP's question - it is one possible explanation for the cannot execute binary file error, but the fact that the error message is prefixed with bash: indicates that the binary is being invoked correctly (by bash), but is not compatible with the executing platform (compiled for a different architecture) - as #Barmar has already stated in a comment.
Thus, while the following contains some (hopefully still somewhat useful) general information, it does not address the OP's problem.
One possible reason for cannot execute binary file is to mistakenly pass a binary (executable) file -- rather than a shell script (text file containing shell code) -- as an operand (filename argument) to bash.
The following demonstrates the problem:
bash printf # fails with '/usr/bin/printf: /usr/bin/printf: cannot execute binary file'
Note how the mistakenly passed binary's path prefixes the error message twice; If the first prefix says bash: instead, the cause is most likely not a problem of incorrect invocation, but one of trying to a invoke an incompatible binary (compiled for a different architecture).
If you want bash to invoke a binary, you must use the -c option to pass it, which allows you to specify an entire command line; i.e., the binary plus arguments; e.g.:
bash -c '/usr/bin/printf "%s\n" "hello"' # -> 'hello'
If you pass a mere binary filename instead of a full path - e.g., -c 'program ...' - then a binary by that name must exist in one of the directories listed in the $PATH variable that bash sees, otherwise you'll get a command not found error.
If, by contrast, the binary is located in the current directory, you must prefix the filename with ./ for bash to find it; e.g. -c './program ...'

Displaying and parsing real-time command-line output in Ruby

I am writing a command-line Ruby gem for CraftBukkit (of Minecraft fame).
So, CraftBukkit's .jar file functions as any command-line server interface should: it accepts user input and sends it to the server when the admin presses enter, while displaying a live feed of server events.
Executed in the command-line directly, then,
java -Xmx1024M -Xms1024M -jar craftbukkit.jar
functions perfectly. I need to execute that same command within my Ruby gem and accept user input in the same way. I am currently using %x{} like so:
%x{java -Xmx1024M -Xms1024M -jar craftbukkit.jar}
This functions reasonably well, as it displays output as it should and executes commands typed into the command line window. It does not, however, show user input as it is typed.
I need to fix this. What Ruby commands/frameworks can I use to make the java command function perfectly?
If possible, I would also like to be able to parse the output.
I am using Clamp to parse command line arguments, if that matters.
Does
system "java -Xmx1024M -Xms1024M -jar craftbukkit.jar"
do what you wanted? It should at least display the input and output. Or did you want to parse the output from within Ruby?

Resources