[Bug 287829] lldb prints the wrong value of errno in multi-threaded processes
Date: Thu, 26 Jun 2025 11:12:46 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=287829
Bug ID: 287829
Summary: lldb prints the wrong value of errno in multi-threaded
processes
Product: Base System
Version: 14.2-RELEASE
Hardware: Any
OS: Any
Status: New
Severity: Affects Some People
Priority: ---
Component: bin
Assignee: bugs@FreeBSD.org
Reporter: becker.greg@att.net
Attachment #261631 text/plain
mime type:
Created attachment 261631
--> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=261631&action=edit
Simple C program to reproduce the problem
lldb does not print the value of errno correctly in multi-threaded processes,
and behavior differs between branches (releng/14.2, stable/14, main).
The primary problem is that 'p errno' seems to print thread 1's errno and not
the errno for the thread that lldb is currently looking at (say via the t
command or otherwise stopped in a particular thread).
With 14.2-RELEASE one can run 'p *(int *)__error()' to get the correct value,
but this no longer works reliably with stable/14, and does not work at all with
main/15.
Additionally, one cannot print the value of a thread-local variable as lldb
says "no TLS data currently exists for this thread". This problem looks
somewhat similar to https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=241773.
Here is a walk through of the problem with the attached reproducer:
branch releng/14.2 (4.2-RELEASE-p3)
$ lldb a.out
(lldb) target create "a.out"
Current executable set to '/home/greg/a.out' (x86_64).
(lldb) r
Process 405 launched: '/home/greg/a.out' (x86_64)
main: gvar 8, tlvar 6, errno 3
ptstart: 1: gvar 8, tlvar 5, errno 0
ptstart: 2: gvar 8, tlvar 5, errno 14
Process 405 stopped
* thread #2, name = 'a.out', stop reason = signal SIGABRT
frame #0: 0x00000008219bf1ba libc.so.7`__sys_thr_kill + 10
libc.so.7`__sys_thr_kill:
-> 0x8219bf1ba <+10>: jb 0x8219bd318
0x8219bf1c0 <+16>: retq
0x8219bf1c1: int3
0x8219bf1c2: int3
(lldb) bt
* thread #2, name = 'a.out', stop reason = signal SIGABRT
* frame #0: 0x00000008219bf1ba libc.so.7`__sys_thr_kill + 10
frame #1: 0x00000008219385d4 libc.so.7`__raise + 52
frame #2: 0x00000008219ebb59 libc.so.7`abort + 73
frame #3: 0x00000000002018b4 a.out`ptstart(arg=0x0000000000000000) at
x.c:16:5
frame #4: 0x0000000823156b05 libthr.so.3`___lldb_unnamed_symbol565 + 309
(lldb) f 3
frame #3: 0x00000000002018b4 a.out`ptstart(arg=0x0000000000000000) at x.c:16:5
13 printf("%s: gvar %d, tlvar %d, errno %d\n", __func__, gvar, tlvar,
errno);
14
15 errno = 3;
-> 16 abort();
17
18 pthread_exit(NULL);
19 }
(lldb) p tlvar
error: Couldn't materialize: couldn't get the value of variable tlvar: No TLS
data currently exists for this thread.
error: errored out in DoExecute, couldn't PrepareToExecuteJITExpression
(lldb) p errno
(void *) 0x0000000000000002 <-- wrong, thread 1's errno
(lldb) p *(int *)__error()
(int) 14 <-- correct
---
branch stable/14 bf73594fe0bd3d56b1035478cbbbdf58c05fe80e
branch stable/14 fad4064226b2aa3de6a6c83adb7e0e0108e69bd3
$ lldb a.out
(lldb) target create "a.out"
Current executable set to '/home/greg/a.out' (x86_64).
(lldb) r
Process 7525 launched: '/home/greg/a.out' (x86_64)
main: gvar 8, tlvar 6, errno 3
ptstart: 1: gvar 8, tlvar 5, errno 0
ptstart: 2: gvar 8, tlvar 5, errno 14
Process 7525 stopped
* thread #2, name = 'a.out', stop reason = signal SIGABRT
frame #0: 0x0000000821dc54ca libc.so.7`__sys_thr_kill at thr_kill.S:4
1 /* @generated by libc/sys/Makefile.inc */
2 #include "compat.h"
3 #include "SYS.h"
-> 4 RSYSCALL(thr_kill)
5 .section .note.GNU-stack,"",%progbits
(lldb) bt
* thread #2, name = 'a.out', stop reason = signal SIGABRT
* frame #0: 0x0000000821dc54ca libc.so.7`__sys_thr_kill at thr_kill.S:4
frame #1: 0x0000000821d3c444 libc.so.7`__raise(s=6) at raise.c:50:10
frame #2: 0x0000000821df1f79 libc.so.7`abort at abort.c:64:8
frame #3: 0x00000000002018d4 a.out`ptstart(arg=0x0000000000000000) at
x.c:16:5
frame #4: 0x0000000822a72c72
libthr.so.3`thread_start(curthread=0x0000322e9cc21810) at thr_create.c:289:16
(lldb) f 3
frame #3: 0x00000000002018d4 a.out`ptstart(arg=0x0000000000000000) at x.c:16:5
13 printf("%s: gvar %d, tlvar %d, errno %d\n", __func__, gvar, tlvar,
errno);
14
15 errno = 3;
-> 16 abort();
17
18 pthread_exit(NULL);
19 }
(lldb) p tlvar
error: Couldn't materialize: couldn't get the value of variable tlvar: no TLS
data currently exists for this thread
error: errored out in DoExecute, couldn't PrepareToExecuteJITExpression
(lldb) p errno <-- wrong, thread 1's errno
(int) 2
(lldb) p *(int *)__error()
(int) 0 <-- wrong, just plain wrong
Interestinly, if I rerun the test and do not run the bt and f commands
and just try to print errno right away I get the following:
(lldb) p errno <-- wrong, thread 1's errno
(int) 2
(lldb) p *(int *)__error() <-- correct
(int) 14
---
branch main d86c5811cdb384b3ba565187f8dc7e7e51b6466e
cc -Wall -O0 -g3 x.c -lpthread
$ lldb a.out
(lldb) target create "a.out"
Current executable set to '/home/greg/a.out' (x86_64).
(lldb) r
Process 17454 launched: '/home/greg/a.out' (x86_64)
main: gvar 8, tlvar 6, errno 0
ptstart: 1: gvar 8, tlvar 5, errno 0
ptstart: 2: gvar 8, tlvar 5, errno 14
Process 17454 stopped
* thread #2, name = 'a.out', stop reason = signal SIGABRT
frame #0: 0x000000082326595a libsys.so.7`__sys_thr_kill at thr_kill.S:4
1 /* @generated by libc/sys/Makefile.inc */
2 #include "compat.h"
3 #include "SYS.h"
-> 4 RSYSCALL(thr_kill)
5 .section .note.GNU-stack,"",%progbits
(lldb) bt
* thread #2, name = 'a.out', stop reason = signal SIGABRT
* frame #0: 0x000000082326595a libsys.so.7`__sys_thr_kill at thr_kill.S:4
frame #1: 0x0000000822e1b734 libc.so.7`__raise(s=6) at raise.c:48:10
frame #2: 0x0000000822ed0589 libc.so.7`abort at abort.c:61:8
frame #3: 0x0000000000201824 a.out`ptstart(arg=0x0000000000000000) at
x.c:16:5
frame #4: 0x0000000822d19f4b
libthr.so.3`thread_start(curthread=0x00003da43d043810) at thr_create.c:299:16
(lldb) f 3
frame #3: 0x0000000000201824 a.out`ptstart(arg=0x0000000000000000) at x.c:16:5
13 printf("%s: gvar %d, tlvar %d, errno %d\n", __func__, gvar, tlvar,
errno);
14
15 errno = 3;
-> 16 abort();
17
18 pthread_exit(NULL);
19 }
(lldb) p tlvar
error: Couldn't materialize: couldn't get the value of variable tlvar: no TLS
data currently exists for this thread
error: errored out in DoExecute, couldn't PrepareToExecuteJITExpression
(lldb) p errno
(void *) 0x0016e39000000002 <-- wrong, but lower bits look like thread 1's
errno
(lldb) p *(int *)__error() <-- wrong, thread 1's errno
(int) 2
--
You are receiving this mail because:
You are the assignee for the bug.