Skip to content
Snippets Groups Projects
  • Emilio Cota's avatar
    1ff4a81b
    tcg: use QTree instead of GTree · 1ff4a81b
    Emilio Cota authored
    qemu-user can hang in a multi-threaded fork. One common
    reason is that when creating a TB, between fork and exec
    we manipulate a GTree whose memory allocator (GSlice) is
    not fork-safe.
    
    Although POSIX does not mandate it, the system's allocator
    (e.g. tcmalloc, libc malloc) is probably fork-safe.
    
    Fix some of these hangs by using QTree, which uses the system's
    allocator regardless of the Glib version that we used at
    configuration time.
    
    Tested with the test program in the original bug report, i.e.:
    ```
    
    void garble() {
      int pid = fork();
      if (pid == 0) {
        exit(0);
      } else {
        int wstatus;
        waitpid(pid, &wstatus, 0);
      }
    }
    
    void supragarble(unsigned depth) {
      if (depth == 0)
        return ;
    
      std::thread a(supragarble, depth-1);
      std::thread b(supragarble, depth-1);
      garble();
      a.join();
      b.join();
    }
    
    int main() {
      supragarble(10);
    }
    ```
    
    Resolves: https://gitlab.com/qemu-project/qemu/-/issues/285
    
    
    Reported-by: default avatarValentin David <me@valentindavid.com>
    Reviewed-by: default avatarPhilippe Mathieu-Daudé <philmd@linaro.org>
    Signed-off-by: default avatarEmilio Cota <cota@braap.org>
    Message-Id: <20230205163758.416992-3-cota@braap.org>
    [rth: Add QEMU_DISABLE_CFI for all callback using functions.]
    Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
    1ff4a81b
    History
    tcg: use QTree instead of GTree
    Emilio Cota authored
    qemu-user can hang in a multi-threaded fork. One common
    reason is that when creating a TB, between fork and exec
    we manipulate a GTree whose memory allocator (GSlice) is
    not fork-safe.
    
    Although POSIX does not mandate it, the system's allocator
    (e.g. tcmalloc, libc malloc) is probably fork-safe.
    
    Fix some of these hangs by using QTree, which uses the system's
    allocator regardless of the Glib version that we used at
    configuration time.
    
    Tested with the test program in the original bug report, i.e.:
    ```
    
    void garble() {
      int pid = fork();
      if (pid == 0) {
        exit(0);
      } else {
        int wstatus;
        waitpid(pid, &wstatus, 0);
      }
    }
    
    void supragarble(unsigned depth) {
      if (depth == 0)
        return ;
    
      std::thread a(supragarble, depth-1);
      std::thread b(supragarble, depth-1);
      garble();
      a.join();
      b.join();
    }
    
    int main() {
      supragarble(10);
    }
    ```
    
    Resolves: https://gitlab.com/qemu-project/qemu/-/issues/285
    
    
    Reported-by: default avatarValentin David <me@valentindavid.com>
    Reviewed-by: default avatarPhilippe Mathieu-Daudé <philmd@linaro.org>
    Signed-off-by: default avatarEmilio Cota <cota@braap.org>
    Message-Id: <20230205163758.416992-3-cota@braap.org>
    [rth: Add QEMU_DISABLE_CFI for all callback using functions.]
    Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>