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.
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. Every example below uses ordinary user privileges; none needs sudo.
1. 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 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
- 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
- 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
- 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 --listand 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 --flagpasses--flagtoyour-command.
Done means
setarch --versionidentified 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.