mirror of
				https://github.com/golang/go.git
				synced 2025-10-31 16:50:58 +00:00 
			
		
		
		
	runtime: skip doInit of plugins in runtime.main
Plugins may be loaded in the user's init code. If loading fails, md.bad is true, and doInit should not be executed. If loading succeeds, the plugin must run modulesinit and typelinksinit before doInit. Here is not protected by pluginsMu, and in concurrent scenarios it is possible to obtain the moduledata of the plugin that is still in the loading process. Any added modules after loop starts will do their own doInit calls. This fixes the issue introduced by CL 520375. Fixes #75102 Change-Id: I48e91ae21615a0c54176875a6a2dea8e1dade906 Reviewed-on: https://go-review.googlesource.com/c/go/+/697675 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
		
							parent
							
								
									9ae2f1fb57
								
							
						
					
					
						commit
						ea55ca3600
					
				
					 4 changed files with 45 additions and 1 deletions
				
			
		|  | @ -422,3 +422,11 @@ func TestIssue67976(t *testing.T) { | |||
| 	globalSkip(t) | ||||
| 	goCmd(t, "build", "-buildmode=plugin", "-o", "issue67976.so", "./issue67976/plugin.go") | ||||
| } | ||||
| 
 | ||||
| func TestIssue75102(t *testing.T) { | ||||
| 	globalSkip(t) | ||||
| 	// add gcflags different from the executable file to trigger plugin open failed. | ||||
| 	goCmd(t, "build", "-gcflags=all=-N -l", "-buildmode=plugin", "-o", "issue75102.so", "./issue75102/plugin.go") | ||||
| 	goCmd(t, "build", "-o", "issue75102.exe", "./issue75102/main.go") | ||||
| 	run(t, "./issue75102.exe") | ||||
| } | ||||
|  |  | |||
							
								
								
									
										21
									
								
								src/cmd/cgo/internal/testplugin/testdata/issue75102/main.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/cmd/cgo/internal/testplugin/testdata/issue75102/main.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| // Copyright 2025 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"plugin" | ||||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	_, err := plugin.Open("issue75102.so") | ||||
| 	if err == nil { | ||||
| 		panic("unexpected success to open a different version plugin") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func main() { | ||||
| 	fmt.Println("done") | ||||
| } | ||||
							
								
								
									
										11
									
								
								src/cmd/cgo/internal/testplugin/testdata/issue75102/plugin.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/cmd/cgo/internal/testplugin/testdata/issue75102/plugin.go
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| // Copyright 2025 The Go Authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
| 
 | ||||
| package main | ||||
| 
 | ||||
| func init() { | ||||
| 	panic("unexpected call to init") | ||||
| } | ||||
| 
 | ||||
| func main() {} | ||||
|  | @ -252,8 +252,12 @@ func main() { | |||
| 	// by package plugin). Run through the modules in dependency | ||||
| 	// order (the order they are initialized by the dynamic | ||||
| 	// loader, i.e. they are added to the moduledata linked list). | ||||
| 	for m := &firstmoduledata; m != nil; m = m.next { | ||||
| 	last := lastmoduledatap // grab before loop starts. Any added modules after this point will do their own doInit calls. | ||||
| 	for m := &firstmoduledata; true; m = m.next { | ||||
| 		doInit(m.inittasks) | ||||
| 		if m == last { | ||||
| 			break | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Disable init tracing after main init done to avoid overhead | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Wang Deyu
						Wang Deyu