Test Architecture-Sensitive Programs with setarch
Use setarch to run one program with a different reported machine type or a selected Linux process-personality flag. This is useful for testing installers, build scripts and older software that branches on uname -m. It does not install a 32-bit runtime, change the CPU, or turn a 64-bit process into a 32-bit process.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about five minutes for a basic check. You need a shell and the util-linux package. The examples use ordinary user privileges. No command below needs sudo.
Checkpoint: identify the local implementation
- Check the executable version and the architectures it knows by name.
setarch --version
setarch --list
On the machine used for this guide, the first command reports setarch from util-linux 2.42.4. The list includes i386, i686, linux32, linux64 and x86_64, among other names. The installed manpages are generated from util-linux 2.39.3, so the executable version is the useful reference when behaviour differs between hosts.
The local manual describes an interface that has existed since util-linux 2.33: the architecture argument is optional. That means you can set a personality flag without changing the reported machine type. It also says that whether a named architecture can actually be applied depends on the running kernel.
Checkpoint: compare the native and reported machine types
- Run the same harmless query with and without an architecture wrapper.
printf 'native: '; uname -m
printf 'i386: '; setarch i386 uname -m
printf 'linux32: '; linux32 uname -m
printf 'linux64: '; linux64 uname -m
printf 'x86_64: '; x86_64 uname -m
On an x86-64 host, the result is typically similar to this:
native: x86_64
i386: i686
linux32: i686
linux64: x86_64
x86_64: x86_64
The aliases are alternate entry points to the same setarch behaviour. i386 and linux32 request the 32-bit-style machine report; linux64 and x86_64 request the 64-bit-style report. The manual's precise guarantee is narrower than the names suggest: the execution domain currently affects the output of uname -m. Do not use this test as proof that a program can load 32-bit libraries or execute a foreign binary.
Run a real command without changing the shell
- Put the target command after the architecture and any options.
setarch i386 /path/to/program --print-machine
Replace /path/to/program and its arguments with a command you intend to test. The wrapper applies to that program and its descendants. When the program exits, its personality setting disappears with that process. It does not edit a configuration file and does not alter later commands in your current shell.
If you omit the program, the manual says that /bin/sh is the default:
setarch i386
uname -m
exit
That starts a subshell. The uname check runs inside it, and exit returns to the original shell. A common distraction trap is to type the check after the wrapper has already returned, then conclude that setarch did nothing.
Set one personality flag for a test
- Use the optional architecture argument form when the test needs a process flag but not a different machine name.
setarch -R sh -c 'setarch --show'
-R, also called --addr-no-randomize, disables virtual address-space randomisation for the wrapped program. The verification command reports:
PER_LINUX (ADDR_NO_RANDOMIZE)
This flag is security-sensitive because address randomisation is a defence against some memory-corruption attacks. Use it only for a controlled compatibility or debugging test, and keep the scope to the shortest-lived command possible. The setting is not persistent. Re-run the program without -R to undo the test condition:
/path/to/program
Other useful inspection forms are setarch --show, which prints the current personality and flags, and setarch --show=0x0, which displays the supplied hexadecimal personality value instead of the current one. Use the latter when comparing a known value in a test harness, not as a substitute for understanding the flag names.
Choose flags carefully
The manual includes compatibility flags for older or unusual programs. For example, --3gb requests a maximum 3 GB address space on supported x86 systems, while --32bit is documented for ARM and Alpha. --uname-2.6 makes the wrapped program see a kernel version beginning with 2.6. These options describe kernel personality behaviour, not a general emulation layer.
Do not add --4gb expecting a larger address space. The installed manual explicitly says that it has no effect and remains only for backward compatibility. Several other options emulate obsolete bugs or depend on architecture-specific kernel support. Start with the narrowest flag that reproduces the program's requirement, then verify with --show or the program's own diagnostic output.
Common failures and recovery
- Unknown architecture: run
setarch --listand use one of the names shown. A name being listed does not guarantee that the current kernel supports it. - No visible change: check the value inside the wrapped command, for example
setarch i386 uname -m. Checking a later command in the parent shell tests the wrong process. - Binary still will not run: setarch changes reported state and personality flags. It does not provide a loader, libraries or a foreign CPU instruction set.
- Unexpected option parsing: place setarch options before the program, and use the program's own option terminator where appropriate. A command such as
setarch i386 your-command --flagpasses--flagtoyour-command.
Done means
setarch --versionidentified the executable you are using.- You verified the requested machine report inside the wrapped process.
- You treated the result as a reported value, not as proof of a different ABI or installed libraries.
- Any compatibility flag was limited to the test command and removed by running the command normally again.