Skip to content

[LoongArch] Add debug location for register reload #122057

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

Conversation

wangleiat
Copy link
Contributor

Although the automatically inserted reload instruction in the Epilogue
is unrelated to the original code, in order to improve debugger
functionality, we have re-added debugging location information in the
reload instruction. When using an empty debugging location, the
following issue occurs:

loongson@linux:~$ cat -n test.c
 1  int printf(const char *, ...);
 2  int main(int argc, char **argv) {
 3    printf("%d\n", argc);
 4    return 0;
 5  }
 clang -g -O0 test.c -o test

Without this patch, the debugger is unable to correctly access the
current stack information when a breakpoint is set on line 4:

loongson@linux:~$ gdb -q ./test
Reading symbols from ./test...
(gdb) break 4
Breakpoint 1 at 0x7c0: file test.c, line 4.
(gdb) run
Starting program: /home/wanglei/test
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/loongarch64-linux-gnu/libthread_db.so.1".
1

Breakpoint 1, main (argc=<error reading variable: Cannot access memory at address 0xffffffffffffffe8>,
    argv=<error reading variable: Cannot access memory at address 0xffffffffffffffe0>) at test.c:4
4         return 0;

Created using spr 1.3.5-bogner
@llvmbot
Copy link
Member

llvmbot commented Jan 8, 2025

@llvm/pr-subscribers-backend-loongarch

Author: wanglei (wangleiat)

Changes

Although the automatically inserted reload instruction in the Epilogue
is unrelated to the original code, in order to improve debugger
functionality, we have re-added debugging location information in the
reload instruction. When using an empty debugging location, the
following issue occurs:

loongson@<!-- -->linux:~$ cat -n test.c
 1  int printf(const char *, ...);
 2  int main(int argc, char **argv) {
 3    printf("%d\n", argc);
 4    return 0;
 5  }
 clang -g -O0 test.c -o test

Without this patch, the debugger is unable to correctly access the
current stack information when a breakpoint is set on line 4:

loongson@<!-- -->linux:~$ gdb -q ./test
Reading symbols from ./test...
(gdb) break 4
Breakpoint 1 at 0x7c0: file test.c, line 4.
(gdb) run
Starting program: /home/wanglei/test
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/loongarch64-linux-gnu/libthread_db.so.1".
1

Breakpoint 1, main (argc=&lt;error reading variable: Cannot access memory at address 0xffffffffffffffe8&gt;,
    argv=&lt;error reading variable: Cannot access memory at address 0xffffffffffffffe0&gt;) at test.c:4
4         return 0;

Full diff: https://github.com/llvm/llvm-project/pull/122057.diff

1 Files Affected:

  • (modified) llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp (+4-1)
diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
index 54aeda28364003..32bc8bb8012957 100644
--- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.cpp
@@ -154,6 +154,9 @@ void LoongArchInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
                                               Register VReg) const {
   MachineFunction *MF = MBB.getParent();
   MachineFrameInfo &MFI = MF->getFrameInfo();
+  DebugLoc DL;
+  if (I != MBB.end())
+    DL = I->getDebugLoc();
 
   unsigned Opcode;
   if (LoongArch::GPRRegClass.hasSubClassEq(RC))
@@ -177,7 +180,7 @@ void LoongArchInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
       MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad,
       MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
 
-  BuildMI(MBB, I, DebugLoc(), get(Opcode), DstReg)
+  BuildMI(MBB, I, DL, get(Opcode), DstReg)
       .addFrameIndex(FI)
       .addImm(0)
       .addMemOperand(MMO);

@wangleiat wangleiat requested a review from SixWeining January 8, 2025 06:51
@wangleiat
Copy link
Contributor Author

@xen0n

@wangleiat wangleiat requested a review from heiher January 8, 2025 06:52
@heiher
Copy link
Member

heiher commented Jan 8, 2025

Here is another similar issue:

$ gdb ./t
GNU gdb (GDB) 15.1
...
(gdb) b *main
Breakpoint 1 at 0x760: file t.c, line 2.
(gdb) r
...
Breakpoint 1, main (argc=<error reading variable: Cannot access memory at address 0xffffffffffffffe8>, 
    argv=<error reading variable: Cannot access memory at address 0xffffffffffffffe0>) at t.c:2
2	int main(int argc, char **argv) {

@xen0n
Copy link
Contributor

xen0n commented Jan 8, 2025

looks fine but I haven't tested

@SixWeining SixWeining mentioned this pull request Jan 8, 2025
7 tasks
@wangleiat
Copy link
Contributor Author

Here is another similar issue:

$ gdb ./t
GNU gdb (GDB) 15.1
...
(gdb) b *main
Breakpoint 1 at 0x760: file t.c, line 2.
(gdb) r
...
Breakpoint 1, main (argc=<error reading variable: Cannot access memory at address 0xffffffffffffffe8>, 
    argv=<error reading variable: Cannot access memory at address 0xffffffffffffffe0>) at t.c:2
2	int main(int argc, char **argv) {

This is correct. argc and argv are calculated through fp, where argc = $r22 - 24 and argv = r22 - 32. When breaking at *main, $r22 = 0, and at this point, argc and argv are inaccessible.

@heiher
Copy link
Member

heiher commented Jan 8, 2025

Here is another similar issue:

$ gdb ./t
GNU gdb (GDB) 15.1
...
(gdb) b *main
Breakpoint 1 at 0x760: file t.c, line 2.
(gdb) r
...
Breakpoint 1, main (argc=<error reading variable: Cannot access memory at address 0xffffffffffffffe8>, 
    argv=<error reading variable: Cannot access memory at address 0xffffffffffffffe0>) at t.c:2
2	int main(int argc, char **argv) {

This is correct. argc and argv are calculated through fp, where argc = $r22 - 24 and argv = r22 - 32. When breaking at *main, $r22 = 0, and at this point, argc and argv are inaccessible.

I agree. Throwing an inaccessible result is better than GCC displaying the spurious zero value.

Breakpoint 1, main (argc=0, argv=0x0) at t.c:2

Copy link
Member

@heiher heiher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks.

@wangleiat wangleiat merged commit 5ae44bf into main Jan 9, 2025
8 of 10 checks passed
@wangleiat wangleiat deleted the users/wangleiat/spr/loongarch-add-debug-location-for-register-reload branch January 9, 2025 01:11
github-actions bot pushed a commit to arm/arm-toolchain that referenced this pull request Jan 10, 2025
Although the automatically inserted reload instruction in the `Epilogue`
is unrelated to the original code, in order to improve debugger
functionality, we have re-added debugging location information in the
reload instruction. When using an empty debugging location, the
following issue occurs:
```
loongson@linux:~$ cat -n test.c
 1  int printf(const char *, ...);
 2  int main(int argc, char **argv) {
 3    printf("%d\n", argc);
 4    return 0;
 5  }
 clang -g -O0 test.c -o test
```
Without this patch, the debugger is unable to correctly access the
current stack information when a breakpoint is set on line 4:

```
loongson@linux:~$ gdb -q ./test
Reading symbols from ./test...
(gdb) break 4
Breakpoint 1 at 0x7c0: file test.c, line 4.
(gdb) run
Starting program: /home/wanglei/test
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/loongarch64-linux-gnu/libthread_db.so.1".
1

Breakpoint 1, main (argc=<error reading variable: Cannot access memory at address 0xffffffffffffffe8>,
    argv=<error reading variable: Cannot access memory at address 0xffffffffffffffe0>) at test.c:4
4         return 0;
```

Reviewed By: heiher, xen0n

Pull Request: llvm/llvm-project#122057
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants