webentwicklung-frage-antwort-db.com.de

setrlimit schlägt fehl, wenn Operation unter valgrind nicht zulässig ist

Ich kann etwas vermissen oder auch nicht, aber die setrlimit-Funktion fällt konstant aus, wenn sie unter valgrind ausgeführt wird

int main()
{
        const struct rlimit file_limits = { .rlim_cur = 65536, .rlim_max = 65536 };
        if ( setrlimit( RLIMIT_NOFILE, &file_limits ) )
        {
                printf(" Failed  %d", errno );
                perror(" More " );
        }
        else
        {
                printf(" Success ");
        }
        printf("\n");
        return 0;
}

Hier sind die Probeläufe

Normaler Lauf

sh-4.2# ulimit -H -n
800000
sh-4.2# ulimit -S -n
500000
sh-4.2# ./rlimit
 Success
sh-4.2#

unter valgrind

sh-4.2#
sh-4.2# valgrind ./rlimit
==28974== Memcheck, a memory error detector
==28974== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==28974== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==28974== Command: ./rlimit
==28974==
 More : Operation not permitted
 Failed  1
==28974==
==28974== HEAP SUMMARY:
==28974==     in use at exit: 0 bytes in 0 blocks
==28974==   total heap usage: 1 allocs, 1 frees, 568 bytes allocated
==28974==
==28974== All heap blocks were freed -- no leaks are possible
==28974==
==28974== For counts of detected and suppressed errors, rerun with: -v
==28974== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
sh-4.2#

Jeder Hinweis dazu wäre toll. HINWEIS: Dies ist in CentOS Release 7.4 (Final) enthalten.

Bearbeitungen # 1

Mit minimalem Arbeitscode:

int main()
{
        const struct rlimit file_limits = { .rlim_cur = 65536, .rlim_max = 65536 };
        setrlimit( RLIMIT_NOFILE, &file_limits ) ;
        perror(" wrong ?? " );
        printf("\n");
        return 0;
}

entsprechende Ausgänge:

[[email protected] kk]# valgrind ./rlimit
==29179== Memcheck, a memory error detector
==29179== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==29179== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==29179== Command: ./rlimit
==29179==
 wrong ?? : Operation not permitted

==29179==
==29179== HEAP SUMMARY:
==29179==     in use at exit: 0 bytes in 0 blocks
==29179==   total heap usage: 1 allocs, 1 frees, 568 bytes allocated
==29179==
==29179== All heap blocks were freed -- no leaks are possible
==29179==
==29179== For counts of detected and suppressed errors, rerun with: -v
==29179== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
[[email protected] kk]# ./rlimit
 wrong ?? : Success

diese falsch ??: Operation nicht erlaubt macht mich verrückt :(

Bearbeiten Sie # 2

Basierend auf einigen Vorschlägen habe ich versucht, vorhandene Grenzwerte abzurufen und zu sehen, ob etwas nicht stimmt, und stellt das Verhalten außerhalb meines Verständnisses heraus

int main()
{
        const struct rlimit file_limits = { .rlim_cur = 65536, .rlim_max = 65536 };
        struct rlimit limit;
        getrlimit(RLIMIT_NOFILE,&limit);
        printf("%d \n",limit.rlim_max);

        setrlimit( RLIMIT_NOFILE, &file_limits ) ;
        perror(" wrong ?? " );
        printf("\n");

        getrlimit(RLIMIT_NOFILE,&limit);
        printf("%d \n",limit.rlim_max);
        return 0;
}

Beim ersten Durchlauf ist der Grenzwert auf 65590 festgelegt, und die ausführbare Datei kann den Grenzwert auf 65536 ändern, dh es wird erwartet

[[email protected] kk]# ulimit -n
65590
[[email protected] kk]# ./rlimit
65590
 wrong ?? : Success

65536
[[email protected] kk]#

2. Lauf unter Valgrind

[[email protected] kk]# ulimit -n
65590
[[email protected] kk]# valgrind ./rlimit
==17595== Memcheck, a memory error detector
==17595== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==17595== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==17595== Command: ./rlimit
==17595==
65578
 wrong ?? : Operation not permitted

65578
==17595==
==17595== HEAP SUMMARY:
==17595==     in use at exit: 0 bytes in 0 blocks
==17595==   total heap usage: 1 allocs, 1 frees, 568 bytes allocated
==17595==
==17595== All heap blocks were freed -- no leaks are possible
==17595==
==17595== For counts of detected and suppressed errors, rerun with: -v
==17595== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
[[email protected] kk]#

Ich bin wahrscheinlich geneigt zu sagen, dass Valgrind ein paar Dateideskriptoren für seine Verwendung reserviert basierend auf Diskussionen hier lassen Sie uns in diesem Fall sagen, dass es 12 ?? Also das Limit auf 65578 setzen? Was ist noch mehr als das, was das Programm versucht, 65536 zu reservieren.

Weitere Vorschläge, um zu folgen?

14
u__

Von dem zulässigen Bereich von fd 0 .. hard_limit reserviert Valgrind einen Satz von fd für seine eigenen Zwecke am Ende des Bereichs D.h. der Bereich hard_limit - 11 .. hard_limit, und simuliert dann ein neues hartes Limit, das hard_limit - 12 ist.

Es verbietet dann der Gastanwendung, diesen (simulierten) harten Grenzwert zu ändern. Hier ist der Code, der die Setrlimit-Simulation behandelt:

 if (((struct vki_rlimit *)(Addr)ARG2)->rlim_cur > VG_(fd_hard_limit) ||
      ((struct vki_rlimit *)(Addr)ARG2)->rlim_max != VG_(fd_hard_limit)) {
     SET_STATUS_Failure( VKI_EPERM );
  }

Wenn Sie sehen, dass sich das bereitgestellte rlim_max von dem simulierten VG_ (fd_hard_limit) unterscheidet, führt valgrind dazu, dass das Setrlimit fehlschlägt. Wenn dies akzeptiert wird, ändert valgrind das simulierte weiche Limit.

Ich bin mir nicht sicher, zu verstehen, warum der obige Code nicht Eine niedrigere harte Grenze akzeptiert und in das simulierte VG_ (fd_hard_limit) ..__ usedby valgrind, um den Unterschied zwischen den reservierten valgrind-fds und den __.

Um das Problem zu umgehen, sollten Sie das Limit erhalten und dann nur das Soft-Limit unter dem Hard-Limit ändern, da das Ändern des Hard-Grenzwerts von der valgrind-Setrlimit-Simulation abgelehnt wird.

3
phd

Es scheint, dass dies eine der Einschränkungen von Valgrind ist, nämlich eine Beschränkung von setrlimit für Hard Limit, wenn unter Valgrind ausgeführt. Siehe in news für Version 2.1.2 :

  • Implementieren Sie zusätzlich ein emuliertes Soft-Limit für Dateideskriptoren zum aktuell reservierten Bereich, der effektiv als hart wirkt Grenze. Der Systemaufruf setrlimit aktualisiert jetzt einfach das emulierte Grenzen so gut wie möglich - das harte Limit darf sich nicht bewegen überhaupt und gibt nur EPERM zurück, wenn Sie es versuchen und ändern. Das sollte Unterbrechen Sie die Reduzierung des Soft-Limits und führen Sie bei valgrind Assertions aus versucht, Deskriptoren aus dem reservierten Bereich zuzuordnen. (Diese Kam tatsächlich aus Fehler # 83998).

Beachten Sie, dass Sie nicht die Einzige sind, die diese Valgrind-Einschränkung erreicht hat. Siehe beispielsweise github issue .

0
ks1322