Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

“pre Y2K bug”: XQF segfaults when reloading dozens of master servers plenty of servers #9

Closed
illwieckz opened this issue Oct 11, 2014 · 8 comments

Comments

@illwieckz
Copy link
Member

How to reproduce:

  1. Add many games with at least 1 master server per game (more than 10 master server)
  2. Select all this master servers
  3. reload !
  • Sometimes XQF segfault.
  • Sometimes XQF don’t segfault, but many many lines in server lists are blank.

It’s in the server listing part, not the master server part.

@illwieckz
Copy link
Member Author

This time it segfault in server.c at line 452, function parse_adress.

cf. https://github.com/XQF/xqf/blob/master/src/server.c#L452

#0  __GI___libc_malloc(bytes = 12) at malloc.c:2904
#1  g_malloc(n_bytes = 12) at /build/buildd/glib2.0-2.40.2/./glib/gmem.c:97
#2  parse_address(str = 0x9744aa "85.24.217.9:26000", addr = 0x7fffffffdec0, port = 0x7fffffffdeba) at server.c:452
#3  parse_server(token = 0x7fffffffdf20, n = 8, refreshed = 1413061447, saved = 0) at stat.c:530
#4  parse_qstat_record(conn = 0x93c1d0) at stat.c:768
#5  stat_servers_input_callback(chan = 0x95e350, condition = G_IO_IN, conn = 0x93c1d0) at stat.c:926
#6  g_main_dispatch(context = 0x6f1110) at /build/buildd/glib2.0-2.40.2/./glib/gmain.c:3064
#7  g_main_context_dispatch(context = 0x6f1110, context@entry = 0x6f1110) at /build/buildd/glib2.0-2.40.2/./glib/gmain.c:3663
#8  g_main_context_iterate(context = 0x6f1110, block = 1, block@entry = 1, dispatch = 1, dispatch@entry = 1, self = <optimized out>) at /build/buildd/glib2.0-2.40.2/./glib/gmain.c:3734
#9  g_main_loop_run(loop = 0x7ff3e0) at /build/buildd/glib2.0-2.40.2/./glib/gmain.c:3928`

This code:

int parse_address (char *str, char **addr, unsigned short *port) {
  char *ptr;
  // …
  *addr = g_malloc (ptr - str + 1);

What is that? g_malloc expect a gsizes, not a sum of chars!

cf. https://developer.gnome.org/glib/2.28/glib-Memory-Allocation.html#g-malloc

@illwieckz
Copy link
Member Author

sigabrt, stat.c:534

https://github.com/XQF/xqf/blob/master/src/stat.c#L534

#0  __GI_raise(sig = 6, sig@entry = 6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  __GI_abort() at abort.c:89
#2  __libc_message(do_abort = 1, do_abort@entry = 1, fmt = 0x7ffff5d7e668 "*** Error in `%s': %s: 0x%s ***\\n", fmt@entry = 0x7ffff5d7e668 "*** Error in `%s': %s: 0x%s ***\\n") at ../sysdeps/posix/libc_fatal.c:175
#3  malloc_printerr(str = 0x7ffff5d7e808 "free(): invalid next size (fast)", action = 1) at malloc.c:4996
#4  _int_free(av = <optimized out>, p = <optimized out>, have_lock = 0) at malloc.c:3840
#5  parse_server(token = 0x7fffffffdf20, n = 8, refreshed = 1413062385, saved = 0) at stat.c:534
#6  parse_qstat_record(conn = 0x835c10) at stat.c:768
#7  stat_servers_input_callback(chan = 0x835800, condition = G_IO_IN, conn = 0x835c10) at stat.c:926
#8  g_main_dispatch(context = 0x6f11f0) at /build/buildd/glib2.0-2.40.2/./glib/gmain.c:3064
#9  g_main_context_dispatch(context = 0x6f11f0, context@entry = 0x6f11f0) at /build/buildd/glib2.0-2.40.2/./glib/gmain.c:3663
#10  g_main_context_iterate(context = 0x6f11f0, block = 1, block@entry = 1, dispatch = 1, dispatch@entry = 1, self = <optimized out>) at /build/buildd/glib2.0-2.40.2/./glib/gmain.c:3734
#11  g_main_loop_run(loop = 0x8456e0) at /build/buildd/glib2.0-2.40.2/./glib/gmain.c:3928
#12  gtk_main() at :0
#13  main(argc = 2, argv = 0x7fffffffe298) at xqf.c:4079

This part:

  char *addr;
  //…
  if (!parse_address (token[1], &addr, &port))
    return NULL;

  h = host_add (addr);
  g_free (addr)

@illwieckz
Copy link
Member Author

with ptr == :27000 and str == 192.246.40.37:27000, (strlen(ptr) - strlen(str) + 1) == -12

@illwieckz
Copy link
Member Author

I suppose we must do (strlen(ptr) - strlen(str) + 1), something like ``(strlen("192.246.40.37:27000") - strlen(":27000") + strlen("\0"), ;-)

@illwieckz
Copy link
Member Author

ptr == ":26003"
str == "122.99.118.5:26003"

ptr - str + 1 == -11
strlen(ptr) - strlen(str) + 1 == 13

strlen("122.99.118.5") == 12

@illwieckz
Copy link
Member Author

$ git log -S '*addr = g_malloc (ptr - str + 1);' --source --all
commit 9ca134e3c35171b29ffd913847b3d9fd6f1e28fe refs/tags/xqf-0.9.4f
Author: Alex Burger <alex_b@users.sourceforge.net>
Date:   Sun Nov 5 20:40:48 2000 +0000

    Initial revision

    git-svn-id: http://svn.code.sf.net/p/xqf/code/trunk@3 d2ac09be-c843-0410-8b1f-f8a84130e0ec

Baaaad, this bug is at least more than 14 years old, before the first cvs commit ! It survived to the svn migration! Perhaps since the beginning!

😱 😱 😱 😱 😱 😱 😱 😱

already there in 2000:

*addr = g_malloc (ptr - str + 1);

🎆 🎆 🎆 I fixed the “pre Y2K bug” ! 🎆 🎆 🎆

@illwieckz
Copy link
Member Author

Youpi, I can query 25 master server and list 1589 server without segfault. 🌀

See the commit that fix the bug: edcf3bf

@illwieckz illwieckz self-assigned this Oct 11, 2014
@illwieckz illwieckz changed the title XQF segfaults when reloading dozens of master servers plenty of server XQF segfaults when reloading dozens of master servers plenty of servers Oct 11, 2014
@illwieckz illwieckz changed the title XQF segfaults when reloading dozens of master servers plenty of servers “before Y2K bug”: XQF segfaults when reloading dozens of master servers plenty of servers Oct 11, 2014
@illwieckz illwieckz changed the title “before Y2K bug”: XQF segfaults when reloading dozens of master servers plenty of servers “pre Y2K bug”: XQF segfaults when reloading dozens of master servers plenty of servers Oct 11, 2014
@illwieckz
Copy link
Member Author

The bug that causes some servers appearing blank when querying many servers is another bug.
See #10.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant