Welcome to the Builder Academy

Question Crash bug - need assistance with GDB

More
16 Jan 2018 22:13 #7381 by thomas

Though I Can trace the character up to the 3rd frame. I wonder if something happens between those steps.

The core does not change. You simply look at different levels in the stack.

Please Log in or Create an account to join the conversation.

More
17 Jan 2018 01:55 #7382 by cunning
Nothing like having your login timed out trying to post and lose it all. I have traced up the stack and I found no issues with characters. I see them pushed all the way up the stack. I did find something very interesting going from frame 2 to frame 1.
#2 0x00000000005586da in find_replacement (go=go@entry=0x196f7d0, sc=sc@entry=0x196fb10, trig=trig@entry=0x196fb50,
type=type@entry=0, var=var@entry=0x7ffdd9422911 "actor", field=field@entry=0x7ffdd9422917 "is_pc", subfield=0x7ffdd9422f10 "",
str=0x7ffdd9422b10 "", slen=512) at dg_variables.c:366
366 else if (ch->in_room != NOWHERE && (c = get_char_in_room(&world[ch->in_room], name)));
(gdb) print (char_data *) go
$1 = (char_data *) 0x196f7d0
(gdb) print &(char_data *) go
$2 = (char_data **) 0x7ffdd9422278
(gdb) print *(char_data *) go
$3 = {pfilepos = -1, nr = 504, in_room = 1132, was_in_room = 65535, motion_timer = 0, wait = 0, version = 0 '\000', player = {
passwd = '\000' <repeats 30 times>, passwd2 = '\000' <repeats 30 times>, name = 0x125a2c0 "Patrick paladin guild shopkeeper",
short_descr = 0x125a2f0 "Patrick the paladin guild shopkeeper", long_descr = 0x125a320 "Patrick the paladin of Skara Brae\r\n",
description = 0x125a350 "Patrick the paladin of Skara Brae was badly wounded while\r\ndefending the city. He is here trying to serv as best he\r\ncan with his ruined knees. He is still a powerful\r\nswordsman but simply can not g"..., title = 0x0,
sex = 1 '\001', chclass = 0 '\000', race = 0 '\000', level = 20 '\024', admlevel = 0 '\000', time = {birth = 1516034773,
logon = 1516034773, played = 0}, weight = 200 '\310', height = 198 '\306', last_age = 0}, real_abils = {str = 11 '\v',
str_add = 0 '\000', intel = 11 '\v', wis = 11 '\v', dex = 11 '\v', con = 11 '\v', cha = 11 '\v', ess = 100 'd'}, aff_abils = {
str = 11 '\v', str_add = 0 '\000', intel = 11 '\v', wis = 11 '\v', dex = 11 '\v', con = 11 '\v', cha = 11 '\v', ess = 100 'd'},
points = {mana = 10, max_mana = 10, hit = 174, max_hit = 174, move = 50, max_move = 50, hit_regen = 0, mana_regen = 0,
move_regen = 0, regen_factor = {100, 100, 100}, armor = -5, gold = 20000, bank_gold = 0, exp = 8000, hitroll = 0 '\000',
damroll = 20 '\024', remort_count = 0, deaths = 0, deaths_this_level = 0, reroll_count = 0, pc_steals = 0, xp_bonus = 0,
align_bonus = 0, oldcha = 0, oldstr = 0, oldstradd = 0, oldint = 0, oldwis = 0, oldcon = 0, olddex = 0, oldclass = 0,
oldhit_regen = 0, oldmana_regen = 0, oldmove_regen = 0, oldremort_total = 0, exploss = 0, dt_day = 0, dt_room = 0,
dt_count = 0}, char_specials = {fighting = 0x0, hunting = 0x0, position = 8 '\b', carry_weight = 31, carry_items = 5 '\005',
timer = 0, numplus = 0, succesful_hunt = 0 '\000', saved = {alignment = 1000, idnum = 0, act = {11083, 0, 0, 0}, affected_by = {
272, 0, 0, 0}, apply_saving_throw = {10, 10, 10, 10, 10}, kills = 0, monthly_kills = 0}},
player_specials = 0x93e040 <dummy_mob>, mob_specials = {memory = 0x0, attack_type = 0 '\000', default_pos = 8 '\b',
damnodice = 8 '\b', damsizedice = 3 '\003', mob_race_special = 0, last_direction = 0 '\000', func = 0x125a520}, affected = 0x0,
equipment = {0x0 <repeats 21 times>}, carrying = 0x19701e0, desc = 0x0, id = 101024, proto_script = 0x196faf0, script = 0x196fb10,
memory = 0x0, next_in_room = 0x0, next = 0x196e2b0, next_fighting = 0x0, followers = 0x0, master = 0x0, pref = 0, events = 0x0}
(gdb) print ch->in_room
$4 = 1132
(gdb) print world[ch->in_room]
$6 = {number = 2113, zone = 18, sector_type = 0, name = 0xc13930 "The Full Armor of God",
description = 0xc13950 "You enter a holy shop, dedicated to equipping a paladin to stand against \r\nevil. Along the west wall you see a counter and window, behind which \r\nthey are selling some equipment to help paladins in th"..., ex_description = 0xc13d80,
dir_option = {0x0, 0x0, 0x0, 0x0, 0x0, 0xc13b60, 0x0, 0x0, 0x0, 0x0}, motion_info = 0x0, room_flags = {1053708, 0, 0, 0},
light = 0 '\000', func = 0xc13fe0, proto_script = 0x0, script = 0x0, contents = 0x0, people = 0x1dc2b50, timed = -1, events = 0x0}
(gdb)
#1 0x000000000050eebe in get_char_in_room (room=<optimized out>, name=name@entry=0x2e55b30 "}1365") at dg_scripts.c:408
408 if (ch && valid_dg_target(ch, DG_ALLOW_GODS))
(gdb) list
403 char_data *ch;
404
405 if (*name == UID_CHAR) {
406 ch = find_char(atoi(name + 1));
407
408 if (ch && valid_dg_target(ch, DG_ALLOW_GODS))
409 return ch;
410 } else {
411 for (ch = room->people; ch; ch = ch->next_in_room)
412 if (isname(name, ch->player.name) &&
(gdb) print *ch
value has been optimized out
(gdb) print ch
$10 = <optimized out>
(gdb) print room
$11 = <optimized out>


we send in &world[ch->in_room] which is RNUM 1139 and in frame 1 we no longer have that value. It should be there, ch on the other hand we have not figured out yet and hence its NULL.

I cannot find any invalid free() that i can find for characters, I am looking now at rooms but I have yet to find any.

Sucks having 102 fever due to the walking pneumonia, i am starting to lose my mind LOL. IF you have any other pointers I am all ears.

Please Log in or Create an account to join the conversation.

More
17 Jan 2018 01:58 #7383 by cunning
Now it just happened on a person walking into the room. OK, I guess i really have to dig deeper.

Please Log in or Create an account to join the conversation.

More
17 Jan 2018 06:58 #7384 by thomas
I would like to see your code. I will not redistribute it.

I suggest zipping everything but the bin/circle file, and sending me a dropbox link on welcor2 @gmail.com

People here will know that this is a rare occurrence - I usually don't ask this.

Please Log in or Create an account to join the conversation.

More
17 Jan 2018 15:31 #7385 by cunning
Sent you email.

Please Log in or Create an account to join the conversation.

More
17 Jan 2018 23:37 #7390 by thomas
It is a bug, also in stock tba - luckily it was easily reproducible, once I saw the logs:

dg_scripts.c
Code:
void add_to_lookup_table(long uid, void *c) { int bucket = (int) (uid & (BUCKET_COUNT - 1)); struct lookup_table_t *lt = &lookup_table[bucket]; + if (lt && lt->uid == uid) { + log("add_to_lookup updating existing value for uid=%ld (%p -> %p)", uid, lt->c, c); + lt->c = c; + return; + } + + for (;lt && lt->next; lt = lt->next) + if (lt->next->uid == uid) { + log("add_to_lookup updating existing value for uid=%ld (%p -> %p)", uid, lt->next->c, c); + return; + } - for (;lt->next; lt = lt->next) - if (lt->c == c && lt->uid == uid) { - log ("Add_to_lookup failed. Already there. (uid = %ld)", uid); - return; - } CREATE(lt->next, struct lookup_table_t, 1); lt->next->uid = uid; lt->next->c = c; }

What causes the crash is when a player quits to menu and then logs back in. This triggers a new add_to_lookup call. And because the loop never checks the last entry (it checks lt, but guards against lt->next) we might add twice if no one else have been added in the same bucket since we last went there.
Now, if we log completely off, only the first entry is removed. The other is still there.
So when we connect again, we don't overwrite it, but simply append the correct one. Now, we have a pointer to the old free'd char_data in the list, and it is earlier in the list than the new, correct pointer.
Thus, a crash occurs when we try to dereference the pointer.

Please Log in or Create an account to join the conversation.

Time to create page: 0.213 seconds