Skip to content

Commit

Permalink
x86_64: Correct the identifier when locating the call instruction
Browse files Browse the repository at this point in the history
The previous implementation to locate the call instruction is
to strstr "call", then check whether the previous char is ' '
or '\t'. The implementation is problematic. For example it
cannot resolve the following disassembly string:

"0xffffffffc0995378 <nfs41_callback_svc+344>:\tcall   0xffffffff8ecfa4c0 <schedule>\n"

strstr will locate the "_call" and char check fails,
as a result, extract_hex fails to get the calling address.

NOTE: the issue is more likely to be reproduced when patch[1] applied.
Because without patch[1], the disassembly string will be as follows,
so the issue is no longer reproducible.

"0xffffffffc0995378:\tcall   0xffffffff8ecfa4c0 <schedule>\n"

Before the patch:
    crash> bt 1472
    PID: 1472     TASK: ffff8c121fa72f70  CPU: 18   COMMAND: "nfsv4.1-svc"
     #0 [ffff8c16231a3db8] __schedule at ffffffff8ecf9ef3
     #1 [ffff8c16231a3e40] schedule at ffffffff8ecfa4e9

After the patch:
    crash> bt 1472
    PID: 1472     TASK: ffff8c121fa72f70  CPU: 18   COMMAND: "nfsv4.1-svc"
     #0 [ffff8c16231a3db8] __schedule at ffffffff8ecf9ef3
     #1 [ffff8c16231a3e40] schedule at ffffffff8ecfa4e9
     #2 [ffff8c16231a3e50] nfs41_callback_svc at ffffffffc099537d [nfsv4]
     #3 [ffff8c16231a3ec8] kthread at ffffffff8e6b966f
     #4 [ffff8c16231a3f50] ret_from_fork at ffffffff8ed07898

This patch fix the issue by strstr "\tcall" and " call", to
locate the correct call instruction.

[1]: https://listman.redhat.com/archives/crash-utility/2022-August/010085.html

Signed-off-by: Tao Liu <[email protected]>
  • Loading branch information
liutgnu authored and k-hagio committed Sep 1, 2022
1 parent 2145b2b commit 3ed9ec5
Showing 1 changed file with 1 addition and 2 deletions.
3 changes: 1 addition & 2 deletions x86_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -4432,8 +4432,7 @@ x86_64_function_called_by(ulong rip)
if (gdb_pass_through(buf, pc->tmpfile2, GNU_RETURN_ON_ERROR)) {
rewind(pc->tmpfile2);
while (fgets(buf, BUFSIZE, pc->tmpfile2)) {
if ((p1 = strstr(buf, "call")) &&
whitespace(*(p1-1))) {
if ((p1 = strstr(buf, " call")) || (p1 = strstr(buf, "\tcall"))) {
if (extract_hex(p1, &value, NULLCHAR, TRUE))
break;
}
Expand Down

0 comments on commit 3ed9ec5

Please sign in to comment.