Project

General

Profile

Bug #4202

dtrace: invalid errno value in pid provider

Added by Marcel Telka about 7 years ago. Updated about 7 years ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
DTrace
Start date:
2013-10-12
Due date:
% Done:

0%

Estimated time:
Difficulty:
Medium
Tags:
needs-triage
Gerrit CR:

Description

The pid provider does not have access to the correct value of errno:

# cat a.c
#include <stdio.h>
#include <errno.h>

int
main(void)
{
        if (fopen("file", "r") == NULL)
                printf("errno: %d\\n", errno);

        return 0;
}
# gcc a.c
# dtrace -n '
    pid$target::fopen:return
        {trace(arg1);trace(errno);trace(execname)}
    syscall::open:return /errno!=0&&execname=="a.out"/
        {trace(errno); trace(execname)}' -c ./a.out
dtrace: description '
    pid$target::fopen:return
        ' matched 2 probes
errno: 2
dtrace: pid 1176 has exited
CPU     ID                    FUNCTION:NAME
  1   6874                      open:return         2  a.out
  1  73290                     fopen:return                 0        0  a.out

# ls file
ls: cannot access file: No such file or directory
#

Apparently, the errno value is 2, but the pid provider shows 0.


Related issues

Related to illumos gate - Bug #5085: errno clobbering in libdtraceNew2014-08-13

Actions
#1

Updated by Marcel Telka about 7 years ago

The problem is that dtrace implements errno by reading lwp->lwp_errno:

3211    case DIF_VAR_ERRNO: {
3212        klwp_t *lwp;
3213        if (!dtrace_priv_proc(state, mstate))
3214            return (0);
3215
3216        /*
3217         * See comment in DIF_VAR_PID.
3218         */
3219        if (DTRACE_ANCHORED(mstate->dtms_probe) && CPU_ON_INTR(CPU))
3220            return (0);
3221
3222        /*
3223         * It is always safe to dereference one's own t_lwp pointer in
3224         * the event that this pointer is non-NULL.  (This is true
3225         * because threads and lwps don't clean up their own state --
3226         * they leave that task to whomever reaps them.)
3227         */
3228        if ((lwp = curthread->t_lwp) == NULL)
3229            return (0);
3230
3231        return ((uint64_t)lwp->lwp_errno);

but lwp->lwp_errno is cleared right before we return to the userspace - see the post_syscall() implementation.

Also available in: Atom PDF