On 32-bit x86 kernels the syscall entry wrappers are named
__ia32_sys_open, __ia32_sys_fork and __ia32_sys_read; the legacy
sys_open, sys_fork and sys_read symbols do not exist there. Even so,
x86_omit_frame_pointer() still looked up the legacy names, and
symbol_value() aborted the session during initialization with:
crash: cannot resolve "sys_open"
Add the __ia32_sys_* variants and skip names that are not present in the
kernel symbol table, matching x86_64_framepointer_init(). Keep the
legacy names first so that older kernels, which only provide the sys_*
wrappers, remain supported; the missing names are skipped on both old and
new kernels. Also iterate over all six entries: the loop previously
stopped after two, so the third legacy name was never checked.
Tested with the 32-bit i686 7.3.0-rc2 kdump and matching vmlinux: the
session initializes, "bt" resolves __ia32_sys_write, and no
"cannot resolve" error is reported.
Fixes:
https://github.com/crash-utility/crash/issues/116
Signed-off-by: Dave Young <yangrr.2009(a)tsinghua.org.cn>
---
x86.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/x86.c b/x86.c
index b36f44c54819..fe175aa5bcb0 100644
--- a/x86.c
+++ b/x86.c
@@ -4482,12 +4482,16 @@ x86_omit_frame_pointer(void)
{
ulonglong push_bp_mov_esp_bp;
int i;
- char *checkfuncs[] = {"sys_open", "sys_fork",
"sys_read"};
+ char *checkfuncs[] = {"sys_open", "sys_fork",
"sys_read",
+ "__ia32_sys_open", "__ia32_sys_fork",
+ "__ia32_sys_read"};
if (pc->flags & KERNEL_DEBUG_QUERY)
return FALSE;
- for (i = 0; i < 2; i++) {
+ for (i = 0; i < 6; i++) {
+ if(!kernel_symbol_exists(checkfuncs[i]))
+ continue;
if (!readmem(symbol_value(checkfuncs[i]), KVADDR,
&push_bp_mov_esp_bp, sizeof(ulonglong),
"x86_omit_frame_pointer", RETURN_ON_ERROR))