Possible reasons for a segmentation fault inside mallocgc during package importing

101 views
Skip to first unread message

Yonatan Gizachew

unread,
Aug 24, 2020, 10:05:34 PM8/24/20
to golang-nuts

We were trying to run a go c-shared library on a emulator (Written in C/C++). We use gccgo compiler to create .so file from test.go file, so that the runtime could be liked dynamically. Currently we are facing a problem while packages were imported in main.init. 
Here is a disassembly of the main.init function which was called from runtime.main
https://github.com/Emegua/golang_nuts/blob/master/main_init.S
We tried to debug the issue, and until now, it seems the problem is related to TLS.
We made breakpoint using b ../../../src/libgo/go/runtime/malloc.go:660.
When the c:= gomcache() is executed, a __tls_get_addr function retrieves some address from TLS. 
Refer to the following bt. 
From runtime.gomcache function here:
https://github.com/Emegua/golang_nuts/blob/663517937f34580288c2d07249ade515a7bf4c44/runtime1.go#L490

From the retrieved address (i.e, getg()), now it tries to retrieve its member variable (called mcache) by accessing to specific index using pointer dereferencing.
Please see here the disassembled 
https://github.com/Emegua/golang_nuts/blob/master/disas_1.S 

After a few steps, it retrieves the correct values c. 
 https://github.com/Emegua/golang_nuts/blob/6a246ae7715823688a74581649c77da4369f8717/malloc.go#L661
But while importing some packages, say runtime package, the same process (i.e., dereferencing the pointer obtained by __tls_get_addr) retrieves 0x0 which is nullptr.

From the following line, we inspected the all dereferenced value of pointer, step by step.

The results are as follows. Left column is before the import of runtime, right column is while importing runtime. As it shows, retrieved pointer is same for both situation (i.e., 0x7f7ae76d7b18), but it contains different value so the resulting dereferenced pointer(i.e., c) is also different. Please refer to the following image. 

gccgo --version
gccgo (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0

What would be any possible explanation for the segfault?
2IYvFW0mBWNq.png

Ian Lance Taylor

unread,
Aug 24, 2020, 11:05:53 PM8/24/20
to Yonatan Gizachew, golang-nuts
I don't know what is happening. It appears that somehow you are on a
thread that wasn't properly initialized.

Could you take a step back and show the steps you took to get to this
point? How exactly did you create the .so file? How exactly are you
running it?

Ian

Yonatan Gizachew

unread,
Aug 25, 2020, 1:22:36 AM8/25/20
to golang-nuts
Thank you for the reply!


How exactly did you create the .so file?
$ go build -o libgotest.so -buildmode=c-shared -compiler=gccgo test.go


How exactly are you running it?
     I used the .so file as a plugin in my simulator. 

After loading the library using dlmopen, we get the symbol of the 'mainGo' function with 'dlsym'. 
Then we tried to execute the 'mainGo' function. Here you may get the disassembly for 'mainGo'. As you can see from the disassembly `_cgo_wait_runtime_init_done` function was called to initialize the runtime.
Inside `_cgo_wait_runtime_init_done` function pthread_cond_wait called, and as a result other threads was created to initialize the runtime. 
Please look here and here for the bt of two of the threads. A new go-routine was created from the first thread, and it is inside here the segmentation fault appeared. Here is the bt. 
Reply all
Reply to author
Forward
0 new messages