-
Notifications
You must be signed in to change notification settings - Fork 169
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stack unwinding is broken in Linux 6.4 on x86-64 due to ORC format change #303
Comments
Commits ffb1b4a ("x86/unwind/orc: Add 'signal' field to ORC metadata") and fb79944 ("x86,objtool: Split UNWIND_HINT_EMPTY in two") changed the ORC format. Although ORC is internal to the kernel, it's the only way for external tools to get reliable kernel stack traces on x86-64. In particular, the drgn debugger [1] uses ORC for stack unwinding, and these format changes broke it [2]. As the drgn maintainer, I don't care how often or how much the kernel changes the ORC format as long as I have a way to detect the change. Using the kernel version is not a solution because distros frequently backport changes. It suffices to store a version number for the ORC format in the vmlinux and kernel module ELF files (to use when parsing ORC sections from ELF), and in kernel memory (to use when parsing ORC from a core dump). This patch adds both of these by creating an .orc_header ELF section containing a 4-byte version number and the corresponding __start_orc_header and __stop_orc_header symbols. The current version number is 3. Version 1 is the original version merged in commit ee9f8fc ("x86/unwind: Add the ORC unwinder"). Version 2 is the version from commit ffb1b4a ("x86/unwind/orc: Add 'signal' field to ORC metadata"), which obviously didn't include this header but could get it in a backport to the 6.3 stable branch. 1: https://github.com/osandov/drgn 2: osandov/drgn#303 Signed-off-by: Omar Sandoval <osandov@fb.com>
Commits ffb1b4a ("x86/unwind/orc: Add 'signal' field to ORC metadata") and fb79944 ("x86,objtool: Split UNWIND_HINT_EMPTY in two") changed the ORC format. Although ORC is internal to the kernel, it's the only way for external tools to get reliable kernel stack traces on x86-64. In particular, the drgn debugger [1] uses ORC for stack unwinding, and these format changes broke it [2]. As the drgn maintainer, I don't care how often or how much the kernel changes the ORC format as long as I have a way to detect the change. It suffices to store a version identifier in the vmlinux and kernel module ELF files (to use when parsing ORC sections from ELF), and in kernel memory (to use when parsing ORC from a core dump+symbol table). Rather than hard-coding a version number that needs to be manually bumped, Peterz suggested hashing the definitions from orc_types.h. If there is a format change that isn't caught by this, the hashing script can be updated. This patch adds an .orc_header allocated ELF section containing the 20-byte hash to vmlinux and kernel modules, along with the corresponding __start_orc_header and __stop_orc_header symbols in vmlinux. 1: https://github.com/osandov/drgn 2: osandov/drgn#303 Signed-off-by: Omar Sandoval <osandov@fb.com>
According to the docs, ORC should not be used unless either (a) |
drgn falls back to using ORC if it can't find DWARF CFI for a given program counter. Most kernel stack traces end up with a frame without DWARF CFI because the kernel entry code is in assembly. For example, in this stack trace:
|
Ah interesting, I hadn't gotten the idea that there's sometimes not DWARF for the function at the bottom of the stack. Maybe I should try out dwarfdump to see what data is present for what functions, it looks capable of doing that. |
Commits ffb1b4a ("x86/unwind/orc: Add 'signal' field to ORC metadata") and fb79944 ("x86,objtool: Split UNWIND_HINT_EMPTY in two") changed the ORC format. Although ORC is internal to the kernel, it's the only way for external tools to get reliable kernel stack traces on x86-64. In particular, the drgn debugger [1] uses ORC for stack unwinding, and these format changes broke it [2]. As the drgn maintainer, I don't care how often or how much the kernel changes the ORC format as long as I have a way to detect the change. It suffices to store a version identifier in the vmlinux and kernel module ELF files (to use when parsing ORC sections from ELF), and in kernel memory (to use when parsing ORC from a core dump+symbol table). Rather than hard-coding a version number that needs to be manually bumped, Peterz suggested hashing the definitions from orc_types.h. If there is a format change that isn't caught by this, the hashing script can be updated. This patch adds an .orc_header allocated ELF section containing the 20-byte hash to vmlinux and kernel modules, along with the corresponding __start_orc_header and __stop_orc_header symbols in vmlinux. 1: https://github.com/osandov/drgn 2: osandov/drgn#303 Fixes: ffb1b4a ("x86/unwind/orc: Add 'signal' field to ORC metadata") Fixes: fb79944 ("x86,objtool: Split UNWIND_HINT_EMPTY in two") Signed-off-by: Omar Sandoval <osandov@fb.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Josh Poimboeuf <jpoimboe@kernel.org> Link: https://lkml.kernel.org/r/aef9c8dc43915b886a8c48509a12ec1b006ca1ca.1686690801.git.osandov@osandov.com
Closed by 91ede0c. Hopefully https://lore.kernel.org/linux-debuggers/aef9c8dc43915b886a8c48509a12ec1b006ca1ca.1686690801.git.osandov@osandov.com/ is merged so that the terrible kernel version check is limited. |
My patch was merged in torvalds/linux@b9f174c. |
[ Upstream commit b9f174c ] Commits ffb1b4a ("x86/unwind/orc: Add 'signal' field to ORC metadata") and fb79944 ("x86,objtool: Split UNWIND_HINT_EMPTY in two") changed the ORC format. Although ORC is internal to the kernel, it's the only way for external tools to get reliable kernel stack traces on x86-64. In particular, the drgn debugger [1] uses ORC for stack unwinding, and these format changes broke it [2]. As the drgn maintainer, I don't care how often or how much the kernel changes the ORC format as long as I have a way to detect the change. It suffices to store a version identifier in the vmlinux and kernel module ELF files (to use when parsing ORC sections from ELF), and in kernel memory (to use when parsing ORC from a core dump+symbol table). Rather than hard-coding a version number that needs to be manually bumped, Peterz suggested hashing the definitions from orc_types.h. If there is a format change that isn't caught by this, the hashing script can be updated. This patch adds an .orc_header allocated ELF section containing the 20-byte hash to vmlinux and kernel modules, along with the corresponding __start_orc_header and __stop_orc_header symbols in vmlinux. 1: https://github.com/osandov/drgn 2: osandov/drgn#303 Fixes: ffb1b4a ("x86/unwind/orc: Add 'signal' field to ORC metadata") Fixes: fb79944 ("x86,objtool: Split UNWIND_HINT_EMPTY in two") Signed-off-by: Omar Sandoval <osandov@fb.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Josh Poimboeuf <jpoimboe@kernel.org> Link: https://lkml.kernel.org/r/aef9c8dc43915b886a8c48509a12ec1b006ca1ca.1686690801.git.osandov@osandov.com Signed-off-by: Sasha Levin <sashal@kernel.org>
Commits ffb1b4a ("x86/unwind/orc: Add 'signal' field to ORC metadata") and fb79944 ("x86,objtool: Split UNWIND_HINT_EMPTY in two") changed the ORC format. Although ORC is internal to the kernel, it's the only way for external tools to get reliable kernel stack traces on x86-64. In particular, the drgn debugger [1] uses ORC for stack unwinding, and these format changes broke it [2]. As the drgn maintainer, I don't care how often or how much the kernel changes the ORC format as long as I have a way to detect the change. It suffices to store a version identifier in the vmlinux and kernel module ELF files (to use when parsing ORC sections from ELF), and in kernel memory (to use when parsing ORC from a core dump+symbol table). Rather than hard-coding a version number that needs to be manually bumped, Peterz suggested hashing the definitions from orc_types.h. If there is a format change that isn't caught by this, the hashing script can be updated. This patch adds an .orc_header allocated ELF section containing the 20-byte hash to vmlinux and kernel modules, along with the corresponding __start_orc_header and __stop_orc_header symbols in vmlinux. 1: https://github.com/osandov/drgn 2: osandov/drgn#303 Fixes: ffb1b4a ("x86/unwind/orc: Add 'signal' field to ORC metadata") Fixes: fb79944 ("x86,objtool: Split UNWIND_HINT_EMPTY in two") Signed-off-by: Omar Sandoval <osandov@fb.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Josh Poimboeuf <jpoimboe@kernel.org> Link: https://lkml.kernel.org/r/aef9c8dc43915b886a8c48509a12ec1b006ca1ca.1686690801.git.osandov@osandov.com
This is because torvalds/linux@fb79944 changed the ORC entry format: the type is now 3 bits, and types now range from 0-4. torvalds/linux@ffb1b4a also previously changed the ORC format in a way that we didn't detect.
We might be able to guess the "version" of the format, but let's see if we can make upstream include a version identifier first.
The text was updated successfully, but these errors were encountered: