Home / Alt manpages / setarch(8)

  • setarch(8)
  • Admin command
  • linux

Test Architecture-Sensitive Programs with setarch

An old installer checks uname -m and refuses to run on your 64-bit box, and setarch is the tool that lets you lie to it convincingly. Use it to run one program with a different reported machine type or a selected Linux process-personality flag, useful for testing installers, build scripts and software that branches on architecture. It does not install a 32-bit runtime, change the CPU, or turn a 64-bit process into a real 32-bit one.

Allow about five minutes for a basic check. You need a shell and the util-linux package. Every example below uses ordinary user privileges; none needs sudo.

1. Identify the local implementation

  1. Check the executable version and the architectures it knows by name.
setarch --version
setarch --list

On the machine used for this guide, the version 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 treat the executable's own version as the 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, so you can set a personality flag without changing the reported machine type at all. It also notes that whether a named architecture actually applies depends on the running kernel.

2. Compare the native and reported machine types

  1. 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, expect something like this:

native: x86_64
i386: i686
linux32: i686
linux64: x86_64
x86_64: x86_64

The aliases are alternate entry points into the same setarch behaviour: i386 and linux32 request the 32-bit-style machine report, linux64 and x86_64 the 64-bit-style one. The actual guarantee is narrower than the names suggest: the execution domain currently affects the output of uname -m, full stop. Do not treat this test as proof a program can load 32-bit libraries or execute a foreign binary.

3. Run a real command without changing the shell

  1. 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 whatever you intend to test. The wrapper applies to that program and its descendants; when the program exits, its personality setting disappears with the process. It does not touch a configuration file and does not affect later commands in your current shell.

If you omit the program, the manual says /bin/sh is the default:

setarch i386
uname -m
exit

That starts a subshell. The uname check runs inside it, and exit returns you to the original shell. A common trap is typing the check after the wrapper has already returned, then concluding setarch did nothing.

4. Set one personality flag for a test

  1. 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)

Warning

This flag is security-sensitive, because address randomisation defends against some memory-corruption attacks. Use it only for a controlled compatibility or debugging test, keeping 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

Two other useful inspection forms: setarch --show prints the current personality and flags, and setarch --show=0x0 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 what the flag names actually mean.

5. Choose flags carefully

The manual includes compatibility flags for older or unusual programs. --3gb requests a maximum 3 GB address space on supported x86 systems, --32bit is documented for ARM and Alpha, and --uname-2.6 makes the wrapped program see a kernel version beginning with 2.6. These describe kernel personality behaviour, not a general emulation layer.

Do not add --4gb expecting a larger address space: the installed manual explicitly says 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 --list and use one of the names shown. Being listed does not guarantee 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 entirely.
  • 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. setarch i386 your-command --flag passes --flag to your-command.

Done means

  • setarch --version identified the executable you are using.
  • Verified the requested machine report inside the wrapped process, not the parent shell.
  • Treated the result as reported state, not proof of a different ABI or installed libraries.
  • Limited any compatibility flag to the test command and removed it by running the command normally again.