diff --git a/src/Jamrules b/src/Jamrules index 9fe07c9d2..e93530904 100644 --- a/src/Jamrules +++ b/src/Jamrules @@ -1,6 +1,8 @@ C++ = g++ ; CC = gcc ; +LINKFLAGS += -rdynamic ; + if ! $(HAVE_LUA) { HAVE_LUA = 1 ; } diff --git a/src/common/kernel/battle.c b/src/common/kernel/battle.c index cf3950b67..e97e30256 100644 --- a/src/common/kernel/battle.c +++ b/src/common/kernel/battle.c @@ -2482,9 +2482,6 @@ aftermath(battle * b) sum_hp += df->person[n].hp; } - /* die weggerannten werden später subtrahiert! */ - assert(du->number >= 0); - if (df->alive == du->number) { du->hp = sum_hp; continue; /* nichts passiert */ diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index ce77f7701..1f779f6fa 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -734,7 +734,7 @@ verify_data(void) } if (eff_skill(u, SK_ALCHEMY, u->region)) alchemist += u->number; - if (u->number > 50000 || u->number < 0) { + if (u->number > UNIT_MAXSIZE) { if (lf != f->no) { lf = f->no; printf("Partei %s:\n", factionid(f)); @@ -2535,9 +2535,8 @@ remove_empty_units_in_region(region *r) faction * f = u->faction; if (!fval(f, FFL_NOTIMEOUT) && f->age > MaxAge()) set_number(u, 0); } - if ((u->number <= 0 && u->race != new_race[RC_SPELL]) - || (u->age <= 0 && u->race == new_race[RC_SPELL]) - || u->number < 0) { + if ((u->number == 0 && u->race != new_race[RC_SPELL]) + || (u->age <= 0 && u->race == new_race[RC_SPELL])) { destroy_unit(u); } if (*up==u) up=&u->next; diff --git a/src/common/kernel/karma.c b/src/common/kernel/karma.c index ff7e4f8d1..05cac68ba 100644 --- a/src/common/kernel/karma.c +++ b/src/common/kernel/karma.c @@ -351,13 +351,14 @@ buy_special(unit *u, struct order * ord, fspecial_t special) int fspecial(const faction *f, fspecial_t special) { - attrib *a; +#ifdef KARMA_MODULE + attrib *a; - for(a=a_find(f->attribs, &at_faction_special); a; a=a->nexttype) { - if(a->data.sa[0] == special) return a->data.sa[1]; - } - - return 0; + for(a=a_find(f->attribs, &at_faction_special); a; a=a->nexttype) { + if(a->data.sa[0] == special) return a->data.sa[1]; + } +#endif + return 0; } static int diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index d7414175f..a2e3ed95b 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -1124,7 +1124,7 @@ readunit(FILE * F) } set_order(&u->thisorder, NULL); - assert(u->number >= 0); + assert(u->number <= UNIT_MAXSIZE); assert(u->race); if (global.data_versionnumber >= 0); + assert(u->number <= UNIT_MAXSIZE); assert(u->race); for (i=0;i!=u->skill_size;++i) { diff --git a/src/common/kernel/unit.c b/src/common/kernel/unit.c index e1e5430a6..14443e386 100644 --- a/src/common/kernel/unit.c +++ b/src/common/kernel/unit.c @@ -807,9 +807,9 @@ inside_building(const struct unit * u) void u_setfaction(unit * u, faction * f) { - int cnt = u->number; + int cnt = u->number; unit ** iunit; - if (u->faction==f) return; + if (u->faction==f) return; if (u->faction) { set_number(u, 0); if (playerrace(u->race)) { @@ -823,17 +823,20 @@ u_setfaction(unit * u, faction * f) #endif } - iunit = &f->units; - while (*iunit!=u) iunit=&(*iunit)->next; - assert(*iunit); + if (u->faction!=NULL) { + iunit = &u->faction->units; + while (*iunit && *iunit!=u) { + iunit=&(*iunit)->nextF; + } + assert(*iunit); + *iunit = u->nextF; + } - *iunit = u->nextF; - - if (f!=NULL) { - u->nextF = f->units; - f->units = u; - } - else u->nextF = NULL; + if (f!=NULL) { + u->nextF = f->units; + f->units = u; + } + else u->nextF = NULL; u->faction = f; if (u->region) update_interval(f, u->region); @@ -844,27 +847,28 @@ u_setfaction(unit * u, faction * f) } } } + /* vorsicht Sprüche können u->number == 0 (RS_FARVISION) haben! */ void set_number(unit * u, int count) { - assert (count >= 0); - assert (count <= SHRT_MAX); + assert (count >= 0); + assert (count <= USHRT_MAX); #ifndef NDEBUG - assert (u->faction != 0 || u->number > 0); + assert (u->faction != 0 || u->number > 0); #endif - if (u->faction && u->race != u->faction->race && playerrace(u->race) - && old_race(u->race) != RC_SPELL && old_race(u->race) != RC_SPECIAL - && !(is_cursed(u->attribs, C_SLAVE, 0))) + if (u->faction && u->race != u->faction->race && playerrace(u->race) + && old_race(u->race) != RC_SPELL && old_race(u->race) != RC_SPECIAL + && !(is_cursed(u->attribs, C_SLAVE, 0))) { - u->faction->num_migrants += count - u->number; - } - + u->faction->num_migrants += count - u->number; + } + if (playerrace(u->race)) { u->faction->num_people += count - u->number; } - u->number = (short)count; + u->number = (unsigned short)count; } boolean diff --git a/src/common/kernel/unit.h b/src/common/kernel/unit.h index 1162a6db2..2bc7e0610 100644 --- a/src/common/kernel/unit.h +++ b/src/common/kernel/unit.h @@ -60,6 +60,7 @@ struct skill; # define UFL_SAVEMASK (UFL_MOVED | UFL_NOAID | UFL_OWNER | UFL_PARTEITARNUNG | UFL_LOCKED | UFL_HUNGER | FFL_NOIDLEOUT | UFL_TAKEALL | UFL_HERO) #endif +#define UNIT_MAXSIZE 50000 #ifdef HEROES extern int maxheroes(const struct faction * f); extern int countheroes(const struct faction * f); @@ -78,7 +79,7 @@ typedef struct unit { struct building *building; struct ship *ship; short age; - short number; + unsigned short number; /* skill data */ short skill_size; diff --git a/src/eressea/server.cpp b/src/eressea/server.cpp index fe14d5511..737a2ee99 100644 --- a/src/eressea/server.cpp +++ b/src/eressea/server.cpp @@ -153,6 +153,41 @@ struct settings global = { 1000, /* maxunits */ }; +#ifdef __GNUC__ +#include +#include + +static void +report_segfault(int signo, siginfo_t * sinf, void * arg) +{ + void * btrace[50]; + size_t size; + int fd = fileno(stderr); + + fputs("\n\nProgram received SIGSEGV, backtrace follows.\n", stderr); + size = backtrace(btrace, 50); + backtrace_symbols_fd(btrace, size, fd); + abort(); +} + +static int +setup_signal_handler(void) +{ + struct sigaction act; + + act.sa_flags = SA_ONESHOT | SA_SIGINFO; + act.sa_sigaction = report_segfault; + sigfillset(&act.sa_mask); + return sigaction(SIGSEGV, &act, NULL); +} +#else +static int +setup_signal_handler(void) +{ + return 0; +} +#endif + static void game_init(void) { @@ -644,6 +679,8 @@ main(int argc, char *argv[]) int i; char zText[MAX_PATH]; + setup_signal_handler(); + global.data_version = RELEASE_VERSION; sqlpatch = true; log_open("eressea.log");