[GODRIVER-1373] stack overflow when assigning values to a map Created: 24/Oct/19  Updated: 27/Oct/23  Resolved: 25/Oct/19

Status: Closed
Project: Go Driver
Component/s: BSON, CRUD
Affects Version/s: 1.1.2
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Folajimi Sparse Assignee: Isabella Siu (Inactive)
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Ubuntu 16.04, Intel Core i5, MongoDB version 4.2



 Description   

 

Running the following snippet:

 

package main
 
import (
   "context"
   "fmt"
   "log"
   "time"
 
   "go.mongodb.org/mongo-driver/mongo"
   "go.mongodb.org/mongo-driver/mongo/options"
)
 
type User struct {
   ID        string
   Name      string
   Followers map[string]*User
   Friends   map[string]*User
}
 
func main() {
 
   ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
   defer cancel()
 
   client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
 
   err = client.Ping(ctx, nil)
   if err != nil {
      log.Fatal("could not connect")
   }
 
   coll := client.Database("testing").Collection("users")
 
   ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
   defer cancel()
 
   u1 := &User{ID: "24", Name: "Test1", Followers: map[string]*User{}, Friends: map[string]*User{}}
   u2 := &User{ID: "25", Name: "Test2", Followers: map[string]*User{}, Friends: map[string]*User{}}
 
   u1.Friends[u2.ID] = u2
   u2.Followers[u1.ID] = u1
   
   // uncommenting the next line and commenting out the two above gives the same behavior i.e. assigning to self
   //u1.Followers[u1.ID] = u1 
 
   res, err := coll.InsertOne(ctx, u1)
   if err != nil {
      fmt.Println("error:", err)
   }
   fmt.Println(res.InsertedID)
}

 

 gives the following error:

 

runtime: goroutine stack exceeds 1000000000-byte limitruntime: goroutine stack exceeds 1000000000-byte limitfatal error: stack overflow

 

 

 

 



 Comments   
Comment by Isabella Siu (Inactive) [ 25/Oct/19 ]

Hi jimiolaniyan@gmail.com,

The stack overflow is caused by a circular map. InsertOne marshals the object it's inserting into bson, so it tries to marshal u1, which tries to marshal u2, which tries to marshal u1, and so on.  Trying to marshal this struct with mgo/bson or with the encoding/json library gives the same result. To avoid this circular marshaling, one option is storing user IDs instead of embedded objects in the map.

Generated at Thu Feb 08 08:36:16 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.