1

I used dlopen to load a dynamic link library (.so) in my program, called dlsym to get the address to a certain function foo.

Then I used fork and called foo in the sub-process, and used exit(0) to exit the sub-process. Till now, everything is alright.

And when I tried to fork and call foo again in the sub-process, I found that all data stored by static variables defined in foo was lost. I am sure that I didn't call functions like dlclose explicitly. So how can I prevent the data from disappearing?

Thanks a lot.

IcicleF
  • 61
  • 5
  • I don't quite follow. You create two separate processes after loading the shared library? Are both created from the parent? Some code would really help illustrate this better than words – StoryTeller - Unslander Monica Apr 24 '18 at 14:26
  • 1
    I agree, even pseudo-code will help. – YSC Apr 24 '18 at 14:28
  • 1
    It seems that you assume that static variables set by first call to `foo` in the first child process will be present when you call `foo` again in the second child process. This is not going to happen because those static variables lived in the address space of the first process and are now gone. Second child process will have separate set of static variables in separate address space so it won't have access to static variables of the first child process even if it was still alive. You will need to use some other means of IPC. – user7860670 Apr 24 '18 at 14:28
  • if they were altered before the fork, however, shouldn't those changes persist in both copies? or is there some automatic re-initialization of dlls? – Rob Starling Apr 24 '18 at 14:39
  • i agree that code would help. maybe even a reference case without the dll to show that that regular static vars changed before a fork persist as expected. – Rob Starling Apr 24 '18 at 14:40
  • suggested edits: 1) remove `c++` tag; change to `c`, 2) change title to "Why do my dll's static variables appear to be reset after a fork?" – Rob Starling Apr 24 '18 at 14:42
  • 2
    @RobStarling - Changing the tag is not necessarily an improvement. C++ has quite a fair few rules related to initialization of static objects. Sure, `dlopen` isn't addressed by the C++ standard, but it may be pertinent to the question. This is all assuming the OP ever comes back and addresses our concerns. – StoryTeller - Unslander Monica Apr 24 '18 at 14:45
  • @StoryTeller that's fair. i do think a title change would get better attention, though. (re: questions, it's only been 30min ;) ) – Rob Starling Apr 24 '18 at 14:54
  • OH! re-reading, i see that you specifically mentioned calling `foo` _after_ a fork *both* times. If you're expecting _changes_ that `foo` makes to persist, then you're out of luck, like @VTT said. – Rob Starling Apr 24 '18 at 14:57
  • 1
    @RobStarling - Which is plenty of time, if you ask me. My personal threshold for linking to http://idownvotedbecau.se/beingunresponsive is about one hour, but 30 minutes is also plenty of time to tend to one's question. We'll see I suppose :) – StoryTeller - Unslander Monica Apr 24 '18 at 14:57
  • Is `foo` similar to `void foo(int & v, bool set) { static int t; if (set) { t = v; } else { v = t; } }` ...? – Daniel Jour Apr 24 '18 at 14:57
  • oh wow. really? i assume about a day and a half is "unresponsive" b/c OP might ask at the end of a work day – Rob Starling Apr 24 '18 at 14:58
  • really, i think OP wants pointers to "how to use shared memory" – Rob Starling Apr 24 '18 at 14:59
  • @RobStarling - My view is that no one is holding a gun to anyone's head. If the OP can't tend to the question now, but can do so later, they can also ask later. – StoryTeller - Unslander Monica Apr 24 '18 at 14:59
  • 1
    @StoryTeller thank you for that link. I didn't expect it to be a real link at first, but I'll definitively bookmark this for later use. – Daniel Jour Apr 24 '18 at 15:00
  • 1
    Thanks a lot. I really didn't expect my first question here be responded so quickly. Also, when I asked my question it was almost midnight in China and I went to sleep :( so would you please forgive me – IcicleF Apr 25 '18 at 02:27

2 Answers2

1

You want shared memory. See How to use shared memory with Linux in C for some introductory pointers. Be forewarned, however, that synchronization is tricky and you will probably end up wanting a higher-level abstraction, like message-passing or semaphores.

(Alternatively, maybe forking isn't the model you're looking for. Threads are literally the concept of having multiple execution paths using the same process-memory space...)

Rob Starling
  • 3,868
  • 3
  • 23
  • 40
  • Thanks for the link. I'll go and read it and please forgive me if I have further questions. Also, thread is not a choice for me, because I don't know what `foo` would do -- that is, the library is written and compiled by other people, so I have to make sure the main process don't crash. – IcicleF Apr 25 '18 at 02:23
1

forking your program has the effect of duplicating its address space, including the storage for foo's static locals. It's that copy that was initialized in the child process by the call to foo.

It is no surprise, then, that the original storage is unchanged, as you can see from the second fork and call to foo on a second copy of that uninitialized storage.

Quentin
  • 62,093
  • 7
  • 131
  • 191
  • Thanks for the answer. So if `foo` is a black box to me and I don't know what it would do, then it is impossible for me to keep the data to the second `fork`. Is that true? – IcicleF Apr 25 '18 at 02:43
  • OK now I'm fully convinced that I'm unable to keep those data. I think I will just write another program and load .so in it and keep it running to avoid using `fork`. Thanks. – IcicleF Apr 25 '18 at 05:41
  • @JianGao `fork`ing from the child instead of the parent the second time would solve it, but is maybe not possible in your case. – Quentin Apr 25 '18 at 09:24