*Virtual object name duplicates an existing object name

I am trying to debug a problem being caused by a line in our fluffos code in

/secure/simul_efun/overrides.c at line 253:

The path is probably “/somepath/city_server/7/6/0”.
This is a virtual room, and it works great in mudos, but gives this odd error in fluffos.
How do I fix this?

What does your /secure/simul_efun/overrides.c around line 253 look like?

243  object load_object(mixed path) {
244     object obj;
246     if (!path)
247        error("Attempt to load_object(0).\n");
249     if (objectp(path))
250        return path;
251     if (obj = find_object(path))
252        return obj;
253     obj=efun::load_object(path);
254     if (obj && obj->is_room()) {
255        PERMANENT_D->load_room(obj);
256        obj->add_extra_exits(path);
257        if(!obj->get_coordinates() && !obj->is_ooc())
258           CHANNEL_D->deliver_emote("warnings","load_object","Room: "
259             +file_name(obj)+" has no call to set_coordinates.\n" );
260     }
261     return obj;
262  }

As far as I can tell, this seems to be because a cloned virtual room is being passed in - which happens in mudos, but it isn’t causing this error in mudos… for some unknown reason.
It seems the simulate.c which is part of the drivers has some differences:

  if (stat(real_name, &c_st) == -1 || S_ISDIR(c_st.st_mode)) {
    ob = load_virtual_object(actualname, 0);
    return ob;

[ 2:45 PM ]


[ 2:45 PM ]

   if (stat (real_name, &c_st) == -1 || S_ISDIR (c_st.st_mode)) {
      svalue_t *v;

      if (!(v = load_virtual_object (name))) {
         return 0;
      /* Now set the file name of the specified object correctly... */
      ob = v->u.ob;
      remove_object_hash (ob);
      if (ob->name)
         FREE (ob->name);
      ob->name = alloc_cstring (name, "load_object");
      SET_TAG (ob->name, TAG_OBJ_NAME);
      enter_object_hash (ob);
      ob->flags |= O_VIRTUAL;
      ob->load_time = current_time;
#ifdef LPC_TO_C
      compile_to_c = save_compile_to_c;
#ifdef PRIVS
      if (ob->privs)
         free_string (ob->privs);
      init_privs_for_object (ob);
      return ob;

We tried copying this mudos code over to the fluffos code, and it hasn’t had any effect. I am trusting someone else to do the copying/compiling/modifications though.

DEBUG object=>/daemons/city_d<=
DEBUG file =>/daemons/city_d.c<=
DEBUG value =>/city/cityroom8#1079<=
*Virtual object name duplicates an existing object name.
Trace written to /log/runtime

It looks like the problem string is a cloned virtual room.

After stumbling around a lot, I have learned that the actual cause of the error is
And the problem is at this time in the fluffos version:
returns 0;
In the mudos version:
returns “/city/city_server/7/6/0”.
So, there’s something wrong with virtual room creation, and I’m not sure what yet.

I will take a look

Thank you, but I doubt it’s a fluffos problem.
It looks like some people altered how virtual rooms are created by the mudos driver, and I don’t know how they changed it.
It must be the order of function calls though.
Don’t worry about this - I’m certain it’s our fault, and not fluffos’s.

I have spent a long time debugging this, and have made no progress.
------/secure/simul_efun/overrides.c:259 -
locals: 0

if (objectp(path))
return path;
DEBUG("Find Object: ");
if (obj = find_object(path))
return obj;
=> obj=efun::load_object(path);
DEBUG("Returned: ");
if (obj && obj->is_room()) {

I don’t know how to handle this, and I just can’t make progress.

What information do I need to provide for someone tell help me out?
In short, MudOS does this properly, but FluffOS gives me an error message, and I can’t make heads or tails of what’s wrong. :frowning:

Can you first restate what is the problem exactly? If you have an code snippet , please paste it.

The problem is when I type: @ load_object("/domains/city/city_server/7/6/0")
on our mudos mud, it works perfectly.
When I type it on the fluffos mud, I get:

Mon Aug 24 20:19:09 2020
*Virtual object name duplicates an existing object name.
Object: /secure/simul_efun (/secure/simul_efun/overrides.c) at line 256

#0: '<fake>' at /secure/spirit#743 (/<driver>) at /(fake):0
#1: 'dispatch_modal_input' at /secure/spirit#743 (/secure/spirit/inputsys.c) at
line 332
#2: '<fake>' at /trans/obj/wish#762 (/<driver>) at /(fake):0
#3: 'shell_input' at /trans/obj/wish#762 (/obj/secure/shell.c) at line 170
#4: 'execute_command' at /trans/obj/wish#762 at line 178
#5: 'expand_arguments' at /trans/obj/wish#762 at line 77
#6: 'CATCH' at /trans/obj/wish#762 at line 77
#7: 'evaluate_code' at /trans/obj/wish#762 at line 68
#8: 'exec_code' at /secure/simul_efun (/secure/simul_efun/misc.c) at line 262
#9: 'exec_foo' at <none> (/trans/tmp/exec.c) at line 6
#10: 'load_object' at /secure/simul_efun (/secure/simul_efun/overrides.c) at
line 256
#11: 'compile_object' at /secure/master at line 53
#12: 'create_virtual' at /domains/city/city_server (/std/base_city_server.c)
at line 20
#13: 'get_city_room' at /daemons/city_d at line 378
#14: 'virtual_start' at /domains/city/rooms/city/cityroom8#763
(/std/base_room.c) at line 127
#15: 'virtual_create' at /domains/city/rooms/city/cityroom8#763 at line 37
(1-20 58%) [h]:
#16: 'load_object' at /secure/simul_efun (/secure/simul_efun/overrides.c) at
line 256
#17: 'create' at /domains/city/rooms/city/tent21 at line 17
#18: 'set_tent_location' at /domains/city/rooms/city/tent21
(/obj/base/misc/tent.c) at line 30
#19: 'load_object' at /secure/simul_efun (/secure/simul_efun/overrides.c) at
line 256
#20: 'compile_object' at /secure/master at line 53
#21: 'create_virtual' at /domains/city/city_server (/std/base_city_server.c)
at line 20
#22: 'get_city_room' at /daemons/city_d at line 378
#23: 'virtual_start' at /domains/city/rooms/city/cityroom8#781
(/std/base_room.c) at line 127
#24: 'virtual_create' at /domains/city/rooms/city/cityroom8#781 at line 38
#25: 'load_object' at /secure/simul_efun (/secure/simul_efun/overrides.c) at
line 256
#26: 'create' at /domains/city/rooms/city/tent22 at line 16
#27: 'set_tent_location' at /domains/city/rooms/city/tent22
(/obj/base/misc/tent.c) at line 30
#28: 'load_object' at /secure/simul_efun (/secure/simul_efun/overrides.c) at
line 256

What code would you like to see?

The strangest thing is it only fails the first time. It succeeds every following time until the room is destroyed again… then it fails the first time again.

after looking over the fluffos stack trace, my best guess on the problem is: while you are calling “virtual_create” in /domains/city/rooms/city/cityroom8#763 an virtual object itself, it is trying to load virtual object /domains/city/rooms/city/tent21 , and during its “create” it is trying to load “tent22” , and while loading “tent22” I think it is trying to load an virtual object that is named exactly as the actual object file, which would give you this problem

the useful part of stack is

#26: 'create' at /domains/city/rooms/city/tent22 at line 16
#27: 'set_tent_location' at /domains/city/rooms/city/tent22
(/obj/base/misc/tent.c) at line 30
#28: 'load_object' at /secure/simul_efun (/secure/simul_efun/overrides.c) at
line 256

if you can show what this is trying to load in #28, it will give you a better clue on why loading which object would fail, for example maybe it is trying to load “xxx” but there is already a object named “xxx”

I pushed an new fluffos commit to make the error message print out the actual name, which should help make the error much more clear. But I think to find out the real answer you need to see what “tent22” is trying to load

All tents set their location, which triggers a load_object():
In tent22.c and tent21.c, it is written:



// :FUNCTION set_tent_location
// Parameters:
//    file -> Filename of the object where this tent should be loaded.
// Description:
//    Sets the location for the tent.
// Returns:
//    TRUE on success
//    FALSE on error
int set_tent_location(string file) {
   object env;

   env = load_object(file);
   if (!env) 
      error(file+" is not a valid object file.\n");
   location_file = file;
   if (!location_file) 
      CHANNEL_D->deliver_channel("errors","Initial tent loading error.");

   return TRUE;

This works in mudos, and I’m not sure why it is causing a problem in fluffos.
I know the problem is load_object() is being passed: “/domains/city/city_server/7/6/0” which is what causes the error. What I don’t know is why this is causing an error in fluffos, but not mudos.
I also don’t know how to fix this error in fluffos since we need to load_object("/domains/city/city_server/7/6/0") somewhere to place the tent there before players enter the room and look around.

Line 256 has:
// DEBUG(“Find Object:”);
// DEBUG(find_object(path));
if (obj = find_object(path))
return obj;
// DEBUG(path);
=> obj=efun::load_object(path);
// DEBUG(“Load successful:”);
// DEBUG(obj);
if (obj && obj->is_room()) {

The strangest thing is if I call load_object("/domains/city/city_server/7/6/0") again after this error, it loads properly, and I can goto it fine.

ok, so that confirm that the issue is that we have an reentrancy issue, while you are loading object “/domains/city/city_server/7/6/0” it is loading tent22 which is trying to load “/domains/city/city_server/7/6/0” again , somehow didn’t find it through “find_object” , which cause it to load again to meet this issue .

let me see why “find_object” was not able to find it

Another strange thing is fluffos won’t boot if there are DEBUG statements in that function. The mud owner has to comment out the DEBUG statements every time he tries to start fluffos. I haven’t confirmed if mudos has the same problem.

ok, so this name conflict check is added in mudos v22.01 , I’m guessing your mudos version is older than this because I don’t see this name conflict check in the previous linked code. without this check the driver will probably just leak memory. FluffOS correctly caught this issue and didn’t leak memory, so it is doing the right thing.

But, regardless, back to issue on hand, I think I fully understand the issue now, This is an reentracey issue :

I think you need to change the logic in “‘get_city_room’ at /daemons/city_d at line 378” , I’m guessing it is using new() to construct new “cityroom8.c”, and calling ->virtual_start() right away, if you change this into call_out(0, (: xx->virtual_start() :) ); meaning calling virtual_start() after the current object is fully constructed, then it should work.

This will allow the current load_object for this virtual_object to finish first, then start calling creating on the object, as an workaround for this reentrancy problem: during creating parent object ,
you are creating new child object which in create is trying to load parent object again, which caused the virtual object to be constructed multiple times with same name during is creation.