@@ -728,21 +728,13 @@ const (
728
728
_GoidCacheBatch = 16
729
729
)
730
730
731
- // cpuinit sets up CPU feature flags and calls internal/cpu.Initialize.
732
- func cpuinit () {
731
+ // cpuinit sets up CPU feature flags and calls internal/cpu.Initialize. env should be the complete
732
+ // value of the GODEBUG environment variable.
733
+ func cpuinit (env string ) {
733
734
switch GOOS {
734
735
case "aix" , "darwin" , "ios" , "dragonfly" , "freebsd" , "netbsd" , "openbsd" , "illumos" , "solaris" , "linux" :
735
736
cpu .DebugOptions = true
736
737
}
737
-
738
- // find GODEBUG in envs
739
- var env string // env should be the complete value of the GODEBUG environment variable.
740
- for _ , value := range envs {
741
- if stringslite .HasPrefix (value , "GODEBUG=" ) {
742
- env = value
743
- break
744
- }
745
- }
746
738
cpu .Initialize (env )
747
739
748
740
// Support cpu feature variables are used in code generated by the compiler
@@ -761,6 +753,49 @@ func cpuinit() {
761
753
}
762
754
}
763
755
756
+ // getGodebugEarly extracts the environment variable GODEBUG from the environment on
757
+ // Unix-like operating systems and returns it. This function exists to extract GODEBUG
758
+ // early before much of the runtime is initialized.
759
+ func getGodebugEarly () string {
760
+ const prefix = "GODEBUG="
761
+ var env string
762
+ switch GOOS {
763
+ case "aix" , "darwin" , "ios" , "dragonfly" , "freebsd" , "netbsd" , "openbsd" , "illumos" , "solaris" , "linux" :
764
+ // Similar to goenv_unix but extracts the environment value for
765
+ // GODEBUG directly.
766
+ // TODO(moehrmann): remove when general goenvs() can be called before cpuinit()
767
+
768
+ // If the binary is an archive or a library, the operating system is Linux,
769
+ // and the system uses Musl, then read the environment variables from the
770
+ // /proc/self/environ file. Iterate over each null-terminated string read
771
+ // from the file. If any string has the specified prefix, return that string.
772
+ if libmusl {
773
+ for _ , value := range readNullTerminatedStringsFromFile (procEnviron ) {
774
+ if stringslite .HasPrefix (value , prefix ) {
775
+ return value
776
+ }
777
+ }
778
+ return env
779
+ }
780
+
781
+ n := int32 (0 )
782
+ for argv_index (argv , argc + 1 + n ) != nil {
783
+ n ++
784
+ }
785
+
786
+ for i := int32 (0 ); i < n ; i ++ {
787
+ p := argv_index (argv , argc + 1 + i )
788
+ s := unsafe .String (p , findnull (p ))
789
+
790
+ if stringslite .HasPrefix (s , prefix ) {
791
+ env = gostring (p )[len (prefix ):]
792
+ break
793
+ }
794
+ }
795
+ }
796
+ return env
797
+ }
798
+
764
799
// The bootstrap sequence is:
765
800
//
766
801
// call osinit
@@ -806,10 +841,10 @@ func schedinit() {
806
841
moduledataverify ()
807
842
stackinit ()
808
843
mallocinit ()
809
- goenvs ()
810
- cpuinit () // must run before alginit
811
- randinit () // must run before alginit, mcommoninit
812
- alginit () // maps, hash, rand must not be used before this call
844
+ godebug := getGodebugEarly ()
845
+ cpuinit (godebug ) // must run before alginit
846
+ randinit () // must run before alginit, mcommoninit
847
+ alginit () // maps, hash, rand must not be used before this call
813
848
mcommoninit (gp .m , - 1 )
814
849
modulesinit () // provides activeModules
815
850
typelinksinit () // uses maps, activeModules
@@ -820,6 +855,7 @@ func schedinit() {
820
855
initSigmask = gp .m .sigmask
821
856
822
857
goargs ()
858
+ goenvs ()
823
859
secure ()
824
860
checkfds ()
825
861
parsedebugvars ()
0 commit comments