Skip to content

Creating multiple targets leads to a b2 crash in make1c() #608

Description

@pkl97

Environment and version details

  • Operating System+version: Red Hat Enterprise Linux 10
  • Compiler+version: clang 21
  • Shell: Bash
  • B2 Version: 5.3.2

Running specific gRPC generation rules in our make system sometimes triggers the following crash in b2:

Core was generated by `/home/user/devel/bin/b2 -f Jamfile -a -j8'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x000055d8ac530970 in make1c (pState=0x55d8b427f110) at make1.cpp:710

(gdb) bt
#0  0x000055d8ac530970 in make1c (pState=0x55d8b427f110) at make1.cpp:710
#1  0x000055d8ac52f8a4 in make1 (targets=0x55d8b4272f10) at make1.cpp:247
#2  0x000055d8ac52d70e in make (targets=0x55d8b4272f10, anyhow=true) at make.cpp:159
#3  0x000055d8ac514391 in guarded_main (argc=5, argv=0x7ffdf5970a58) at jam.cpp:633
#4  0x000055d8ac514863 in main (argc=5, argv=0x7ffdf5970a58) at jam.cpp:694

This sample project shows the issue:

MultipleTargetCrashes.zip

The reproduction is simple:

for i in {1..1000}; do echo $i; b2 -f Jamfile -a -j8; done

One however needs a machine with sufficient parallelism to trigger the crashes. During 1000 runs I obtained 13 crashes.

The reason for the crash is a null pointer dereference in function make1c() of file make1.cpp.

This simple patch fixes the issue:

diff --git a/src/engine/make1.cpp b/src/engine/make1.cpp
index 1b1858af6..6a99f83b5 100644
--- a/src/engine/make1.cpp
+++ b/src/engine/make1.cpp
@@ -708,8 +708,8 @@ static void make1c( state const * const pState )
                      *    considered built before the additional MAKE1A state
                      *    processing even got a chance to start.
                      */
-                    make0( t->includes, t->parents->target, 0, 0, 0, t->includes
-                        );
+                    make0( t->includes, t->parents ? t->parents->target : 0, 0,
+                        0, 0, t->includes );
                     /* Link the old includes on to make sure that it gets
                      * cleaned up correctly.
                      */

With the patch applied the above for loop is absolutely stable. Even 10000 iterations do not trigger a single crash.

However I am not really sure if simply passing 0 to make0() if t->parents turns out to be 0 is the correct way to address the problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions