View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
909 [LDMud 3.6] Compilation, Installation minor always 2023-12-23 21:22 2023-12-26 06:15
Reporter: gorgar Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.6.6  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: 3.6.7 make error
Description: Hi. Getting this error on making 3.6.7. See attachment for full output.


./mk-patchlevel.sh
3.6.7
bison --defines=lang.h -o lang.c lang.y
lang.y:2.9-25: error: %define variable 'api.location.type' is not used
 %define api.location.type {code_location_t}
         ^^^^^^^^^^^^^^^^^
Makefile:214: recipe for target 'lang.h' failed
make: *** [lang.h] Error 1
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: make.log (24,117 bytes) 2023-12-23 21:22
http://ldmud.eu/file_download.php?file_id=305&type=bug
Notes
(0002713)
Gnomi   
2023-12-24 00:32   
Which Bison version are you using? It seems like api.location.type is supported starting with Bison 3.4.
(0002714)
gorgar   
2023-12-26 06:15   
$ bison --version
bison (GNU Bison) 3.0.4
Written by Robert Corbett and Richard Stallman.

Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ cat /etc/*-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.6 LTS"
NAME="Ubuntu"
VERSION="18.04.6 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.6 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
908 [LDMud 3.7] Implementation crash always 2023-10-14 19:27 2023-10-15 18:11
Reporter: paradox Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: assigned Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: add_action with some efun operator closure args produces segfault
Description: I was writing an object that used `add_action` with a closure argument and noticed I could reliably segfault 3.6.7 (also 3.6.6 and 3.6.5) if the initial closure arg to 'efun::add_action' was given a particular efun operator closure as argument, instead of the intended lfun (e.g. because the lfun was accidentally omitted, or had the wrong name).

The choice of efun closure appears to matter. Using a normal efun closure like #'write, or #'notify_fail doesn't crash. Using an operator efun closure like #'switch, #',, or #'= does crash reliably.

Tags:
Steps To Reproduce: 1. create an object that uses `add_action(#'switch, "cmd");` but has no 'switch' lfun.
2. invoke 'cmd' as a living
3. observe crash
Additional Information: Here's a unit test that can be added to the driver test suite to demonstrate the crash:

```
#include "/inc/base.inc"
#include "/inc/client.inc"

#include "/sys/configuration.h"
#include "/sys/input_to.h"

void run_server()
{
    add_action(#'write, "test");
}

void run_client()
{
    call_out(#'switch, __ALARM_TIME__ + 0, "test\n");
}

void run_test()
{
    msg("\nRunning test for crash when add_action w/ efun closure arg:\n"
          "-----------------------------------------------\n");

    connect_self("run_server", "run_client");
}

string *epilog(int eflag)
{
    run_test();
    return 0;
}
```

Here's the backtrace from an instance of the crash:
```
(gdb) bt
#0 0x00000000004168d0 in closure_location (cl=0xffffffffffffffcc) at closure.c:5975
0000001 0x0000000000459336 in get_line_number_if_any (name=name@entry=0x7fffffff3840) at interpret.c:22405
0000002 0x00000000004d2af5 in errorf (fmt=<optimized out>, fmt@entry=0x509804 "Uncallable closure\n")
    at simulate.c:980
0000003 0x000000000046fc5c in int_call_lambda (lsvp=<optimized out>, num_arg=0, external=<optimized out>,
    bind_ob=<optimized out>) at interpret.c:21783
0000004 0x00000000004d5efe in execute_callback (cb=cb@entry=0x7ffff7711460, nargs=nargs@entry=0,
    keep=keep@entry=true, toplevel=<optimized out>) at simulate.c:4414
0000005 0x0000000000406a78 in parse_command (buff=buff@entry=0x7fffffff4590 "crash",
    from_efun=from_efun@entry=false) at actions.c:999
0000006 0x00000000004086bf in execute_command (str=str@entry=0x7fffffff4590 "crash", ob=0x7ffff7bbc0b8)
    at actions.c:1143
0000007 0x0000000000411551 in backend () at backend.c:979
0000008 0x000000000040576b in main (argc=<optimized out>, argv=<optimized out>) at main.c:704
```

I can provide a core dump/binary if needed but the core is ~10mb and too large for the issue tracker. Since the issue is so easy to reproduce it didn't seem like it would be very helpful anyway.
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
238 [LDMud 3.6] Efuns feature N/A 2004-11-26 23:50 2023-10-02 18:35
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.8 and before  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.3  
    Target Version:  
Summary: Colored string handling
Description: Short: Useful coloured string efuns
From: "Alexander Weidt et al." <tubmud@cs.tu-berlin.de>
Date: Fri Feb 23 13:42:33 2001
Type: Feature
New: Acknowledged
See also: f-011016-0

Hi Lars,,

hier schick ich Dir mal die Klasse basic/coloured_string.c.

Anmerkungen:
- #define REGEXP_TERMINAL_COLOUR_TOKEN "%\\^([^%]|(%%*[^%^]))*%%*\\^"
- LIB_CNTL_SEQUENCES->get_plain_mapping() liefert ein Mapping fuer
  terminal_colour(), welches alle hier im Mud definierten tokens enthaelt
  und auf "" abbildet.

Viele Gruesse,

  Coogan.
-----------------------------------------------------------------------
/*
 * /basic/coloured_string.c by Alfe for TubMud 01-Feb-14
 *
 * This is a basic class for handling coloured strings.
 */

#pragma strong_types

#include <regexps.h>
#include <libs.h> // Coogan, 16-Feb-01

private nosave mapping plain_mapping;

/*
 * this applies `changer' on all parts of the given coloured_string
 * which are not a colour token and returns the result.
 */
string apply_on_coloured_string(string coloured_string,closure changer) {
  mixed h;
  int i;
  h = regexplode(coloured_string,REGEXP_TERMINAL_COLOUR_TOKEN);
  for (i=0; i<sizeof(h); i+=2) // pick the non-tokens
    h[i] = funcall(changer,h[i]);
  return implode(h,"");
}

/*
 * this removes all colour tokens from the given coloured_string and
 * returns the result; thus it produces a verbatim string.
 */
string to_verbatim(string coloured_string) {
  if (!plain_mapping)
    plain_mapping = LIB_CNTL_SEQUENCES->get_plain_mapping();
  return terminal_colour(coloured_string,plain_mapping);
}

/*
 * this returns the visible string length of a coloured string
 */
int strlen_visible(string coloured_string) {
  if (!plain_mapping)
    plain_mapping = LIB_CNTL_SEQUENCES->get_plain_mapping();
  return strlen(terminal_colour(coloured_string,plain_mapping));
}

private void find_pos(string *parts,
                      int pos,status pos_from_back,
                      int real_part,int real_pos,
                      status as_start) {
  if (pos_from_back) {
    if (pos < 0) {
      real_part = sizeof(parts) - 1;
      real_pos = strlen(parts[<1]);
    } else {
      pos = strlen_visible(implode(parts,"")) - pos;
      find_pos(parts,pos,0,&real_part,&real_pos,as_start);
    }
  } else { // from front
    // skip all parts which are too short:
    for (real_part = real_pos = 0;
         real_part < sizeof(parts) && (as_start?
                                       pos > strlen(parts[real_part]) :
                                       pos >= strlen(parts[real_part]));
         real_pos += strlen(parts[real_part]),
         pos -= strlen(parts[real_part]),
         real_part += 2)
      ;
    if (real_part >= sizeof(parts)) { // too long?
      real_part = sizeof(parts) - 1;
      real_pos = strlen(parts[<1]);
    } else
      real_pos = pos;
  }
}

/*
 * this returns a substring of the given coloured string;
 */
varargs string substring(string coloured_string,
                         int start, int stop,
                         status start_from_back,status stop_from_back) {
  string *parts;
  int *real_pos, *vis_pos;
  int i;
  int real_start_pos,real_stop_pos;
  int real_start_part,real_stop_part;
  parts = regexplode(coloured_string,REGEXP_TERMINAL_COLOUR_TOKEN);
  find_pos(parts,start,start_from_back,&real_start_part,&real_start_pos,1);
  find_pos(parts, stop, stop_from_back, &real_stop_part, &real_stop_pos,0);
  if (real_start_part > real_stop_part)
    return "";
  if (real_start_part == real_stop_part)
    parts[real_start_part] =
      parts[real_start_part][real_start_pos..real_stop_pos];
  else {
    parts[real_start_part] = parts[real_start_part][real_start_pos..];
    parts[real_stop_part] = parts[real_stop_part][..real_stop_pos];
  }
  return implode(parts[real_start_part..real_stop_part],"");
}

varargs string coloured_sprintf(string format,varargs mixed *args) {
  int i;
  int strlen_diff;
  for (i=0; i<sizeof(args); i+=2)
    if (stringp(args[i+1])) {
      strlen_diff = strlen(args[i+1]) - strlen_visible(args[i+1]);
      if (args[i] < 0)
        args[i] -= strlen_diff;
      else
        args[i] += strlen_diff;
    }
  return apply(#'sprintf,format,args);
}

Aber gleich zu [] noch was anderes: Wir haben hier die Notwendigkeit
festgestellt, farbige strings mit terminal_colour()-token an definierten
Stellen umzubrechen bzw. teilstrings zu extrahieren, und diese Extraktion
ist in LPC recht teuer.

Dies ist bisher hier so geloest in einer sefun
subcoloured_string(string coloured_string,
                   int start, int stop,
                   status start_from_back,status stop_from_back):

string s = "%^BOLD_BLUE%^Test%^NORMAL%^ %^RED%^another test%^NORMAL%^";

subcoloured_string(s, 2) == "%^BOLD_BLUE%^est%^NORMAL%^ %^RED%^another test%^NORMAL%^"
s[0..3] == "%^BOLD_BLUE%^Test%^NORMAL%^%^RED%^%^NORMAL%^"
s[5..] == "%^BOLD_BLUE%^%^NORMAL%^%^RED%^another test%^NORMAL%^"

D.h. alle Farbtokens bleiben im resultat-string drin, und extrahiert wird
letztlich der verbatim-teil dazwischen.
Die sefun zerlegt zunaechst den String in farbtokens und plain text, dann
wird das extract auf den plaintext-Stuecken vorgenommen, und danach wieder
der farb-string zusammengesetzt. Wie gesagt, sehr teuer.

Aber hierbei koennen wir wirklich wieder in Probleme laufen, wenn man das
in [] machen wollte. Ein Datentyp 'coloured_string' waere wirklich nett.
Und/oder natuerlich eine efun, die diese extrahierung von plain text
aus colour-token-verseuchten strings vornimmt. :-)
----------------------------------------------------------------------------
And Slava wrote in Oct 2001:

Recently I revealed great demand in something like hibrid of
sprintf+terminal_colour. Also I've discovered, that some time ago
there was something about this topic - f-990309-1.

In the matter of fact there is a great demand in such a functionality
in the driver. Till now, there are no official way, how to handle
coloured strings. I mean, yes you can do something with it - wrap,
and do very rudimentary formatting, using terminal_colour. But this is
not enough.

Furthermore, without additional and expensive workarounds, there are no
way how to:

1. format coloured string like in sprintf(), especially using such a
   modifiers, like: '-=', '|=', etc.
2. measure coloured string length like in strlen() or sizeof()
3. Use all the great funs, that we have for their non-coloured
   equivalents. All because of there is difference in actual string
   size and its displayable one.



Subject: sprintf() and colour strings
From: Lars Duening, Alfe
Date: 2001-10-16
Type: Feature
State: Acknowledged.
See also: f-010223, f-011015-1, f-000905-1

New format specifier '%S' to format colour-coded strings, '%s' normal strings
as usual.

Optionally introduce an efun

  csprintf(mapping cntl, string format, mixed args...)

which first applies sprintf(), and then replaces all colour strings in the
result before returning it.

Dafire also requested this formatting capability:


From: "Bastian Hoyer" <dafire@dafire.de>
Date: Tue, 16 Oct 2001 11:15:39 +0200


Hallo Lars,

was ich braeuchte waere ein leerzeichen das vorne am Wort klebt :)

also ich mache eine liste die so aussieht:

aaa: +bbb -ccc +ddd eee fff

vor jedem wert hab ich ein + oder - oder ein leerzeichen :)

wenn das jetzt umbricht sieht das evtl so aus :

aaa: +bbb -ccc +ddd
     eee fff

weil das Leerzeichen vor eee beim umbrechen wegfaellt :)

Ich hoffe das war irgendwie verstaendlich :)
Ich glaub bei html ist das ein   :)

Bastian
Tags: ldmud-extensions
Steps To Reproduce:
Additional Information:
Attached Files: p-020810.gz (9,435 bytes) 2004-11-27 01:15
http://ldmud.eu/file_download.php?file_id=30&type=bug
Notes
(0000223)
lars   
2004-11-27 01:14   
p-020810: Hyperborea's implementation of formatting of colored text (using their own color tag notation)
(0001781)
_xtian_   
2010-03-10 17:54   
zesstra: this might be something for your extras git-repository, although I would actually prefer avalons colour-aware implementation (which is also MXP sequence aware). I just thought I'd bump this.
(0001793)
zesstra   
2010-03-14 10:25   
Uh. Yes, that would be IMHO a good candidate.
Anybody interested in 'adopting' this? ;-)
(0002711)
Gnomi   
2023-10-02 18:35   
sprintf() in LDMud 3.6.3 honors ANSI Escape sequences together with Unicode Grapheme Clusters.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
865 [LDMud 3.6] LPC Language feature N/A 2018-07-25 17:54 2023-10-02 18:27
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: MacOS X  
Priority: normal OS Version: 10.9.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.7  
    Target Version:  
Summary: efun is_typeof() to check if a program is inherited
Description: Ein Wunsch eines Magiers aus dem MG...

--- cut here ---
wenn ihr mal wieder am Driver baut: so etwas wie is_typeof(object o, str
baseloadname) waere cool.

Semantik:
  return objectp(o) &&
         member(program_name+".c", inherit_list(o))>=0;

Nur halt nicht so teuer :D
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0002460)
Gnomi   
2018-07-25 19:25   
I think the name is too similar to the already existing efun typeof (which handles values, not objects). A name that uses the term 'inherit' instead of 'type' would imho be better.

The objectp(ob) part is redundant if the efun accepts only objects as their first parameter. (Anything else then results in a compile or runtime error.)
The searched name shall be given as a program name, thus already containing the ".c" ending.

So it would basically boil down to member(baseloadname, inherit_list(ob))>=0;

But I would think passing an object as the second parameter (and then using its program name) would be okay also.
(0002461)
zesstra   
2018-07-28 11:30   
The name is secondary, I just used it as given in the suggestion. ;-) The basic issue of @Leonidas was the overhead of creating the complete array of inheritees followed with the member().
Agreed, using the program name of a second optional argument would be nice as well.
baseof() would also be an idea if not already in use for structs. Although one could accept structs and objects, if adventurous.
(0002689)
Gnomi   
2022-10-06 20:23   
Upcoming driver version will allow something like: check_type(ob, [object "/obj/table"])
(0002710)
Gnomi   
2023-10-02 18:27   
Implemented check_type(ob, [object "/obj/table"])

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
792 [LDMud 3.6] Efuns feature N/A 2011-11-01 17:39 2023-10-02 18:26
Reporter: _xtian_ Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.7  
    Target Version:  
Summary: limited( expression ... ) would be nice
Description: Similar to catch( expression ) it would be nice to have a variant of limited() in which one can simply write an expression out.

limited() is hugely helpful for securing critical code, but a limited( expression ... ) variant would help with adoption, as it would make adding a limited() around an expression as easy as adding a catch().

Example:

BEFORE:
  err= catch( ob->fun() )

AFTER (proposed):
  limited( err= catch( ob->fun() ) )
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002076)
zesstra   
2011-11-02 10:05   
AFAIK that needs to hacked directly into the compiler then. That would replace the efun altogether. Since that is not compatible to the current efun, we would probably need two different keywords for that.

But does it really save much effort compared to
limited(function void () {err=catch(...);} ); (faster)
limited( (: err=catch(...); :) );
?
(0002077)
_xtian_   
2011-11-10 09:26   
oh, hadn't thought of that.

Well, then you can probably close this item. thanks!
(0002596)
Gnomi   
2021-04-16 21:29   
An alternative would be to add a keyword to the already existing catch(), if you want to catch and limit at the same time:
  err = catch(ob->fun(); limit 200000);

The question here is what kind of limits would be needed? The full blown limited() syntax with all in an array or single tags or just eval limits?
Do you need only reduction of the limit or also expand it (like limited() can, but that needs privileges).
(0002690)
Gnomi   
2022-10-06 20:29   
Agreed on implementing catch(ob->fun(); limit 200000); for eval limits in catch().
(0002709)
Gnomi   
2023-10-02 18:26   
Implemented catch(expr; limit N)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
526 [LDMud 3.3] Portability feature always 2008-01-26 16:10 2022-10-07 00:00
Reporter: zesstra Platform: Darwin 9.1.0  
Assigned To: OS: MacOS X  
Priority: normal OS Version: 10.5.1  
Status: new Product Version: 3.3  
Product Build: r2364 Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Implicit conversions of 64-bit values into 32-bit values
Description: The gcc in MacOS X 10.5 has a switch for enabling some interesting warnings. -Wshorten-64-to-32 warns about implicit conversions (truncations) of 64-bit values into 32-bit values. This is interesting for people who use the driver on 64-bit platforms, I guess, because this conversion is generally not lossless.
I learned about this switch today and enabled it to satisfy my curiosity. ;-)
I got 643 warning during building the driver.
I will attach the build log to this bug, because I guess, at sometime we have to look into these warning, as that truncations may well cause some bugs and maybe people working on 64-bit platforms want to have a look.
Tags:
Steps To Reproduce: Compile the driver on MacOS X 10.5 with -Wshorten-64-to-32.
Additional Information:
Attached Files: build.log (81,666 bytes) 2008-01-26 16:10
http://ldmud.eu/file_download.php?file_id=114&type=bug
Notes
(0000590)
zesstra   
2008-01-27 16:48   
I had a quick glance at some of these warnings and identified some general cases until now. Perhaps we should think a moment, how to handle them consistently.
(I assume for now the 64-bit platform having the LP64 data model: longs and pointer 64 bits, ints 32 bit, shorts 16 bits.)

1. Using svalue.u.number or p_int/p_uint as input values, calculate something
   and assign the result to int.
   If we can be sure, that the result always fits into int, we could
   add an explicit cast to int. But maybe we should just use p_int?
2. assign svalue.u.number to an int value. I think, these cases should be
   changed to p_int val = svalue.u.number;
   Especially something like
   int d;
   if ( 0 != (d = (left->u.number >> 1) - (right->u.number >> 1)) )
   if ( 0 != (d = left->u.number - right->u.number) )
   suffers from this. (from i-svalue.cmp.h)
3. assigning time stamps (like current_time) to int. Here we should
   definitely use mp_int (current_time is mp_int) or IMHO better time_t
   for all time values.
4. svalue.x.generic: in svalue.h is mentioned, this generic is usually
   svalue.u.number << 1 and x.generic is also used as 'secondary type
   field' handle for comparisons, don't know the details here...
   Are there anywhere any details about x.generic? BTW: u.number is
   p_int (8 bytes) and x.generic is ph_int (2 bytes).
5. assigning return values from long-functions to int (e.g.
   find_function in closure.c). Should be changed, I think, probably
   by changing the assignment. I assume, the return values of functions
   are chosen deliberately. ;-)
6. Assigning pointers or differences of pointers to int, e.g.
   int ix = ... (current_variables - current_object->variables);
   where variables is a pointer to svalues. May be a problem or not, but
   I would suggest to avoid any risks... (This issue is similar to 1)
   BTW: What to use for pointers? p_int? Or intptr_t?

What do you think?
(0000591)
Largo   
2008-01-27 17:06   
> IMHO better time_t for all time values.
I strongly agree to this. time_t is not only the standard typedef for time values, it should also produce more readable code.
(0000592)
Gnomi   
2008-01-27 17:20   
> IMHO better time_t for all time values.
I disagree. Finally all timestamps end up in the MUD as LPC values. So at one point it has to be converted to p_int (the type of svalue.u.number), so why not do it at the source (current_time)?
(0000594)
zesstra   
2008-01-30 16:01   
Im not so sure. Right now, time_t and p_int are both typedefed to long, so there is no conversion necessary.
If that should change, I see basically 2 possibilities:
a) in a way that an impplicit conversion is lossless
b) if p_int and time_t are of 2 incompatible types we would have problems
   in any case: Either the conversion to svalues is not lossless and we
   get garbage from efuns which deal with time or the driver uses an
   incompatible data type for calling the libc functions which deal with
   time values, which can also be very ugly.

I personally agree, that time_t is more readable.
BTW: from backend.c I noticed concerning current_time: "TODO: Should be time_t if it is given that time_t is always a skalar.".

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
325 [LDMud 3.6] General minor always 2004-12-17 12:59 2022-10-06 23:17
Reporter: menaures Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: assigned Product Version:  
Product Build: Resolution: reopened  
Projection: none      
ETA: none Fixed in Version:  
    Target Version: 3.5.0  
Summary: array index range inconsistency
Description: Indexing an array by range [x..y] always works, even for negative ranges. However, if you try to assign new values to the indexed part of the array, you get a Lower/Upper range index out of bounds Runtime-Error.

Example:
   
({0,1,2,3})[-3..1]
    -> ({0,1})
    
({0,1,2,3})[-3..1] = ({4,5})
    -> Lower range index out of bounds: -3, size: 4.

({0,1,2,3})[2..5] = ({6,7,8})
    -> Upper range index out of bounds: 5, size: 4.

I like sloppyness (to a certain degree), it's actually sad to see some of it fade away in 3.3. I'm not keen on this half-and-half sloppyness, however. I'd prefer these ranges to work at all times, or never.

Now for something not completely unexpected:

({0,1,2,3})[4..-1] = ({9})
    -> ({0,1,2,3,9,0,1,2,3})

Where did that 'out of bounds' error go here? And what's with the result? Although the behaviour is half documented, it doesn't make any sense to me.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000260)
lars   
2004-12-18 16:09   
While I agree that the array indexing should work the same all the time, I feel uncomfortable to make the indexing for retrieval stricter as it is right now because I'm afraid that it would break existing code (I remember the problems I had when I disallowed indexing past the end of strings). At the same time I don't want to relax the bounds checking on the assignment simply because I dislike sloppy programming.

What I will do is
 - throw an error for the last case (assignment to a negative range)
 - in 3.3 out-of-bounds ranges for retrieval will generate a warning.
(0000261)
lars   
2004-12-18 18:51   
Ok, not really resolved on all counts, but the array range handling will be with us for a while either way.

I implemented the changes I wrote about in my bug note in 3.2.11-dev.689 and 3.3.531.
(0000262)
menaures   
2004-12-20 08:33   
If you dislike sloppy programming, do you intend to remove all sloppy elements from LPC? That would change the language quite a lot if you think about it. I'd rather keep the sloppyness, add sloppyness even, but in a clearly defined, well documented and consistent manner. Then you'd no longer have to think of it as sloppy, but rather a cool feature of the language.
(0000263)
peng   
2004-12-20 11:06   
The change for the warnings for out-of-bounds-ranges gave is a huge amount of warnings, and I don't like them. There is no broken code at all and fixing all the places where out-of-bound-ranges could occur wastes our time and is inefficient, since it brings a lot more code to write (every index has to check against sizeof) and no better code at all.
So I've thrown out this change since its pretty useless.

The error for the asignement case is ok.
(0000264)
malc   
2004-12-21 01:11   
I have an idea...maybe it's useless, maybe not. I agree with Lars solution on this issue. However, I can also see Peng's viwepoint, and I'm sure lots of people would have problems like that.

I also think that people starting fresh, with new code/libs, whatever, ought to do it right the first time, since they have no legacy code to support.

So my idea is, in 3.3, make the default like the changes Lars made. Add a --enable-sloppy-code (or whatever) to allow the behavior similar to what Peng/Menaures wants. As time goes on and Lars cleans up LPC, making it a better language, more of the existing code can be added to this enable option. All the while, defaulting to good, clean code constraints that new libs would (hopefully) take advantage of. Maybe it would make the source too convoluted, but I really dislike sloppy programming as well.

-Malc
(0000265)
lars   
2004-12-21 16:01   
While I am certainly nudging LPC into a direction with stricter checking, it will never be a fully checked language simply because there is too much code relying on the old behavior. Peng's comment is a good illustration for it.

Now, as far as these array bounds are concerned, my thinking no goes into the direction to couple the warnings with the no-warn-deprecated pragma, as it is already done for string indexing. If the two checks however are disconnected (read: code which wants to check string indices, but not array range indices), a new pragma just for the bounds checking would be in order.
(0000267)
lars   
2004-12-22 03:08   
The array range indexing warnings in 3.3 are as of 3.3.632 controlled by the warn-deprecated pragma.
(0000862)
zesstra   
2009-01-08 06:48   
Do have to do anything more here? Do we need the additional pragma Lars mentioned? If not, I believe this should be closed.
(0000866)
Gnomi   
2009-01-08 07:36   
We have to decide, which way to go for 3.5, as deprecated behavior will likely be removed there.
(0001976)
zesstra   
2011-02-14 15:07   
IMHO, there some different cases:

Arrays:
a) indexing past end of array: is already an error
b) indexing with negative ranges for assignment: is an error
c) indexing with negative ranges for retrieval / Out-of-bounds lower range limits: Actually, I vote for error, because I assume they are not too common and I perceive them as unreasonable from the beginning.
d) Out-of-bounds (upper) range limits: are probably far more common and, so far, they are actually not deprecated. I don't even have an idea, how many we might have in MG. Maybe we should deprecate them first?

Strings:
e) Indexing past string end by more then one: already forbidden.
f) indexing with negative ranges for retrieval: like c), disallow them.
g) Indexing past string end: they are really common in MG. And since there are few people caring about them, I see only very slow improvement. In my experience, the most often issue here is ""[0] (most people assume, there is an input and want to have the first char). I am thinking about the following: start with making it an error for strings != "" and keep the deprecated warning for some more time for ""? That would reduce the sudden impact of a huge number of errors but make the point, that they will be gone at some point?
(0002705)
Gnomi   
2022-10-06 23:17   
We target LDMud 3.7 for making problematic indexing expressions errors.

In the meanwhile we'll extend the range_check pragma to strings to propagate similar behavior as with arrays.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
856 [LDMud 3.7] General major always 2017-12-16 11:41 2022-10-06 23:00
Reporter: manuel Platform:  
Assigned To: OS: gnu/linux  
Priority: normal OS Version: current  
Status: confirmed Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Cipher list in tls.h lacks modern ciphers
Description: Up to date tls libraries like libgnutls or libssl (from openssl) provide ciphers that are not listed in mudlib/sys/tls.h. If the define TLS_CIPHER_NAME(x) is called naively it may choke on a bad index.
Tags:
Steps To Reproduce: Install mudlib/sys/tls.h and link ldmud with libgnutls28 (current dev version in debian stable is 3.5.8). Initiate a tls session with TLS_CIPHER_AES_256_GCM or any other cipher that is not provided in tls.h. Call TLS_CIPHER_NAME(x).
Additional Information: See the attached example of a tls.h updated for usage with a current libgnutls28.
Attached Files: tls.h (2,600 bytes) 2017-12-16 11:41
http://ldmud.eu/file_download.php?file_id=292&type=bug
Notes
(0002285)
zesstra   
2017-12-16 22:31   
And as far as I can see, it won't work at all with OpenSSL, because then tls_query_connection_info() will return the cipher name, not any index.
IMHO the API is not great even with an up-to-date table/tls.h.

I would argue, that tls_query_connection_info() should - if necessary - translate any enums/indices from the used crypto lib to a common name...
(0002446)
Gnomi   
2018-01-30 23:46   
I agree.
(0002703)
Gnomi   
2022-10-06 23:00   
The efun should be changed to return a struct and the struct should contain strings for algorithms instead of ids. Target LDMud 3.7.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
299 [LDMud 3.5] Implementation feature N/A 2004-11-27 01:01 2022-10-06 22:50
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: assigned Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Redesigning mappings, arrays, lvalues
Description: Short: Redesigning arrays and mappings, and lvalues.
From: Lars
Date: 2002-08-13
Type: Feature
State: New

The current problem with arrays and mappings is that even though they are
by-reference objects, they implement it differently. This is most visible
in the construct lhs += rhs, which for arrays creates a copy of lhs, but not
for mappings. Reason is that in arrays the data is stored in the array header
structure, whereas mappings store the data in a separate memory block.

Strings again act like arrays even though they use a separate memory block for
the data, but otoh they are easy to duplicate and it would be unnatural
for them to be by-reference datatyps.

Having a by-reference type may feel unusual for programmers coming from other
languages, but is no functional problem.

Note: Python handles everything by reference. list.append() changes in-place,
      list + x creates a new list.

Solution 1: Implement the by-reference semantics consequentially

  This means:

  'lhs = rhs1 + rhs2' always creates a new item, copies the content of rhs1
  and rhs2 into it and then assigns the new item to lhs, freeing whatever
  was in lhs before.

  'lhs += rhs' takes the contents of rhs and adds them to the existing lhs.

  LPC already has the semantic that lhs[] works directly on the given
  array/mapping, but it might help if programmers could specify directly
  that the lhs is to be made duplicated if referenced by more than one
  owner. For example:

    'unique lhs += rhs' would act like 'lhs = lhs + rhs'
    'unique lhs[i] = j' would act like 'lhs = copy(lhs); lhs[i] = j'

  'unique' could also be used in a rhs context and would act like copy().
  The special form 'unique lhs1, lhs2, lhs3,...' would act like
  'lhs1 = copy(lhs1); lhs2 = copy(lhs2); lhs3 = lhs(3);'

  In order to implement this efficiently, it might be useful to have a
  separate svalue type for arrays with fixed number of elements (structs,
  tuples). Another idea would be to store the initial elements in the array
  header structure, and let later changes to the array replace the first
  svalue entry with a special svalue (T_ARRAY_EXTENSION) pointing to the
  additional data.

  The disadvantage would be that ({}) != ({}) (but ([]) != ([]) already
  anyway).

Solution 2: Implement a by-value semantics.

  Both 'lhs = rhs1 + rhs2' and 'lhs += rhs' create a new item, copy the
  content of rhs1 and rhs2 into it and then assigns the new item to lhs,
  freeing whatever was in lhs before. The advantage of using the '+='
  operator would be that the interpreter can avoid duplicating lhs
  if it doesn't have more than one reference.

  To implement this efficiently, the driver would have to implement
  a copy-on-write semantic.

  To allow the sharing of arrays and mappings, programs would explicitely
  create references to it, like 'return &foo'. A good implementation of
  these references would be to use indirection like this:

    type a = value;

      a = (T_TYPE, value)

    type b = &a;
    type c = &b;

      a = (T_LVALUE)\
      b = (T_LVALUE)- (3 refs, (T_TYPE, value))
      c = (T_LVALUE)/

    The lvalue-resolution code would then detect and collapse lvalue
    holders with only one ref left.

  Handling references to subranges or single elements would require
  some more effort - views maybe? One view would cache the referenced
  element and write it back to the underlying structure when the
  underlying structure as a whole is read, or when another view
  to the same structure is about to be changed. This would imply a back-
  pointer from the lvalue-holder to the list of views.

  With this, the language would need a way to ignore the lvalue mode:

    type a = value; type b = &a;

    b = 0; --> removes value from a and b
    &b = 0; --> removes value from b, but not from a
    &b = 1; --> just assigns '1' to b, ignores the '&' as b is not an lvalue.

  Another modification would be to allow only read access to the
  reference: type b = const ref a;
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002702)
Gnomi   
2022-10-06 22:49   
We would like to change array semantics into a full reference type (similar to mappings). So changes to the array size (due to operator assignments like += or using slice assignments) will not create any copies of arrays anymore. Because the new behavior would be more intuitive than the current one. Target for this would be LDMud 3.7.

As this is may break a lot of code, the next step would be to add a pragma (default on) to warn when array operations (slice assignment, operator assignments) create a new array and the original array has more than one reference (i.e. when the behavior would be different with an array with pure reference semantics). Also warn on comparisons with the empty array (==, !=, member, in, -=, &=, mapping lookup).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
476 [LDMud 3.3] Runtime tweak always 2006-06-28 12:48 2022-10-06 22:11
Reporter: fufu Platform:  
Assigned To: fufu OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Improve eval statistics gathering (patch)
Description: This patch adds calls to mark_start_evaluation() and mark_end_evaluation() for external master applies, calls to logon() and erq_send callbacks. It also adds a mark_end_evaluation() in the global error handler
Tags:
Steps To Reproduce:
Additional Information: there are some other places which may or may not be toplevel evaluations:
  telnet negotiation hook - I don't know which of the calls are toplevel and which might be triggered while executing code (say, by input_to)
  noecho hook - same.
  erq stop hook - called by attach_erq_demon, is it also called at the top level?
  tls callbacks - didn't look further

Attached Files: improve-statistics.patch (2,457 bytes) 2006-06-28 12:48
http://ldmud.eu/file_download.php?file_id=87&type=bug
Notes
(0000510)
fufu   
2006-06-28 12:50   
The category is wrong. Should be 'runtime'. Sorry.
(0000651)
Gnomi   
2008-07-02 04:44   
(Last edited: 2008-07-02 05:19)
For determining whether telnet/noecho hooks are toplevel evaluations it's related to 0000534, because error handling has to be different in these cases, too.

(0000914)
fufu   
2009-01-17 08:09   
Mostly done in svn rev 2500.

A note regarding erq callbacks:
- most of the erq callbacks are asynchronous
- if triggered by attach_erq_demon, stop_erq_demon will start a new evaluation for the stale_erq calls anyway. might be worth fixing.

I still haven't looked at the TLS callbacks.
(0002577)
fufu   
2021-04-09 00:33   
(I might pick this up again, but for now I have no idea what the current state of tracking evaluations is.)
(0002580)
zesstra   
2021-04-09 09:04   
My suggestion is to close it for the time being until you want to get back to it.
(0002697)
Gnomi   
2022-10-06 22:11   
TLS callback handling should be fixed in 3.6.3 (using backend_callback() function).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
146 [LDMud 3.7] General feature N/A 2004-11-26 20:15 2022-10-06 21:48
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: confirmed Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Filenames in master calls should always start with a leading '/'
Description: This might break backwards compatibility.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001327)
zesstra   
2009-09-28 15:01   
Ok, had a look into it:

- make_path_absolute(): obviously does not get an absolute path and should not. ;-)
- include_file/inherit_file(): they get the file to be inherit/included not as absolute, because they should make them absolute, if necessary. The file currently compiled is given with absolute paths if !compat.
- compile_object(): not absolute
- get_ed_buffer_save_file_name(): not absolute
- get_wiz_name(): not absolute
- preload(): absolute paths
- privilege_violation(): seems to get only objects, although its mixed according to the manpage.
- valid_exec(): program has no leading /
- valid_read()/valid_write(): absolute path.
- runtime_error(), heart_beat_error(): curobj and curprg are not absolute.
- runtime_warning(): curobj is made absolute if !compat, but curprg not.

I just think about: another possibility than to manipulate the paths each time prior to apply_master() is to always use absolute object names and program names, not only during master applies, because that would be more consistent (e.g. you get the program in runtime_error() absolute, but in debug_info() it is not). But on the other hand, in the case of paths for reading/writing files that makes it more complicated access files in the driver...
Also, in that case, we should first get rid of the compat mode.
(0001334)
Gnomi   
2009-09-29 12:28   
We should get rid of compat mode anyway. :-)

And I'd support the idea of having a leading '/' an all absolute path names.
Most changes would affect the master only, so the compatibility is not that a problem (if we do it in 3.5). And I don't think it would complicate the driver side (you just have to use filename+1 to skip the leading '/').
(0001362)
zesstra   
2009-09-30 16:14   
You are right. But one problem is to find all the places where we use such paths and not have to add some +1 to the pointers. I am not completely convinced that that will not be a pain in the ass. But maybe someone else has better knowledge. ;-)
(0001388)
Coogan   
2009-10-01 04:47   
Getting rid of compat mode: I'm not the one who would go over 100MB area lib code and check for correct handling of absolute path names in our compat mode mudlib.
Fixing
  inherit "basic/living";
is easy with gred/sed, things like
  if (object_name(previous_object())[0..9]!="obj/player")
not. Especially occurances where a filename is computed are almost only to find by the hard way.

Lars already tried that and came to the conclusion that he'll stuck with native and !native mode.
(0001389)
Gnomi   
2009-10-01 04:58   
With a simul_efun object_name() that removes the slash there would only be the master and simul_efun to check and occurrences of efun::object_name.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
907 [LDMud 3.7] LPC Language minor N/A 2022-10-06 21:46 2022-10-06 21:47
Reporter: zesstra Platform: x86_64  
Assigned To: OS: MacOS X  
Priority: normal OS Version: 10.9.x  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Disallow addition of empty mappings with different width
Description: Currently, empty mappings with different widths can be added, e.g. widthof(([:2]) + ([:3])) is 3.
Non-empty mappings cause a runtime error.
We currently think, there are no reasonable usecases to be able to add mappings with different widths and would like to disallow them in 3.7.
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
158 [LDMud 3.3] Runtime feature N/A 2004-11-26 20:42 2022-10-06 21:28
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: confirmed Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Add driver compilation options and constants to driver_info()
Description: We need to
a) assemble a list of options/constants in config.h.in, machine.h.in, that are useful to have in LPC
b) add that to driver_info() and maybe even to configure_driver if it should be changed/is changeable.

--- historic description ---
Short: Runtime query of driver compilation options.
Date: 981114
Type: Feature
State: Proposed
Long:

The driver should offer a way to query compilation options (like MAX_BITSTRING)
at runtime, either via LPC-Predefines, or by an efun returning a mapping.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001322)
zesstra   
2009-09-28 12:12   
Ok, I agree, there should be some possibility to know things like compiletime limits. So: should they be a permanent define or should it be something query_driver()? For things which may be often used in a loop a define seems to be more reasonable. But then it breaks consistency to use a define for some things and an efun for others. For things changeable at runtime, the decision is IMHO easy: the efun.
And we would need a list of such thing. MAX_BITSTRING_LENGTH does not exist currently, but what else should be added?
(0001341)
Gnomi   
2009-09-29 13:30   
I think we settled on the name driver_info() for that efun (similar to object_info() and interactive_info()). :-)
(0001479)
zesstra   
2009-10-05 18:50   
Right, that was the name. :-)
I will start that efun with MAX_BITSTRING.

Please add suggestions about other information here.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
777 [LDMud 3.6] General minor N/A 2011-02-14 15:14 2022-10-06 20:40
Reporter: zesstra Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version: 3.6.0  
Summary: Remove memory fragmentation related configuration switches
Description: It would be nice to remove the following switches (so remove their behaviour OR remove the conditional use): USE_AVL_FREELIST, MALLOC_ORDER_LARGE_FREELISTS and MALLOC_ORDER_SLAB_FREELISTS.

As Gnomi mentioned in 0000663:0001229 we should try to measure their impact on fragmentation.
A possibility for this might be the idea sketched in 0000663:0001232.
Tags:
Steps To Reproduce:
Additional Information: http://blog.pavlov.net/2007/11/10/memory-fragmentation/
Attached Files:
Notes
(0002033)
Coogan   
2011-02-24 01:27   
In Tubmud, I did not use any of them. Which muds do use them?
(0002038)
zesstra   
2011-02-24 10:12   
Actually, they are defined by default (on 3.3.x) and not configurable by configure. ;-) (Along with SLABALLOC_DYNAMIC_SLABS, MALLOC_EXT_STATISTICS, EXT_STRING_STATS.)
(0002051)
zesstra   
2011-05-26 22:21   
(Last edited: 2022-10-06 20:40)
I created some experimental patches to create images of the usage state of the memory after garbage collections. I hope, they will give us a hint about memory fragmentation...
The code is in the branch mem_image at https://github.com/zesstra/ldmud/commits/mem_image.
To use the stuff (warning: I don' recommend it for live muds), just apply the patches in that branch / switch to the branch and run the garbage collector. The driver will then create ppm images - they are huge (3/4 or 5/8 of the allocated memory) and should be compressed ASAP (PNG are fine). Supply enough disk space! ;-)
Colour legend: free large blocks: black, allocated large blocks: red, free small blocks: lightgray, allocated small blocks: blue.
(0002054)
zesstra   
2011-05-27 10:18   
I noticed with slaballoc a rather intimate mixture of small and large block areas (e.g. isolated large blocks in the midst of small blocks), which seems to be disadvantageous, because these large blocks will probably never be joined with other large blocks when freed. Also the OS may be less effective in finding rarely used pages for swapping.
Some spontaneous ideas:
1) increase the desired slab size / small chunk size. This is for slaballoc 4KB and seems rather on the small side considering modern amounts of memory. (BTW: Should be probably a multiple of pagesize?)
2) increase the retention time for free slabs from 60s to something significantly more (they will be always free'd in during GC)
3) introduce some MB of pre-allocated small block space by default? For smalloc this is currently 3 times the small chunk size which is not much.
(0002593)
Gnomi   
2021-04-16 20:43   
We should also measure, which of both allocators (smalloc, slaballoc) performs better and then get rid of the other one.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
783 [LDMud 3.6] General minor N/A 2011-05-27 00:38 2022-10-06 20:34
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: assigned Product Version: 3.3.720  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Change documentation to explain small_min_malloc and that it is only used in smalloc
Description: MIN_SMALL_MALLOCED is used to allocate a certain amount of memory used for small blocks at boot time and reduce memory fragmentation. This is only done for the smalloc allocator, not slaballoc.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002053)
zesstra   
2011-05-27 09:40   
OK, I just noticed that MIN_SMALL_MALLOCED for slaballoc is probably not very reasonable at the moment: the allocator returns free slabs to the free large block pool, so any pre-allocated slabs at the start will be free'd shortly after.
This is good for recycling memory, but IMHO it leads to fragmentation of the large block pool. Maybe we should try to find a balance here to create larger areas of contiguous areas of small/large blocks... Some ideas:
0) How often are small block slabs free'd anyway?
1) mark any pre-allocated slabs to be not returned to the large block pool?
2) favor the creation of new small slabs adjacent to existing ones (although I am not sure how effective that is)?
3) free small slabs only when a) memory is short or b) a significant percentage of them are free?

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
730 [LDMud 3.6] General minor always 2010-02-25 15:42 2022-10-06 20:16
Reporter: zesstra Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.3  
    Target Version:  
Summary: static logon() function does not work for TLS logon callback
Description: For a standard connect logon() in the login object can be static.

If tls_init_connection() is called in connect() in the master, the call to logon() in the login object is delayed until TLS handshake finished and the logon() is called. In this case, logon() must not be static. This inconsistency is a bit annoying, especially because it is not documented.

However, because arbitrary callbacks can be defined with tls_init_connection(), we can't simply ignore any access modifiers when executing the callback.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001745)
Gnomi   
2010-02-25 16:31   
The problem should be solved by setting current_object prior to calling the callback. It should be set to the object that called tls_init_connection(), so we have to save that somewhere.

We wouldn't need that if we restricted tls_init_connection (and tls_deinit_connection) to the current object. I see no reason why it should be possible to call that on another object.
(0001746)
zesstra   
2010-02-25 16:52   
We call tls_init_connection() in the master object in connect(), clone the login object and return it from connect(). Given the documentation of TLS in the driver, that seems to be a sane way to handle things.
But this seems to be a special case, because the callback is setup into the object received from the master, while in other cases the callback is setup in tls_init_connection() itself.
So I also have no compelling reason why it should possible to specify another object.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
696 [LDMud 3.7] Compilation, Installation feature N/A 2009-10-27 16:26 2022-10-06 19:59
Reporter: zesstra Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Change some efuns to return structs
Description: LDMud recently gained the capability to return structs from efuns.

We now need to define which efuns should be changed in 3.7.x.
Ideas: driver_info (DI_TRACE), ...?

--- historic/obsolete description ---
 thought today of efuns returning structs.
Usually we return arrays, if efuns return more than one value. But struct are nice as well (nearly as fast, but typed). I could imagine it for efuns like object_info(), driver_info(), query_limits(), call_out_info() and such...

As far as I can see: returning structs is not a big problem (now that they are not optional anymore), but returning anonymous structs is not better than arrays. So, we would the type definitions for these structs independent of a specific program being loaded...

Some ideas: kind of simul_efun for structs? Or struct-preloads? Then we would have to supply the right struct types in LPC (write them on-the-fly?) or have them implicitly defined and 'inherited' by any program...
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001576)
_xtian_   
2009-11-01 04:35   
I am using the 'inherit the struct definition' in multiple programs a lot. Frankly, this is just messy. With complex inheritance trees you will easily end up inheriting the same object (the file defining the struct) many times. It's just overkill.
Then there is the question of changing the struct definition at runtime. With multiple inheritance and only partly reloading the inheritance tree, you may end up - by accident, but this happens a lot - with programs that should exchange struct-data, but are unable to do so, because one part expects variation A and another expects variation B of a struct. Never destroy an inherit with struct definitions!

Maybe a way out of here would be to make struct definitions global. Their namespaces already are.
(0001578)
zesstra   
2009-11-01 15:06   
This reloading/changing of structs in complex inherit trees seems to me the biggest obstacle as well and one reason why we don't share structs between programs at all until now.

If we introduce global structs, I would appreciate very much, if there could be global and program-bound structs...
But even then we still have the basic problem of changing/reloading structs: Suppose you have a global struct callout_s which is used by a lot of programs (which may be also often cloned). If you now reload the global callout_s and the compiler does not happen to merge the old and new struct, we have a new one. Now all existing programs must use the old struct definition and all newly loaded programs use the new one and we have the same issue...
(0002609)
zesstra   
2021-04-16 23:36   
We are still interested in this, but do not yet have a very nice idea how to implement it. But it is anyway a breaking change and we post-pone it to 3.7.
(0002685)
Gnomi   
2022-10-06 19:59   
A candidate would be get_dir() returning arrays of structs.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
664 [LDMud 3.7] General minor have not tried 2009-06-18 05:09 2022-10-06 19:48
Reporter: Gnomi Platform: i686  
Assigned To: OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: RfC: Remove compat mode
Description: The efun transfer() might be emulated by a simul-efun. But the biggest problem is, that in compat mode all file and object names don't have a leading slash.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0001223)
zesstra   
2009-06-18 05:23   
Additionally there are the differences in initialisation I think: create/reset vs. reset(0)/reset(1).
AFAIR all the stuff concerning (E)UID was controlled by strict-uids, right?
(0001224)
Gnomi   
2009-06-18 05:28   
Initialization is specified by the driver hooks (H_CREATE_*, H_RESET) and not dependent on the driver mode. And also - I think - uid handling is controlled by strict-uids, I haven't seen a dependency on the driver mode, but I might have overlooked something.
(0001225)
zesstra   
2009-06-18 05:32   
Ah, right. The table in the manpage 'native' only describes traditional behaviour. I thought, the driver still sticks to these and doesn't offer the hooks in compat mode (never used compat mode here... *g*).
(0001500)
zesstra   
2009-10-06 15:38   
Maybe we should make a list of things, which would get a leading slash?

object_name()
load_name()
program_name()
include_list()
inherit_list()
debug_info()

We may have to check restore_structs(), because the program name is encoded in the struct identifier. So we have to take care, that we can restore savefiles without leading / and savefiles with them.
(0001503)
Coogan   
2009-10-06 18:33   
You should also take get_dir() into account. I glimpsed over the entries of /doc/efun, but found nothing else, yet.
(0001509)
Bardioc   
2009-10-07 05:06   
We switched over to native mode a couple of years ago and it was not THAT complex. The native mode works perfectly well even without using euid/strict uids (even though we take advantage of them now). The main problem for us was the missing SLASH, so be previously introduced a define COMPAT_SLASH that resolved to an empty string when running in Native mode.

However, I must say, we I do not need it anymore, so lets get rid of it *grins*
(0001522)
Coogan   
2009-10-15 17:58   
traceprefix() could be another candidate: The manpage says, that internally objects are stored without the leading slash. But when called in !compat mode, one should not rely on the underlying internal storage but write the arguments like other arguments: with leading slash.
(0001899)
Coogan   
2010-09-24 19:08   
For all the above mentioned eight efuns the OUTPUT has to be checked.

The following efuns possibly accept a filename in the arguments. Their INPUT arguments have to be checked, if they have a leading '/' or not:

* attach_erq_demon()
* clone_object()
* clonep()
* environment()
* filter_indices()
* first_inventory()
* garbage_collection()
* load_name()
* load_object()
* map()
* map_indices()
* object_name()
* restore_object()
* save_object()
* sort_array()
* symbol_function()
* tell_object()
* walk_mapping()

The next list of efuns do already use a leading /, even in compat mode:
* ed()
* file_size()
* get_error_file()
* read_bytes()
* read_file()
* rm()
* tail() -- removed in 3.5 anyway
* write_bytes()
* write_file()

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
294 [LDMud 3.6] LPC Compiler/Preprocessor feature N/A 2004-11-27 00:57 2022-09-20 00:47
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.10  
Product Build: Resolution: duplicate  
Projection: none      
ETA: none Fixed in Version: 3.6.6  
    Target Version:  
Summary: Range operator in mappings
Description: Short: Range operators on 2d mappings
From: Lars
Date: 2002-05-07
Type: Feature
State: New

m = ([ "foo": 2; 3; 4, "spot": 7; 8; 9 ]);

m["spot",0..1] --> ({ 7, 8 })

It could be implemented such that m["spot",<range>] always returns a flat copy of the values in the mapping.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
753 [LDMud 3.6] General feature N/A 2010-07-18 15:14 2022-09-20 00:46
Reporter: bubbs Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.6  
    Target Version:  
Summary: Ranged mapping indexing
Description: I'd like to propose ranged mapping indexing, allowing wide mapping values to be accessed as an array. For instance;

mapping map1 = ([ "a": 1; 2; 3, ]);

printf("%Q\n%Q\n", map1["a", 0..2], map1["a", <2..]);

Additionally, it would be a natural extension to use these as l-values, so -

map1["b", 1..2] = ({ 4, 5, });

Coping mapping values from one mapping to another would become a lot easier -

map2["c", ..] = map1["a", ..];

As for the closure versions of these operators, I'd suggest reusing the existing ranged closures (#'[..], #'[<..], #'[..<], #'[<..<]), accepting an additional argument as the mapping key -

funcall(#'[..], map1, "a", 0, 2) == map["a", 0..2]);


I think this would be a logical extension to the language, making wide mappings easier to manipulate. However, I understand how much time these things take and I'd like to express my gratitude for the work being done and to all contributors.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001888)
Gnomi   
2010-07-22 02:55   
Interesting idea. I'd like to do this, but after 0000546 is finished, otherwise we might code it twice.
(0002602)
fufu   
2021-04-16 22:01   
The closures should get new names, #'[,..], #'[,<..], etc. (This is consistent with the existing #'[,]).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
902 [LDMud 3.6] Runtime crash always 2022-01-11 03:23 2022-09-20 00:46
Reporter: paradox Platform: Linux  
Assigned To: Gnomi OS: Ubuntu  
Priority: normal OS Version: 20.04  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.6  
    Target Version:  
Summary: LDMud 3.6.5 python initialization time object reference crash
Description: With LDMud 3.6.4 with Python support compiled in it was possible to have a `--python-script` argument that used `import ldmud; ldmud.Object("/some/path.c")` to get a reference to an LPC object, even while the early driver initialization is occurring and the master object is not available.

With LDMud 3.6.5 the same Python startup script causes a reliable segfault. In "Steps to Reproduce" I've included a built binary and core dump from a representative segfault.

This appears to be due to a the `current_ob` being `NULL` before master has been initialized. This in turn causes a call to `ldmud_object_create` to use `NULL` as an argument to `ref_object`, causing a panic.

Here is a GDB session with a backtrace:
```
mud@windmill2:~/dunenextnext/ldmud-3.6.5/test$ gdb --args ../src/ldmud -u-1 -E 0 --no-compat -e -N --cleanup-time -1 --reset-time -1 --max-array 0 --max-callouts 0 --max-bytes 0 --max-file 0 -s-1 -sv-1 --hard-malloc-limit unlimited --min-malloc 0 -ru0 -rm0 -rs0 --no-strict-euids --no-wizlist-file --check-refcounts --check-state 2 --access-file none --access-log none -f test --python-script startup.py -Mmaster -mt-python 65432 --debug-file ../log/result.t-python.log
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation tgresources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ../src/ldmud...
warning: File "/home/mud/dunenextnext/ldmud-3.6.5/src/ldmud-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
To enable execution of this file add
    add-auto-load-safe-path /home/mud/dunenextnext/ldmud-3.6.5/src/ldmud-gdb.py
line to your configuration file "/home/mud/.gdbinit".
To completely disable this security protection add
    set auto-load safe-path /
line to your configuration file "/home/mud/.gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual. E.g., run from the shell:
    info "(gdb)Auto-loading safe path"
(gdb) run
Starting program: /home/mud/dunenextnext/ldmud-3.6.5/src/ldmud -u-1 -E 0 --no-compat -e -N --cleanup-time -1 --reset-time -1 --max-array 0 --max-callouts 0 --max-bytes 0 --max-file 0 -s-1 -sv-1 --hard-malloc-limit unlimited --min-malloc 0 -ru0 -rm0 -rs0 --no-strict-euids --no-wizlist-file --check-refcounts --check-state 2 --access-file none --access-log none -f test --python-script startup.py -Mmaster -mt-python 65432 --debug-file ../log/result.t-python.log
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
2022.01.11 02:10:38 LDMud 3.6.5 (3.6.5-1-gd8f1ef68) (development)
2022.01.11 02:10:38 Seeding PRNG from /dev/urandom.
2022.01.11 02:10:38 TLS: (OpenSSL) x509 keyfile '/home/mud/dunenextnext/certs/privkey.pem', certfile '/home/mud/dunenextnext/certs/fullchain.pem'
2022.01.11 02:10:38 TLS: (OpenSSL) X509 certificate from '/home/mud/dunenextnext/certs/fullchain.pem': B3:99:2B:EC:AD:C2:AE:1C:E6:64:C1:34:97:69:F6:C8:65:63:6F:21
2022.01.11 02:10:38 TLS: (OpenSSL) trusted x509 certificates from '/home/mud/dunenextnext/certs/fullchain.pem'.
2022.01.11 02:10:38 TLS: Importing built-in default DH parameters.
2022.01.11 02:10:38 mySQL 8.0.27

Program received signal SIGSEGV, Segmentation fault.
ldmud_object_create (ob=0x0) at pkg-python.c:2943
2943 self->lpc_object = ref_object(ob, "ldmud_object_create");
(gdb) bt
#0 ldmud_object_create (ob=0x0) at pkg-python.c:2943
0000001 0x000055555565beca in svalue_to_python (svp=0x7fffffffc710) at pkg-python.c:9322
0000002 python_save_contextvar_value (contextvar=0x5555557b9c08 <python_contextvar_current_object>,
    name=0x5555556c9dbd "ldmud.current_object", object=...) at pkg-python.c:9832
0000003 python_save_context () at pkg-python.c:9857
0000004 0x0000555555660fc5 in python_call_hook_object (hook=1, is_external=<optimized out>, ob=0x7ffff6440b80)
    at pkg-python.c:10410
0000005 0x0000555555619b4a in init_object_variables (ob=ob@entry=0x7ffff6440b80, templ=templ@entry=0x0) at object.c:494
0000006 0x000055555566ed22 in load_object (lname=lname@entry=0x7ffff644ad20 "a", create_super=create_super@entry=false,
    depth=depth@entry=0, isMasterObj=isMasterObj@entry=false, chain=chain@entry=0x0) at simulate.c:2236
0000007 0x000055555566c443 in lookfor_object (str=<optimized out>, bLoad=bLoad@entry=true) at simulate.c:2538
0000008 0x0000555555651a25 in ldmud_object_init_getobject (num_arg=num_arg@entry=0, data=data@entry=0x7fffffffcaa0)
    at pkg-python.c:2600
0000009 0x000055555565c0e9 in call_lpc_secure (fun=fun@entry=0x555555651a10 <ldmud_object_init_getobject>,
    num_arg=num_arg@entry=0, data=data@entry=0x7fffffffcaa0) at pkg-python.c:9759
0000010 0x000055555565c59a in ldmud_object_init (self=0x7ffff5de3540, args=<optimized out>, kwds=<optimized out>)
    at pkg-python.c:2632
0000011 0x00007ffff6edd199 in ?? () from /lib/x86_64-linux-gnu/libpython3.8.so.1.0
0000012 0x00007ffff6f3cafb in _PyObject_MakeTpCall () from /lib/x86_64-linux-gnu/libpython3.8.so.1.0
0000013 0x00007ffff6d08df3 in ?? () from /lib/x86_64-linux-gnu/libpython3.8.so.1.0
#14 0x00007ffff6d10ef6 in _PyEval_EvalFrameDefault () from /lib/x86_64-linux-gnu/libpython3.8.so.1.0
#15 0x00007ffff6e5eecb in _PyEval_EvalCodeWithName () from /lib/x86_64-linux-gnu/libpython3.8.so.1.0
#16 0x00007ffff6e5f252 in PyEval_EvalCodeEx () from /lib/x86_64-linux-gnu/libpython3.8.so.1.0
#17 0x00007ffff6e5f63f in PyEval_EvalCode () from /lib/x86_64-linux-gnu/libpython3.8.so.1.0
#18 0x00007ffff6e200dc in ?? () from /lib/x86_64-linux-gnu/libpython3.8.so.1.0
#19 0x00007ffff6e21a47 in PyRun_SimpleFileExFlags () from /lib/x86_64-linux-gnu/libpython3.8.so.1.0
#20 0x000055555565faf6 in pkg_python_init (prog_name=<optimized out>) at pkg-python.c:9987
#21 0x0000555555571b52 in main (argc=<optimized out>, argv=0x7fffffffe158) at main.c:581
```
Tags:
Steps To Reproduce: You can download a core and a binary from https://binaryparadox.net/d/3.6.5.pyinit.segfault.tar.gz

It's also very easy to reproduce. Simply add a `.c` file to your lib, and have the Python script you pass to `--python-script` reference it from the top level package init context with `ldmud.Object("/path/to/ob.c")`. This will cause a segfault at game start.

Additional Information: I have a unit test that reproduces the crash as well as a fix to consider. I'll open a PR with both and leave a comment here with the URL in a moment.
Attached Files:
Notes
(0002674)
paradox   
2022-01-11 03:26   
Here's a branch with a unit test that reproduces the crash, and a potential fix to consider: https://github.com/ldmud/ldmud/pull/69

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
903 [LDMud 3.6] Efuns trivial always 2022-01-12 04:15 2022-09-20 00:46
Reporter: gorgar Platform:  
Assigned To: Gnomi OS:  
Priority: low OS Version:  
Status: resolved Product Version: 3.6.5  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.6  
    Target Version:  
Summary: unique_array throwing debug error
Description: This efun will throw this error if the first argument is empty or not, and if the second argument (a string) is not a defined function in the calling object. Seems strange, why should the calling object need the function defined?

> lpc unique_array( ({}), "short")
LPC result: ({ })

debug log:
2022.01.11 22:02:19 Function short() not found in /players/gorgar/tmp_code0.
2022.01.11 22:02:19 program: players/gorgar/tmp_code0.c, object: players/gorgar/tmp_code0 line 21
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
904 [LDMud 3.6] Runtime crash always 2022-02-27 19:56 2022-09-20 00:45
Reporter: paradox Platform: Linux  
Assigned To: Gnomi OS: NixOS  
Priority: normal OS Version: 21.11  
Status: resolved Product Version: 3.6.5  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.6  
    Target Version:  
Summary: LWO to LWO bad call_other causes SIGABRT
Description: Using `efun::call_other` from an LWO, on an `ob` target that is itself an LWO, specifying a `fun` that does not exists causes LD to catch a SIGABRT from `interpret.c` failing an assertion:

```
ldmud: interpret.c:14379: eval_instruction: Assertion `sp[-1].type == T_ARG_FRAME' failed.

Thread 1 "ldmud" received signal SIGABRT, Aborted.
```
Tags:
Steps To Reproduce: I have a branch (https://github.com/ldmud/ldmud/compare/master...dune-mud:cpu-py-lwo-crasher?expand=1) that adds a very small unit test to `t-python` that reproduces the issue reliably.
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
897 [LDMud 3.6] LPC Language feature N/A 2021-10-06 00:17 2022-09-20 00:45
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: MacOS X  
Priority: normal OS Version: 10.9.x  
Status: resolved Product Version: 3.6.4  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.6  
    Target Version:  
Summary: Support global struct definitions via simul_efun object
Description: It might be useful to support introducing struct definition via the simul_efun object. Some commonly used structs need not to be inherited explicitly and sefuns could accept or return structs.
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0002661)
paradox   
2021-10-17 22:35   
Chiming it to say I've been enjoying using structs but have also found the inheritance model awkward for things like in-lib structs to accompany MUD-wide functionality (Python simuls for things like HTTP in particular!).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
285 [LDMud 3.6] Runtime feature N/A 2004-11-27 00:50 2022-09-20 00:45
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.10  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.6  
    Target Version:  
Summary: Deactivate sefuns (when loading the master)
Description: Short: Deactivate sefun (when loading the master or on pragma)
Date: Thu, 21 Mar 2002 12:01:33 -0700
From: Lars Duening <c-lars.duening@wcom.com>
Type: Feature
State: New

When reloading the Master, deactivate all sefuns.

Also:

#pragma no_simul_efuns

schaltet die Verwendung von allen simul-efuns ab. Automatisch definiert fuer
master und simul_efun haupt-object, sollte es auch in allen inheriteten
Modulen verwendet werden.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000236)
_xtian_   
2004-12-07 06:59   
Yes! Just happens too often that the MUD doesn't come up because of this and nobody noticed for weeks. ;)
(0000385)
Gnomi   
2005-08-29 04:06   
I agree, it's a good idea. But this pragma should not allow to circumvent nomask simul-efuns, so master->privilege_violation should be asked about it.
(0002011)
zesstra   
2011-02-20 01:49   
In Januar we had a crash in Morgengrauen during reloading of the sefuns. The simul_efun object was not loadable (the backups were). The error handler of the master used (indirectly) a sefun which caused a recursive try to load the sefuns. We also had an autoinclude-Hook which used a sefun as well (*cough*)...

I was wondering if it is possible to deactivate calls to sefuns not only for the a specific program, but in general during loading the master and sefuns.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
896 [LDMud 3.6] Implementation minor always 2021-10-06 00:14 2022-09-20 00:44
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: MacOS X  
Priority: normal OS Version: 10.9.x  
Status: resolved Product Version: 3.6.4  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.6  
    Target Version:  
Summary: struct literals and to_struct() should check types at runtime
Description: When creating structs with literals or by to_struct(), the types of values should be checked for compatbility with the struct definition when the pragma rtt_checks is active.
These checks are currently missing in the implementation of F_S_M_AGGREGATE and v_to_struct().
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
906 [LDMud 3.7] Runtime feature always 2022-04-28 22:29 2022-04-28 22:29
Reporter: Gnomi Platform: i686  
Assigned To: OS: Debian GNU/LInux  
Priority: normal OS Version: 5.0  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Revise default-initialization of float variables
Description: TLDR: Initialize floats with integer 0 and prevent arithmetic on this value with RTTCs.

Since LDMud 3.2.11 and 3.3.585 floats are default-initialized with 0.0, whereas all other types are initialized with 0. This brings some inconsistent behavior:
  T var;
  if (!var) { write("Uninitialized.\n"); }

For all T (like string, or float|closure) this will print the string, but not for T = float.

The reasons for the change are unknown. This might have been a suggestion for more intuitive behavior in the following cases or just preventing type inconsistencies there:
    float var;

    return (var + 1) / 2
    var++;
    var += 2;

Previously those expressions would have resulted in 0, 1, 2 as integers, now the result is 0.5, 1.0 and 2.0 as floats.

The change hides an underlying problem with doing arithmetic on the default-zero. In the above example we could initialize var explicitly with 0 and get the old behavior,
thus violating the type restrictions. Also the following code still "works" in LDMud 3.6.5:
    
    string var;
    var+=2;

And results in var being 2.

So in order to remove the default-initialization to 0.0, we need to have a different solution for the arithmetic. Let's start with getting the semantics right.
   
Do we want to do automatic conversion on assignment:
   string var = 2; // Error or "2"?
   float var = 2; // Error or 2.0?
I would vote 'no', otherwise 'string var = 0;' becomes a tricky case. Also it makes runtime behavior very dependent on the knowledge about the type (so pragma save_types might have a heavy influence) and union types will complicate matters.
   
Do we want to do automatic conversion on usage:
   float var;
   return (var + 1) / 2; // 0 or 0.5?
Same argument is before: Making runtime behavior dependent on the knowledge of the type seems a bad idea.

Combination of the above questions for +=:
   string var;
   var += 2;

   float var;
   var += 2;
This should have the same meaning as 'var = var + 2;', so it depends on the previous answers.

So in the end I would suggest to:
1. Remove the 0.0 initialization
2. Add RTTC checks to ++, --, +=, -=

But this would break stuff and would only be detectable at runtime...
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
892 [LDMud 3.6] Networking minor always 2021-04-17 02:49 2022-01-09 21:36
Reporter: fufu Platform:  
Assigned To: fufu OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.5  
    Target Version:  
Summary: Newline characters may be lost in switch to INPUT_CHARMODE handling
Description: Assume we want to read some data, a line of text followed by a single character:

  ... input_to("fun1"); ...
  fun1(string str) { input_to("fun2", INPUT_CHARMODE); }
  fun2(string str) { ... }

If we send "a\n\nb" to the server in one packet, then "fun2" will never be executed. What happens under the hood is a bit convoluted:

  1. get_message() receives 4 bytes of data, passes this off to telnet_neg() (comm.c line 2836), which consumes 2 bytes of data and prepares a line containing "a" in the command buffer
  2. still in get_message(), the command buffer is copied to the output buffer and then telnet_neg() is invoked again to "reinitialize the telnet machine" (comm.c line 3000). Note that we're still in line mode, so the newline is consumed and an empty line is prepared in the command buffer.
  3. the first input_to() completes, the second is issued.
  4. in get_message(), now we're in char mode, and the code will see that the telnet state machine is ready, and then fail to extract a character (comm.c line 2892). Nothing happens; we're stuck in this state forever.
Tags:
Steps To Reproduce: I'll attach a testcase.
Additional Information:
Attached Files: t-0000892.c (1,052 bytes) 2021-04-17 02:50
http://ldmud.eu/file_download.php?file_id=298&type=bug
Notes
(0002622)
fufu   
2021-04-17 02:50   
(0002623)
fufu   
2021-04-17 03:00   
There are quite a few things that are odd about this:

- telnet_neg() gets ahead of the data the driver has actually consumed
- telnet_neg() is responsible for stripping newlines for line mode input
- NUL is somehow treated as a newline character
- as far as I can see, charmode reads can never recover from that empty command buffer state; arguably they should try to get more input if that state ever occurs

Changing either of the first two points should solve the issue at hand. But they both feel wrong to me.
(0002624)
zesstra   
2021-04-17 09:55   
(Last edited: 2021-04-17 09:59)
The telnet convention concerning end-of-line is kind of difficult. There are some clients, that do not send the usual CR LF sequence, but CR NUL as EOL sequence. I could imagine, this being related to treating NUL as EOL.
This document also discusses EOL stuff and mentions that in character mode CR will be passed to the application when in "raw mode" - maybe your NUL was CR NUL and only the NUL remained for interpretation?
https://www.freesoft.org/CIE/RFC/1123/31.htm
(Originally, the idea behind CR NUL seems to be to send only a CR, but I guess, at some point the implementations interpreted that as EOL, because some clients never sent CR LF.)

BTW: could you try to switch to BINARY mode - this may enable yet another combination of problems with EOL. (e.g. I noticed that Tinyfugue in BINARY LINEMODE with a current driver will change the line, but not perform the carriage return... But no idea if that is our fault or TF).

Jof, how I wish we could leave stuff like this to a library!
(0002625)
Gnomi   
2021-04-18 20:26   
I tried to get rid of the second telnet_neg() call in get_message() a few years ago. (I found it odd and just removed it.) And then something broke. I don't know the details anymore, but the second call was somehow important. Maybe we could try to move it to the top of the function, before the select call.

I think it's correct that telnet_neg() does the newline stripping as newlines are part of the telnet protocol. There is information about that in the state (TS_READY: newlines were stripped, TS_CHAR_READY: they weren't). I would argue, that it is a mistake, that TS_READY occurs in charmode. This also points to postponing the second telnet_neg() call.
(0002626)
fufu   
2021-04-18 20:33   
See also https://github.com/ldmud/ldmud/pull/61
(0002627)
fufu   
2021-04-18 20:36   
@Gnomi, indeed that second call to telnet_neg() was odd, but that was because telnet_neg() served two purposes, 1) reset the telnet machinery after processing a line/character of input and 2) advance the telnet negotiations until the next line of input is available. The patch I produced splits it into two functions for that reason.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
898 [LDMud 3.6] General minor N/A 2021-10-17 21:51 2022-01-09 21:35
Reporter: paradox Platform: N/A  
Assigned To: Gnomi OS: N/A  
Priority: normal OS Version: N/A  
Status: resolved Product Version: 3.6.4  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.5  
    Target Version: 3.6.5  
Summary: Provide line number as an argument to master's log_error lfun hook.
Description: Presently, the `log_error` lfun called in master for compiler errors and warnings uses the function signature:

```
void log_error(string file, string err, int warn)
```

The "err" argument most typically[0] is a string that includes the file at fault, the error line number, and some context:
```
sprintf(buff, "%s line %d%s: %s\n", error_file, line, context, what);
```

I would like to be able to access the line number _without_ having to parse the "err" string. This closer matches the `runtime_error` and `runtime_warning` hooks that receive the line number as one of the arguments to the master `lfun` called by the driver.

[0]: https://github.com/ldmud/ldmud/blob/cf009941c0aefa593dc353fe62d938a3b0b4bcb5/src/simulate.c#L1399
Tags:
Steps To Reproduce: Compile an LPC file with warnings or errors, observe that `log_error` in master.c is called, but without providing a line number argument.
Additional Information:
Attached Files:
Notes
(0002660)
paradox   
2021-10-17 22:08   
If you're interested in helping a driver neophyte implement this themselves I'd be willing to try and to submit a PR. If you have any notes on "gotchas" I should watch out for (thinking in particular, for legacy instances not expecting this argument) that would be helpful!
(0002662)
paradox   
2021-10-22 23:35   
I've put up a "draft" PR here: https://github.com/ldmud/ldmud/pull/63

I think the main missing piece is test coverage. I will look at that next, advice welcome!

I did some quick manual testing to ensure that this patch still worked on a driver that had a master ob that didn't expect the new argument to its `log_error` function and saw no problems. I also tested that a master ob that _did_ expect the new argument got the right value and it seemed to be working correctly.
(0002663)
paradox   
2021-10-23 00:16   
> I think the main missing piece is test coverage. I will look at that next, advice welcome!

I made a basic unit test (https://github.com/ldmud/ldmud/pull/63/commits/fcdf4fca5238a1fc2f26fecc00f2d106d83f6e41) that appears to pass locally when I run it. If there's some other test configurations to consider I'm happy to try!
(0002673)
paradox   
2022-01-08 22:50   
This was resolved by Gnomi merging https://github.com/ldmud/ldmud/commit/7f14d6028d7b8ab5f5f1955b739f2464660dbca8 to master.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
529 [LDMud 3.6] Efuns minor always 2008-01-31 08:22 2022-01-09 21:35
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3.713  
Product Build: 3.3.714-2314 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.5  
    Target Version:  
Summary: sprintf's column mode misplaces a newline
Description: sprintf("%-=4s\n%s", "A B\n","X\n") returns "A B\n\nX\n", which seems correct.

But sprintf("%-=4s\n%s", "A B C\n","X\n") returns "A B\nC\nX\n\n". There one of the '\n' at the end should occur between the 'C' and 'X'.

Greetings,
Gnomi.

Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
665 [LDMud 3.6] Efuns minor always 2009-06-18 17:12 2022-01-09 21:34
Reporter: garapol Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.5  
    Target Version:  
Summary: sscanf and %% don't like each other
Description: sscanf(str, fmt, junk, junk2)
does not work correctly for some of the following:

      str | fmt | result | should result
----------+------------+--------------+---------------------
te%st | %s%%%s | (te, 0) | (te, st)
%%s | %s%%%s | (%, 0) | (%, s) oder (0, %s)
s%%%%%t%% | %s%%t | s%%%% | 0
s%%%%% | %s%% | s | s%%%%
s% | %s%% | s | s (Ok)
%%s | %%%s | %s | %s (Ok)
%s | %%%s | s | s (Ok)

BTW: In efun.c the sscanf-code have some gotos. ;-)


Garapol Leckerlin (@Avalon)
Tags:
Steps To Reproduce:
Additional Information: I don't know wether other format strings may have bugs, too. I only saw these for %%.
Attached Files:
Notes
(0002572)
Gnomi   
2021-04-08 19:37   
I don't agree with the 3rd and 4th case:

sscanf("s%%%%%t%%", ""%s%%t", x) should yield "s%%%" instead of 0.
sscanf("s%%%%%", "%s%%", x) can yield "s".

sscanf() is never required the match the whole input string. Therefore "s%%%" is valid result in the first case, because for %s it is only required that the following characters match as well (%t), which they do. In the second case "s" is also a valid result, because the following characters (in this case "%") match.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
198 [LDMud 3.6] Efuns tweak N/A 2004-11-26 22:38 2022-01-09 21:34
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.8 and before  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.5  
    Target Version:  
Summary: sprintf() on code closures
Description: Short: sprintf() on non-efun-symbols
From: Lars Duning <lduning@peopledoc.com>
Date: Wed, 03 Mar 1999 13:32:34 +0000
Type: Feature
State: Unclassified.

sprintf("%O", #'({) -> "#'aggregate", but should be "#'({"
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
332 [LDMud 3.6] General trivial always 2005-01-03 13:02 2022-01-09 21:33
Reporter: randalar Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.5  
    Target Version:  
Summary: Warning: Missing 'return <value>' statement.
Description: While I find the warnings regarding no return statements quite useful, it seems to not always grasp what the function is doing, and gives warnings when I would rather it not :) Here is an example:

int my_func(string s)
{
    if (!s)
        return 0;

    switch(s)
    {
        case "this": return 1;
        case "is" : return 2;
        case "a" : return 3;
        case "test": return 4;
        default : return -1;
    }
}

this causes a warning to be generated. However, I can add one line and the warning goes away:

int my_func(string s)
{
    if (!s)
        return 0;

    switch(s)
    {
        case "this": return 1;
        case "is" : return 2;
        case "a" : return 3;
        case "test": return 4;
        default : return -1;
    }
    return -1;
}

Should I always put in redundant return statements? (Of course, I may be missing something obvious that doesn't make this redundant :))
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000283)
lars   
2005-01-03 22:57   
This is a limitation caused by the single-pass nature of the LPC compiler: this particular check doesn't do proper control flow tracing, but instead checks the last generated bytecode. I'm afraid the only resolution at the moment is to enter additional returns.

At least I can say that the LPC compiler is not alone in this kind of limitation: one of the compilers I use at work tends to complain about uninitialized variables even if the control guarantees that the initializer will be executed.
(0000284)
randalar   
2005-01-04 07:55   
Ah, thanks for the explanation. I appreciate it. :)
(0000447)
hkremss   
2005-12-06 10:07   
(Last edited: 2005-12-06 10:23)
We have the same problem for many files using switch(). Maybe this issue will be 'fixed' some day, here is another suggestion:

If the switch() has a default: case with return, the code below the switch() is unreachable and should generate a warning too. Knowing, that all changes now to avoid this warning would lead to 'unreachable code warnings' in future, but this is the right behaviour in my eyes.

But I understand, that the LPC compiler is not able to handle this at the moment. It depends on the order of 'case' and 'default' too and maybe other issues. We just found the pragma to switch it off. This should be OK. Thanks.

(0000463)
fufu   
2006-01-01 04:11   
re: hkremms

it's not that simple because you can break out of a switch with break;
also the default: branch is not necessarily the last one in the switch.

you'd really have to build a control flow graph to handle this properly.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
726 [LDMud 3.6] General feature N/A 2010-02-20 16:42 2022-01-09 21:32
Reporter: sinnvoll Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.5  
    Target Version:  
Summary: in - Operator
Description: At the moment after member_array and member I have to look up,
which parameter of member comes first.

if(array_member in array) do_something();
if(character in char_string) do_something_else();
if(key in map) do_something_completely_different();

An infix operator 'in' would be more readable and intuitive.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
800 [LDMud 3.6] General major always 2012-01-08 02:17 2022-01-09 21:32
Reporter: clutch Platform: Linux  
Assigned To: Gnomi OS: CentOS  
Priority: normal OS Version: 5.7  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.5  
    Target Version: 3.5.0  
Summary: (s)printf truncates when using a 0 in the string
Description: This is similar to problem 472. When inserting a 0 into a string using sprintf("%c",0) causes problems later using (s)printf.

Tags: sprintf
Steps To Reproduce: lpc printf("Does not print after %-=30s, really!",sprintf("asd%casd",1>0?0:'s'))
Additional Information: We are running LD 3.5 pulled from the latest github.
Attached Files:
Notes
(0002097)
zesstra   
2012-01-08 16:55   
Interestingly the error does only happen in column mode.
(0002098)
zesstra   
2012-01-10 00:12   
Additional information/examples:

# printf("asd%casd",0) -> prints "asdasd"
-> works
# sprintf("asd%casd",0) -> returns "asdasd"
-> works
# string str=sprintf("asd%casd",0);printf(str); -> prints "asd"
-> fails

# sprintf("Does not print after %20s, really!",sprintf("asd%casd",0))
-> works
# sprintf("Does not print after %=20s, really!",sprintf("asd%casd",0))
-> fails

At least for the last two: column mode (add_column()) seems to use \0 as termination char for columns.
(0002099)
zesstra   
2012-01-10 00:18   
(Last edited: 2012-01-10 09:32)
As Paradox@Dune just noted:
# string str=sprintf("asd%casd",0);printf("%s",str); -> prints "asdasd"
-> works.
So the format string should not contain \0, the string argument can, unless in column mode.
One error in column mode and one error somewhere else.


View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
780 [LDMud 3.6] General tweak always 2011-02-19 22:51 2022-01-09 21:31
Reporter: sinnvoll Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.5  
    Target Version:  
Summary: Seltsame float 0,
Description: zlpc return 0.; Got=0
zlpc return !0.; Got=0
zlpc return 0.==0 Got=1
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002004)
zesstra   
2011-02-19 23:28   
Ok, concerning example 1:
zlpc in UNItopia uses to_string() for output of floats. to_string() uses "%g" in sprintf() to print T_FLOAT. And the sprintf manpage states: "a decimal point appears only if it is followed by at least one digit."
I think, we have to include that comment as well in our manpage of to_string - or change it in a way to print the same as our sprintf("%d")...

Note: Our %d in sprintf does not behave the same: 0.0 is printed as "0.0".

Example 2:
Basically, 0.0 is not equal 0, so !0. == 0 is in general justified. It just looks contradictory to Example 3.

Example 3:
The F_EQ (==) operator converts T_NUMBER into double before comparing them with == with the T_FLOAT argument, therefore the comparison returns true...
(0002005)
zesstra   
2011-02-19 23:56   
Sin suggested to document the special meaning of 0 (e.g. assignable to every type, initialization value for any type, but despite this always an integer) and its implications.
(0002022)
Gnomi   
2011-02-22 00:10   
Hmm, I think example 2 should return 1. !x should be the same as x == 0.
(0002614)
Gnomi   
2021-04-17 00:07   
Although we don't like the current behavior, we hesitate to change it, because one cannot detect where it will break existing code.
Therefore we decided to issue warnings, whenever floating point numbers are used in a boolean context and pragma warn_deprecated is in effect.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
900 [LDMud 3.6] Runtime crash have not tried 2021-12-28 04:19 2022-01-09 21:31
Reporter: gorgar Platform:  
Assigned To: Gnomi OS:  
Priority: low OS Version:  
Status: resolved Product Version: 3.6.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.5  
    Target Version:  
Summary: too many local variables defined
Description: This is a mudlib file inherited by other mudlib files. I just defined too many local variables in the function and updated the file.
I would not have expected this to crash.
Did not produce a core.
Have not attempted to reproduce.

2021.12.27 22:08:21 obj/modules/responses.c line 319: Too many local variables before ' (int) who'.
[xerq] read: Success
2021.12.27 22:08:22 [xerq] Demon exiting.
Tags:
Steps To Reproduce: See above.
Additional Information:
Attached Files:
Notes
(0002665)
gorgar   
2021-12-28 04:26   
Update: reproduces easily. does not have to be this mudlib file. never produces a core.
(0002666)
Gnomi   
2021-12-28 17:13   
Fixed in https://github.com/amotzkau/ldmud/commit/d609d1ea40547fb88425f31b3a5c64df7d41abed

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
842 [LDMud 3.6] LPC Language feature N/A 2015-08-07 07:21 2022-01-09 21:30
Reporter: Bardioc Platform:  
Assigned To: Gnomi OS:  
Priority: low OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.5  
    Target Version:  
Summary: Extend type saftey by adding class-name annotations to type 'object' for parameters and variables
Description: While taking advantage of the new runtime type checks of LDMud 3.5.0.3, I've removed certain type checks we have implemented in methods during the years. While simply type checks are no longer necessary, I've came across a specific version. Let me explain this using an example:

public int make_em_die(object liv)
{
    check(liv, ({ IS_OBJECT, "/class/living/living" }))

    // make em actually die
}

I cannot remove this check here, as it is kind of an assertion that after the check line, 'liv' is supposed to be an instance of "/class/living/living". If someone calls this function with something else than an object that inherits "/class/living/living" the caller will get an error raised in the form:

Bad argument 1 to make_em_die(): expected 'instance of '/class/living/living''.

How about introducing something like the following within the driver that must be easily able to check this inheritance:

public int make_em_die(object["/class/living/living"] liv)
{
   // make em actually die
}

One could do this for variables too:

{
    object["/class/living/living"] liv = clone_object("/class/item/base/torch")
    // -> outch ... Wrong instance
}

What do you think of this? It would remove lots of checks in the mudlib code that needs to verify of the correct object has been given or created.

Regards,

Heiko aka Bardioc@Evermore
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002277)
abathur   
2016-06-20 23:46   
(Last edited: 2016-06-20 23:48)
Just a few different thoughts/questions:

- Do you see benefits beyond just having this in core syntax? The syntax you suggest is shorter than your example, but it seems like you could also just define and use a simul_efun "require_living(liv)" and abstract that logic out without littering the mudlib with fixed paths?

- It seems like elevating this sort of object-identity test (versus an object functionality test) to core syntax might encourage some unfortunate over-restriction by suggesting these restrictions are a best practice? The syntax might, for example, inspire someone to make their container in/out functions require "treasure" objects, in the process making it so that a builder down the road would have to create new commands in order to build their dream quest where players have to smuggle Muffins the friendly gnome (an npc) through a guard post in their backpacks.

- In 0000817 I suggested bringing decorators to LPC; it doesn't look like we'll see them in the short term, but they could make for an interesting syntactical compromise that could enable the use of an lfun or sefun (or perhaps even an efun...) in a way that more clearly communicates that it is a precondition:

@require_living
public int make_em_die(object liv){...}

- I was pondering the syntax you suggest for ways to shorten it, and I realized there's already a template here in how structs are handled. One alternative might be some sort of "object declaration" syntax along the lines of the struct and function declaration syntaxes, with the ability to create a short name that could fit into the same syntax idiom structs already use.


View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
688 [LDMud 3.6] General feature always 2009-10-05 09:32 2022-01-09 21:30
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.5  
    Target Version:  
Summary: Lightweight objects
Description: Implement support for lightweight objects.

Lightweight objects would be objects that don't have a name, don't have all the load normal objects have (inventory, environment, shadows, actions), they can be created really fast and are destroyed automatically when all references to them are gone.

How this can be implemented in the language and runtime is to be discussed (with LPC files like normal objects, attaching functions or an master to a datastructure are something completely different).
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
882 [LDMud 3.6] LPC Compiler/Preprocessor feature N/A 2020-08-07 11:36 2022-01-09 21:29
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: GNU/Linux  
Priority: normal OS Version: 0  
Status: resolved Product Version: 3.6.2  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.5  
    Target Version:  
Summary: Warning about applied lfuns being implemented with incompatible signature
Description: In MG we currently have a discussion if the compiler should warn/abort when an lfun, that the driver applies (i.e. it is part of the Mudlib<->Driver-API), is defined in an incompatible way.

This would require to check for the hard-coded applies, but also the configured driver hooks (at the time of compilation).
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0002543)
Gnomi   
2020-08-07 12:37   
I think the only hardcoded applied lfuns (in non-compat mode) are in the master object. Compat mode has some hardcoded applies for normal objects, too.
All the others are configurable via driver hooks.

This is doable nevertheless, the compiler knows if it is compiling a master object and can use the current configuration for the other objects. But it would also check for functions even if they would never apply, for example H_MODIFY_COMMAND_FNAME even if the object never enables commands.
(0002544)
zesstra   
2020-08-07 16:00   
I think, that would be acceptable. But we need a suitable pragma for it, I guess.
(0002545)
Gnomi   
2020-08-07 22:45   
What would be an incompatible definition? Only cases where the runtime type checks would throw errors? (Parameters of incompatible types?) Would a wrong number of parameters be criticized (currently it's not a problem)? Would another return type be a problem (for some applies the driver expects an integer, and treats all other types as the answer 'no', but doesn't raise an error)? Should visibility be a concern? (The applies can be static or protected, but not private. A private definition is just ignored, should the driver warn about that?)
(0002547)
zesstra   
2020-08-15 23:23   
Mhmm. I think, there two use cases:
a) prevent a definition, that causes runtime errors later.
b) warn about wrong usage (e.g. forgetting that this function will have special meaning)

I think for b) it would be good to warn about the wrong number of arguments and a wrong return type. Therefore I would also warn about private definitions.
(0002548)
zesstra   
2020-08-15 23:25   
Addition, why b) would be relevant: The recent crash in clean_up in MG was because the programmer forgot about the clean_up mechanism and just used a function named clean_up for something completely else. There it seems to happen. ;-)
(0002549)
Gnomi   
2020-08-17 11:51   
Then I would think about two pragmas (warn_applied_functions, warn_applied_functions_strict?). The first one would warn about incompatible types and the second one about everything. The pedantic pragma would make them errors.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
782 [LDMud 3.6] Runtime crash always 2011-04-28 16:04 2022-01-09 21:29
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/LInux  
Priority: normal OS Version: 5.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.5  
    Target Version:  
Summary: Closures for simul-efuns with an index > 2047 crash the driver
Description: For efun, operator or simul-efun closures the efun, operator resp. simul-efun index is stored as the secondary type information. For each of these three types there are 2048 values reserved.

For simul-efuns with an index beyond 2047 closures with illegal secondary type information will be created resulting in a crash.

One solution would be to create alien lfun closures for such simul-efuns instead. As another solution the simul-efun index could be moved into the .u value (but then we would need to store the object pointer and the simul-efun index which wouldn't fit into a p_int, so we would need to allocate another memory block for that).
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0002050)
Gnomi   
2011-04-28 16:18   
Third solution: Give some more values to simul-efuns (e.g. 20480) and throw a warning when this limit is reached.
(0002165)
zesstra   
2012-12-05 20:28   
Maybe discard any simul-efuns once this higher limit is reached with a warning? Better than crashing...
BTW: do private lfuns in simul_efun.c count against this limit? (My guess is no, but I am not sure).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
894 [LDMud 3.5] Efuns crash have not tried 2021-09-08 00:00 2021-09-08 21:14
Reporter: paradox Platform: x86_64  
Assigned To: Gnomi OS: Ubuntu  
Priority: normal OS Version: 21.04  
Status: resolved Product Version: 3.5.4  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.5  
    Target Version:  
Summary: efun::dump_driver_info crash - Illegal type: 0
Description: Running `efun::dump_driver_info(DDI_OBJECTS);` on my production game instance caused a crash.

You can find a password protected zip file with more information here: https://dunemud.net/lib/exe/fetch.php/dunemud.dump_driver_info.details.zip

Please ask Paradox on the LPC Discord for the password if you don't already have it.

Inside is:

* ldout.crash.snip.txt - standard out log lines.
* lderr.crash.snip.txt - standard err log lines
* 2021.09.01.crash.dump - the core dump
* home/dune/dune/ldbin/ldmud - the LD binary we were running at the time of the core dump

At the time of the crash, on standard out we log:
2021.09.01 01:28:39 Illegal type: 0
2021.09.01 01:28:39 Current object was players/paradox/secure/.lpc/.tmp_code26

On standard err we log a disassembly trace and the line "2021.09.01 01:28:39 LDMud aborting on fatal error.". See `lderr.crash.snip.txt` for the full trace.

We are running LDMud 3.5.4, but with some slight customization.

* For the most part, it's Gnomi's 3.5.4 "35+python" branch from: https://github.com/amotzkau/ldmud/tree/35+python
* (Shamefully) I also revert the `set_light` deprecation: https://github.com/dune-mud/ldmud/commit/3b896cacfd2e80169907727bae8d1ab3d3052f8c
* At the time of the crash, we were running this SHA from my Dune LDMud branch: https://github.com/dune-mud/ldmud/commit/3f250aa67e9930b03fbb689f19c7065afeb114f5

In the password protected zip you can find the built production binary. Please take some care sharing this as it has a MySQL password "baked in" (on my TODO list to fix...).
Tags:
Steps To Reproduce: Simply run `efun::dump_driver_info(DDI_OBJECTS);`....

However, running `efun::dump_driver_info(DDI_OBJECTS);` on my QA instance, and in my development instance functions correctly and I have no observed a crash. I am hesitant to try to reproduce on production (my playerbase suffers when there are frequent reboots) but could schedule a test in ~20d if we are sufficiently stumped to need more data. Frustrating!
Additional Information: Here is a backtrace from the core dump:
```
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
0000001 0x00007f6bac616859 in __GI_abort () at abort.c:79
0000002 0x00005595e991181c in dump_core () at simulate.c:616
0000003 0x00005595e9911ac8 in fatal (fmt=fmt@entry=0x5595e993837b "Illegal type: %d\n") at simulate.c:677
0000004 0x00005595e986afba in svalue_size (v=v@entry=0x7f6b949aa590, pTotal=pTotal@entry=0x7fffbd657238) at dumpstat.c:426
0000005 0x00005595e986ab75 in svalue_size (v=v@entry=0x7f6ba37e0b60, pTotal=pTotal@entry=0x7fffbd6572a0) at dumpstat.c:287
0000006 0x00005595e986b01f in svalue_size_map_filter (key=<optimized out>, values=0x7f6ba37e0b70, extra=0x7fffbd657350)
    at dumpstat.c:73
0000007 0x00005595e98beeef in walk_mapping (m=0x7f6ba9531888, func=func@entry=0x5595e986afc0 <svalue_size_map_filter>,
    extra=extra@entry=0x7fffbd657350) at mapping.c:2051
0000008 0x00005595e986ae50 in svalue_size (v=v@entry=0x7f6ba95657f0, pTotal=pTotal@entry=0x7fffbd6573c8) at dumpstat.c:136
0000009 0x00005595e986b330 in data_size (pTotal=<synthetic pointer>, ob=0x7f6ba95650d0) at dumpstat.c:460
0000010 dumpstat (fname=0x7f6b8f13c3c8, fname@entry=0x7f6bac03e508) at dumpstat.c:536
0000011 0x00005595e987d9ef in f_dump_driver_info (sp=0x5595e99c5b00 <value_stack_array+800>) at efuns.c:9297
0000012 0x00005595e989ec62 in eval_instruction (
    first_instruction=first_instruction@entry=0x7f6b967fdafa "\017\017\004\v]\031\b@]\251k\177",
    initial_sp=<optimized out>) at interpret.c:7696
0000013 0x00005595e98a6a56 in apply_low (fun=<optimized out>, fun@entry=0x7f6ba95d4008, ob=ob@entry=0x7f6b9bb77b28,
    num_arg=num_arg@entry=0, b_ign_prot=b_ign_prot@entry=false) at interpret.c:15872
#14 0x00005595e98a7a65 in int_apply (fun=0x7f6ba95d4008, ob=0x7f6b9bb77b28, num_arg=num_arg@entry=0,
    b_ign_prot=b_ign_prot@entry=false, b_use_default=b_use_default@entry=true) at interpret.c:16071
#15 0x00005595e989b094 in eval_instruction (
    first_instruction=first_instruction@entry=0x7f6b8f6c6a9d "c\037\006~\v\220~\f\220p\017",
    initial_sp=<optimized out>) at interpret.c:15277
#16 0x00005595e99149e9 in catch_instruction (flags=2, offset=<optimized out>,
    i_sp=i_sp@entry=0x5595e9a78f78 <inter_sp>, i_pc=i_pc@entry=0x7f6b8f6c6a9d "c\037\006~\v\220~\f\220p\017",
    i_fp=i_fp@entry=0x5595e99c5910 <value_stack_array+304>, reserve_cost=8000, i_context=0x0) at simulate.c:461
#17 0x00005595e989e9fc in eval_instruction (
    first_instruction=first_instruction@entry=0x7f6b8f6c5e62 "b\001\005\017\003;(\002\n", initial_sp=<optimized out>)
    at interpret.c:9086
#18 0x00005595e98a6a56 in apply_low (fun=<optimized out>, fun@entry=0x7f6ba9b5b920, ob=ob@entry=0x7f6b99e15d78,
    num_arg=num_arg@entry=1, b_ign_prot=b_ign_prot@entry=false) at interpret.c:15872
#19 0x00005595e98a7a65 in int_apply (fun=0x7f6ba9b5b920, ob=0x7f6b99e15d78, num_arg=num_arg@entry=1,
    b_ign_prot=b_ign_prot@entry=false, b_use_default=b_use_default@entry=true) at interpret.c:16071
#20 0x00005595e989b094 in eval_instruction (
    first_instruction=first_instruction@entry=0x7f6ba972d002 "b\001\001c\b\255\017\003;~\001)\a#d=(\006\b\255\037\001>=l\001\031c\b\255\037\001>\n\332\037", initial_sp=<optimized out>) at interpret.c:15277
#21 0x00005595e98a6a56 in apply_low (fun=<optimized out>, fun@entry=0x7f6ba9719b00, ob=ob@entry=0x7f6ba1330070,
    num_arg=num_arg@entry=1, b_ign_prot=b_ign_prot@entry=false) at interpret.c:15872
#22 0x00005595e98a7a65 in int_apply (fun=fun@entry=0x7f6ba9719b00, ob=ob@entry=0x7f6ba1330070,
    num_arg=num_arg@entry=1, b_ign_prot=b_ign_prot@entry=false, b_use_default=b_use_default@entry=true)
    at interpret.c:16071
#23 0x00005595e98a7f03 in sapply_int (fun=0x7f6ba9719b00, ob=ob@entry=0x7f6ba1330070, num_arg=num_arg@entry=1,
    b_find_static=b_find_static@entry=false, b_use_default=b_use_default@entry=true) at interpret.c:16233
#24 0x00005595e9917e8a in execute_callback (cb=cb@entry=0x7f6b9aad8f70, nargs=nargs@entry=1, keep=keep@entry=true,
    toplevel=toplevel@entry=true) at simulate.c:4088
#25 0x00005595e983f125 in parse_command (buff=buff@entry=0x7fffbd658120 "lpc dump_driver_info(0);",
    from_efun=from_efun@entry=false) at actions.c:1005
#26 0x00005595e9840db2 in execute_command (str=str@entry=0x7fffbd658120 "lpc dump_driver_info(0);", ob=0x7f6ba1330070)
    at actions.c:1161
#27 0x00005595e984c907 in backend () at backend.c:967
#28 0x00005595e983d946 in main (argc=<optimized out>, argv=0x7fffbd65e3d8) at main.c:705
```

Looking at frame 0000007 I was able to identify the mapping that caused the problem. In frame 0000005 we're calculating the svalue_size for a closure value from the mapping and everything seems OK. In Frame 0000004 we find an lvar with type 0 and abort. All frames above that are related to processing the abort condition.

For what it's worth, the mapping key and value that caused this problem are from some fairly complex code implementing "moustache" templating in LPC. It might be tickling something off the beaten path but I wasn't able to spot the problem with my level of driver-fu.
Attached Files:
Notes
(0002656)
Gnomi   
2021-09-08 21:13   
This is already fixed in https://github.com/amotzkau/ldmud/commit/c73532a73a24b205ebedae343c75fc79d780f6b0.

This commit is marked for the upcoming 3.5.5 and 3.6.5 release. Therefore closing this bug.

As a workaround either don't create lambdas with more than 256 values or refrain from using DDI_OBJECTS or OI_DATA_SIZE.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
890 [LDMud 3.6] LPC Language minor have not tried 2021-04-12 11:24 2021-06-25 13:18
Reporter: sinnvoll Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: new string literal prefixes for ascii/unicode handling
Description: There is now b"ForBytes" to get bytes

a"AsciiOnly" would throw an error for NonAsciiChars introduced for example by script
c"Maßstäbchen" would convert the string to Ascii at compile time
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002594)
Gnomi   
2021-04-16 21:19   
What is the use case behind the a""-Prefix? Why do you need a compiler error on non-ASCII-Strings?
(0002655)
sinnvoll   
2021-06-25 13:18   
There are strings, that should be ascii file-names, user-names, tags for states

I work with Search & Replace over many files. Sometimes I get it wrong.

So I get an error, if something is wrong after a false replacement or a change of someone, who doesn't know it should be ascii.

Compile Time Errors do trigger by loading the File without long testing.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
862 [LDMud 3.5] Runtime crash always 2018-02-04 19:19 2021-05-31 21:44
Reporter: gulahr Platform:  
Assigned To: zesstra OS: Ubuntu  
Priority: normal OS Version: 17.10  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.2  
    Target Version: 3.5.2  
Summary: Segmentation fault during startup
Description: I compiled and installed revision 2aa52c15942c6edfcd32dce6e391043c0caa36ab with morgengrauen settings and I get a segmentation fault during the startup.

The option --with-malloc=sysmalloc fixes the issue, but I'll send you the stacktrace and driver log anyway.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: driver.log (2,172 bytes) 2018-02-04 19:19
http://ldmud.eu/file_download.php?file_id=293&type=bug
stacktrace (11,503 bytes) 2018-02-04 19:19
http://ldmud.eu/file_download.php?file_id=294&type=bug
Notes
(0002450)
zesstra   
2018-02-04 20:04   
Thank you!
It seems, we have yet another interference between system libs and our own malloc implementation. Our default replacement of the system malloc seems to get increasingly problematic. Maybe we will find another solution, but we will probably change that default soon...
(0002473)
zesstra   
2019-04-05 21:34   
The driver now uses by default the system memory allocator, not our own allocator. This solves the immediate issue.
(Rewriting our memory allocator would solve the fundamental issue, but that has to wait...)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
594 [LDMud] Efuns minor always 2009-01-14 17:49 2021-05-05 21:02
Reporter: Gnomi Platform: i686  
Assigned To: OS: Debian GNU/Linux  
Priority: low OS Version: 4.0  
Status: new Product Version: 3.3  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: save_value doesn't need to save inline closures
Description: save_value takes its time to save inline closures, there is code in it only for them (e.g. saving context variables). But restore_value can't restore them.

The main reason for this is, that the lfun of the inline closure is private and so it is not included in the function name lookup table (the table contains only visible function names) and therefore can't be found by restore_value. symbol_function() has the same limitation for the same reason.

I think the reasons are conceptually sound. Inline closures are invisible, almost volatile functions (just like lambdas) and therefore should not be saved by save_value/object.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0000892)
zesstra   
2009-01-15 14:57   
I would not describe them as 'volatile' (then other functions are IMHO volatile as well), but as they are private and the savefile might be restored to a different object, I guess they should not be restored. And then I also agree, that we should not save them.
(0002629)
zesstra   
2021-05-05 21:01   
(Last edited: 2021-05-05 21:02)
One should add: if restore_object could restore closures to private functions, any inheritee could create closures to private functions they would otherwise not see, by creating a specially crafted savefile. That seems to me the most important conceptional issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
734 [LDMud 3.7] LPC Language feature N/A 2010-03-10 17:49 2021-04-17 10:34
Reporter: _xtian_ Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: acknowledged Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: warn_nomask modifier
Description: And another modifier idea:

I find myself adding "nomask" modifiers a lot to old code. It is a great way to ensure that inheriters don't break some API functionality or build hacks on assumptions that change over time.

Mostly I do this in several steps, where I first announce my intention to add "nomask" to a core function (this usually is shamelessly ignored), then I start grepping for all users of that function. Unfortunately I nearly always miss some of those, so when I finally make the function "nomask", some code ends up not compiling any more.

It would be nice to be able to add another step, where I add a "warn_nomask" modifier, which only throws a warning instead of an error. So we could find masking functions earlier.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001782)
zesstra   
2010-03-10 18:44   
Hehe, I know the problem, that nobody cares about announcements like this. ;-)
(Although using nomask to fix the interface is a quite drastic step. But I can feel with you, I encountered too much crap which people redefined mudlib functionality with, sometimes they copied the mudlib lfun, appended a single line and now the behaviour is drastically different to the rest of the mud.)

Well, one first comment: after the 'deprecated' flag we don't have a free bit in the function flags left. ;-) So first we have to change the function flags to a 64 bit type and check code for hard-coded assumptions about its size. The bright side is, that we anyway plan to move the function headers from the bytecode into a separate table in the program structure.
(0001783)
_xtian_   
2010-03-11 03:05   
modifier flags field: What I tried a few years back - and obviously I didn't finish that or send it in - was to seperate the field for function flags and variable flags. If I remember correctly enough Defines don't overlap, so this freed enough bits.
(I also renamed the fields to let the compiler find any usage of the old field name)
(0002583)
Gnomi   
2021-04-12 00:42   
We would have enough bits if we moved the function start pointer / inherit index out of the flags...
And separating function from variable flags might be a good idea, too.
(0002584)
zesstra   
2021-04-12 09:08   
If I remember correctly, we also thought that was a good idea some years ago for other reasons...
(0002604)
zesstra   
2021-04-16 22:41   
suspended pending refactoring function and variable flags. ;-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
891 [LDMud 3.7] Runtime feature N/A 2021-04-15 19:52 2021-04-17 10:08
Reporter: fufu Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: confirmed Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: H_TELNET_NEG hook should take data as bytes, not array of ints
Description: The current spefication of the hook is

  void|mixed <closure>(int action, int option [, int * opts ] )

but the new bytes type seems to be more appropriate for dealing with subnegotiations.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002590)
fufu   
2021-04-16 18:42   
There are more callbacks that this applies to, we should deal with all of those at once.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
698 [LDMud 3.6] LPC Language feature have not tried 2009-11-01 04:44 2021-04-17 00:27
Reporter: _xtian_ Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.3  
    Target Version:  
Summary: Make different versions of a struct compatible to each other
Description: As there seems to be some interest in making structs-children and struct-parents polymorph - *yippie* ;) - , I thought I'd add another issue that may be similar.

One negative issue with structs is that they may not be saved/restored without complications. Technically it is feasible, but practically speaking struct definitions change over time and old struct-definitions will not be compatible to newer ones. Then the struct in the save-file will not be able to restore properly.

(so what I do is to use mappings whenever I have to store data)

It would be great, if older structs could restore to newer variations of its definition. Mostly this will just be adding or maybe removing an element of the struct.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001581)
zesstra   
2009-11-02 10:38   
Mhmm. I just had a look at this stuff. Basically, the struct is searched first in the objects program (including inherited programs). If that fails, the struct is searched in the program given in the savefile itself (so you can restore a struct into a <mixed> without inheriting the struct definition).

If the savefile has more members than the current struct definition, the extra members in the save file will be silently ignored.
If the struct has more members than the savefiles, these will just be 0.
So far, so good.

But if you change the types... Well the struct will still be restored. The data will be assigned to the current structs members in the sequence they are in the savefile. Example:
struct a_s {
    int a;
    string b;
};
Savefile:
a_instance (<"a_s players/zesstra/i1.c #1469",42,"Foobar",>)

If I change a_s in the meantime to:
struct a_s {
    mapping a;
    string b;
};

I can still restore it. But obviously, a_instance->a has now a incorrect type.
So technically, older structs can restore to newer ones, but the result may not always be desireable. In case of wrong types, this can be checked upon restore and I would seriuosly consider to raise an error if the types are not matching.

But then another example would be if I insert something at the beginning of the struct, like:
struct a_s {
    int ref;
    string name;
    int a;
    string b;
};
Now, this we can't detect at the moment. The old struct will be restored, by now ref would be 42, name "Foobar", but a and b would be 0...

For preventing the latter case, we need another savefile format, which includes member names (like mappings) and does not rely completely on the sequence of members in a struct. Either use a format similar to mappings or find a way to save struct definitions in a savefile and compare that to the current struct upon restore.
(0002620)
Gnomi   
2021-04-17 00:27   
save & restore of different struct versions is implemented in 3.6.3

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
787 [LDMud 3.6] Runtime feature N/A 2011-09-13 14:18 2021-04-16 20:22
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: assigned Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version: 3.3.721  
Summary: Possibility to change time_to_reset globally at runtime
Description: It may be interesting to be able to change the content of that variable at runtime for all objects in the game not setting the reset time themselves.

Although in this case, we probably should not change __RESET_TIME__, i.e. decouple the permanent define from time_to_reset.

Of course, that needs a privilege violation and would probably be suitable in configure_driver().
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002592)
zesstra   
2021-04-16 20:22   
__RESET_TIME__ soll dann geändert werden.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
797 [LDMud 3.6] Documentation text always 2011-12-09 10:37 2021-04-16 19:58
Reporter: Sorcerer Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: assigned Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Typo in db_conv_string manpage
Description: interpretated -> interpreted in section "Description" of db_conv_string manpage
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
616 [LDMud 3.3] Networking minor always 2009-03-15 09:47 2021-04-08 23:34
Reporter: fufu Platform:  
Assigned To: fufu OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: IPv6 support is broken.
Description: Basically the implementation doesn't deal very well with the fact that it may encounter both IPv4 and IPv6 addresses when IPv6 support is enabled.

As a result, using ldmud with IPv6 is slightly tricky. In particular ldmud is currently sensitive to the order of entries in /etc/hosts, and __HOST_IP_NUMBER__ is formatted wrong.

(In Wunderland we get "8b12:b56::" as __HOST_IP_NUMBER__ -- 8b.12.0b.56 is its IPv4 address in hex.)

I'm attaching a patch for these two problems, but I don't want to apply it.

The proper fix, I think, is to teach ldmud to cope with several address families simultaneously, and that's what I'm planning to do.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: ipv6-bandaid.patch (2,387 bytes) 2009-03-15 09:47
http://ldmud.eu/file_download.php?file_id=201&type=bug
Notes
(0002573)
fufu   
2021-04-08 23:32   
See @3023/8dcd3287f by Gnomi, which implements a better bandaid: it looks up the IPv6 address of the host if available, and falls back on an IPv6-mapped IPv4 address otherwise.

When I wrote about dealing with several address families simultaneously, I suspect I wanted to render IPv4 addresses without the ::ffff: prefix, so that using a driver with IPv6 support from an IPv4 host would be just like running a driver without IPv6 support. But by now people will either have disabled IPv6 support or adapted the mudlib to cope with the prefixes... I don't want to change anything in this area anymore.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
758 [LDMud 3.6] General minor N/A 2010-09-19 18:37 2021-04-08 18:01
Reporter: zesstra Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.719  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.1  
    Target Version:  
Summary: sscanf: Conditional jump or move depends on uninitialised value
Description: valgrind reported the following:
==21326== Conditional jump or move depends on uninitialised value(s)
==21326== at 0x100064766: e_sscanf (efuns.c:4131)
==21326== by 0x100093C24: eval_instruction (interpret.c:9632)
==21326== by 0x1000B2E53: apply_low (interpret.c:17233)
==21326== by 0x1000B3109: int_apply (interpret.c:17311)
==21326== by 0x1000B37C7: sapply_int (interpret.c:17472)
==21326== by 0x10015FD56: execute_callback (simulate.c:4082)
==21326== by 0x10003ED2C: call_input_to (comm.c:4063)
==21326== by 0x10003EFAA: call_function_interactive (comm.c:4148)
==21326== by 0x1000164C2: backend (backend.c:802)
==21326== by 0x1000D5720: main (main.c:678)
==21326== Uninitialised value was created by a stack allocation
==21326== at 0x100064381: e_sscanf (efuns.c:4024)
==21326==
==21326== Conditional jump or move depends on uninitialised value(s)
==21326== at 0x100064766: e_sscanf (efuns.c:4131)
==21326== by 0x100093C24: eval_instruction (interpret.c:9632)
==21326== by 0x1000B26AC: apply_low (interpret.c:17110)
==21326== by 0x1000B3109: int_apply (interpret.c:17311)
==21326== by 0x1000AB2D3: eval_instruction (interpret.c:16562)
==21326== by 0x1000B5A91: int_call_lambda (interpret.c:18209)
==21326== by 0x1000BDA35: v_funcall (interpret.c:20762)
==21326== by 0x100091499: eval_instruction (interpret.c:8525)
==21326== by 0x1000B699A: int_call_lambda (interpret.c:18489)
==21326== by 0x1001636FC: v_limited (simulate.c:5265)
==21326== by 0x100091499: eval_instruction (interpret.c:8525)
==21326== by 0x100153305: catch_instruction (simulate.c:456)
==21326== Uninitialised value was created by a stack allocation
==21326== at 0x100064381: e_sscanf (efuns.c:4024)
==21326==
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
458 [LDMud] LPC Language feature N/A 2006-03-01 15:32 2021-04-07 00:08
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: & implementation on arrays
Description: ;; TODO: ({ 'a', 'a', 'b' }) & ({ 'a' }) -> ({ 'a' }), but should be ({ 'a', 'a' })
;; TODO:: strings already do that: "aab" & "a" -> "aa"
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002564)
Gnomi   
2021-04-06 23:54   
I don't know since when, but the desired behavior is the actual behavior of LDMud 3.6.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
647 [LDMud 3.5] LPC Compiler/Preprocessor minor always 2009-06-01 07:31 2021-04-07 00:04
Reporter: _xtian_ Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.717  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: struct types in arguments not checked at compile time; polymorphism request
Description: Struct (template) type does not seem to be checked in function arguments at compile time. This actually compiles:

#pragma strict_types
#pragma save_types

struct a {
  int j;
};

struct b {
  int i;
};

void fun(struct a bla) // expects a
{
  printf("%O\n", bla);
}

void create()
{
  fun( () ); // this compiles with b. Should be (<a>)
}


Now, this should throw an error when compiling.

(note: if you access an non-existing member of "bla" at runtime, this will properly cause an error)
Tags:
Steps To Reproduce:
Additional Information: ... BUT: I would like to make a strong case for polymorphism in structs as arguments for functions.
This would mean that the modified above case:

struct b (a) { // b now inherits from a
  int i;
};

... and the rest of the above example, would then again compile correctly.

void fun(struct a bla);
void create()
{
  fun( () ); // this now works because b inherits a
}


So this is a request for adding compile-time checks of struct-type into function call arguments, but also allowing arguments who are "related" to those expected.


Good reasons for polymorphism in this place:
- it should be fairly simple to implement (although Im not a driver-hacker, I dont know exactly what this needs)
- it greatly enhances the possibilities to work with structs as you can define your own data types (different structs) and achieve some type-safety with them while using some sort of generic function like in the example.
- I need it ;) ... I _really_ need it.
- since until now there were no type-checks at compile-time at all, there could be users who are using this possibility of passing different struct-types as arguments. This would be a way of keeping those mechanics (albeit more elegantly).
Attached Files:
Notes
(0001178)
zesstra   
2009-06-01 08:11   
Huh. All struct values have internally the LPC type T_STRUCT, no matter what struct it actually is. And the compiler just looks at the primary type tag. I am not sure that this is a really simple thing to change.
(0001182)
Gnomi   
2009-06-01 09:06   
The fulltype_s structure already has the information about which structure T_STRUCT refers to, it's already checked for assignments (struct a x = (); is not allowed), but not for function calls.
(0002565)
Gnomi   
2021-04-07 00:04   
I checked it with LDMud 3.6.4 and the given code throws 'Bad type for argument 1 of fun (struct a vs struct b)'.
I think the check works since LDMud 3.5.0.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
199 [LDMud 3.6] Implementation feature N/A 2004-11-26 22:39 2021-04-06 23:45
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.8 and before  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.4  
    Target Version:  
Summary: Extension of func_spec syntax
Description: Short: Extension of func_spec syntax
From: Lars Duning <lduning@peopledoc.com>
Date: Wed, 03 Mar 1999 13:32:34 +0000
Type: Feature
State: Unclassified

make_func: should allow func_spec declaration a la

    int sscanf(string s1, string s2, lvalue mixed dest...)
                                     ^^^^^^
or
    int sscanf(string s1, string s2, mixed &dest...)

so that functions like sscanf() are no longer a special case.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
546 [LDMud 3.5] Runtime crash always 2008-07-02 08:10 2021-04-06 23:36
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Rework lvalue handling
Description: This is the master bug for everything lvalue related in 3.5.

Lvalues in its current form are still dangerous and my lead to crashes, because in several circumstances the driver assumes a limited lifetime which cannot be guaranteed. So main goal is to create lvalues with possibly unlimited lifetime. But also most of the many inconsistencies shall be eliminated.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
656 [LDMud 3.6] General minor have not tried 2009-06-03 15:32 2021-04-06 23:35
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.4  
    Target Version:  
Summary: lvalue 8: Miscellaneous
Description: * Remove restrictions on & usage ("Can't trace reference loops.")

* RANGE lvalues should be able to create a circular linked list of themselves.
This is for

     mixed x = &(arr[1..4]);
     mixed y = &(brr[2..5]);
     x = &y;

The last statement would make arr[1..4] = brr[2..5] and also link x and y together, so that future assignments change both. Also each pair of elements are linked together via LVALUE_PROTECTED, so that an assignment to one element changes the other.

* Allow range lvalues to be indexed: mixed a = &(arr[3..4]); a[1] = 10;
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
834 [LDMud 3.6] General major always 2014-08-20 02:27 2021-04-06 23:31
Reporter: chaos Platform: amd64  
Assigned To: Gnomi OS: Debian  
Priority: normal OS Version: 2.6.18-5  
Status: resolved Product Version: 3.3.720  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.4  
    Target Version:  
Summary: Quoted arrays inside arrays or mappings save correctly but error on restore
Description: Serialization of quoted arrays inside arrays or mappings results in a spurious format error on restore_svalue().
Tags:
Steps To Reproduce: restore_value(save_value(({ '({}) })))
Additional Information: This happens because ({ is a valid operator per symbol_operator(), which causes restore_size() and restore_map_size() to return inaccurate results when the data structure contains a quoted array.

I fixed this locally by wrapping the usage of symbol_operator() in restore_size() and restore_map_size() in this:

            /* Specially avoid quoted arrays since symbol_operator(), if
             * called now, will think their opening construct is an operator
             */
            if(*pt != '(' || *(pt + 1) != '{')
            {
               ...
            }

The relevant code is identical in the 3.2 branch; I'd suggest this would be a valid update to reopen this branch for, since it's a potentially serious bug and very easily resolved.
System Description
Attached Files:
Notes
(0002238)
chaos   
2014-08-20 15:12   
BTW: My fix would leave the case of an actual serialized #'({ unaddressed and presumably not working, except that #'({ is serialized as #e:aggregate, not #e:({, so it seems like it should be fine.
(0002241)
chaos   
2014-09-14 08:06   
(Last edited: 2014-09-14 08:10)
It turns out that my fix continues to fail in the case of quoted arrays with sharing specifiers, like #​1:<1>=({1,2,})

For a more robust fix, I added this function (before restore_map_size()):

/*-------------------------------------------------------------------------*/
/* Detects whether we are at the beginning of an array literal in
 * a serialized data string
 */

INLINE static int
at_array_literal (char *pt)
{
    if (*pt == '(' && *(pt + 1) == '{')
        return MY_TRUE;
    if (*pt != '<')
        return MY_FALSE;
    switch (*++pt)
    {
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
        for (pt++; *pt != '>'; pt++) {
            switch (*pt) {
            case '0': case '1': case '2': case '3': case '4':
            case '5': case '6': case '7': case '8': case '9':
            case '>':
                break;
            default :
                return MY_FALSE;
            }
        }
        break;
    default :
        return MY_FALSE;
    }
    return *(pt + 1) == '=' && *(pt + 2) == '(' && *(pt + 3) == '{';
}

and replaced the logic I originally gave with if (!at_array_literal(pt)).


View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
888 [LDMud 3.6] Efuns crash always 2021-04-02 19:19 2021-04-06 23:30
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: high OS Version: 10.9.x  
Status: resolved Product Version: 3.6.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.4  
    Target Version: 3.6.4  
Summary: variable_list() needs to check for swapped variables
Description: variable_list() with the flag RETURN_VARIABLE_VALUE tries to access the value of variables, but does not check if the variables are swapped. Therefore, if variables are swapped out, a wrong pointer is used and likely results in a crash.
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
886 [LDMud 3.6] Runtime crash always 2021-03-30 04:38 2021-04-06 23:30
Reporter: gorgar Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.4  
    Target Version:  
Summary: crash when mssp enabled
Description: Game is crashing under rather odd circumstances:
1. mssp recently configured and may not be configured perfectly
2. user pastes a very long message to a channel via discord with raw text from mssp values (from client)
3. mud crashes few seconds later

Despite the oddness and possible misconfiguration with mssp, didn't think that should justify a crash.
Tags:
Steps To Reproduce:
Additional Information: LDMUD 3.6.0-22-g42134c1f

err:
[xerq] read: Success
2021.03.29 20:58:47 [xerq] Demon exiting.

debug.log:
2021.03.29 20:58:46 (terminal_colour) indent 259 > wrap 80

core and ldmud file:
https://drive.google.com/drive/folders/1UF1vMUsewDXwc7opX8jvDILgXETGcxVc?usp=sharing

Note: ldmud is symlinked to dev-ldmud
Attached Files:
Notes
(0002558)
Gnomi   
2021-03-30 08:45   
I think this crash may have been fixed in LDMud 3.6.2. Could you verify that with an updated version of LDMud?
(0002559)
Gnomi   
2021-03-30 12:28   
Disregard my last comment. The terminal_colour message is just an error message, not a fatal error.

But it seems, the binary and core file do not match. I can't get any information from the core file. Are there any more messages before the '[xerq] read: Success' line?
(0002560)
Gnomi   
2021-03-30 14:08   
As I said I can't get much, because the binary does not seem to match. This is what I could gather from the core file alone:

The crash happened in an object named '/guilds/channel_d', in the function SendChannel. The function calls a lambda, which calls the efun terminal_colour() with a string, that seems like MSSP info, a mapping for colouring, a width of 80 and indent of 259.

As the indent is wider than the width, terminal_colour will throw an error. This error is not yet handled, a call trace was not generated and the master not called, yet.

So my guess is that the problem might lie within get_line_number_if_any(), but I couldn't reproduce it.
(0002561)
gorgar   
2021-03-30 14:20   
The core should match but the binary is symlinked to dev-ldmud.

Did upgrade to 3.6.2 last nite but havent reproduced the crash yet.
(0002563)
Gnomi   
2021-03-30 17:46   
The reason was an out-of-bounds write into a buffer for the name of the lambda. Normally this wouldn't crash the driver, but in this case the driver was compiled with -D_FORTIFY_SOURCE which leads to an abortion with a message "*** buffer overflow detected ***" on standard error.

Fixed it in https://github.com/amotzkau/ldmud/commit/f2238d7170ac1065f10f83934e1be6303de36720

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
819 [LDMud 3.6] General minor always 2013-07-12 15:08 2021-04-06 23:28
Reporter: Leonidas Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.4  
    Target Version:  
Summary: column-mode of sprintf does drop rows
Description: Using the column-mode of sprintf the last row will be dropped if it's row is otherwise empty.

xeval printf("%#-30.3s", "AAA\na1\na2\n\nBBB\nb1\nb2\n\nCCC\n\n\nc3\n")

gives a table with dropped third row (element c3):

AAA BBB CCC
a1 b1
a2 b2

instead of the full table

AAA BBB CCC
a1 b1
a2 b2
                    c3
Tags: sprintf
Steps To Reproduce:
Additional Information: The third row can be forced to be displayed by setting all other elements in the third row (whitespace suffices):
xeval printf("%#-30.3s", "a\na1\na2\n \nb\nb1\nb2\n \nCCC\n\n\nc3\n")

Setting only one element in the row leads to dropping of the last element (n,m):
xeval printf("%#-30.3s", "AAA\na1\na2\n \nBBB\nb1\nb2\n\nCCC\n\n\nc3\n")

AAA BBB CCC
a1 b1
a2 b2
a3
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
654 [LDMud 3.6] General minor always 2009-06-03 15:20 2021-04-06 23:27
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.4  
    Target Version:  
Summary: lvalue 6: call-by-reference on efuns
Description: sscanf and parse_command aren't efuns because we need special compiler magic so that its arguments get passed by reference per default. Other efuns don't respond well to explicit lvalues (lfuns don't care, but efuns respond with something like "Bad arg 1 to sin(): got 'lvalue', expected 'number/float'.")

I'd like to allow efun definitions to specify whether its arguments have to be rvalues (default), can be lvalues (keyword "lrvalue"), or should be lvalues ("lvalue"). In the rvalue case all lvalues are automatically converted to rvalues when calling the efun (test_efun_args() can do this). In the lvalue case the compiler automatically generates the bytecode for protected lvalues (as it does for sscanf now).

With this sscanf and parse_command can be made real efuns.

This can be extended to object-internal lfun-calls, when a parameter is declared as <type> &var.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
651 [LDMud 3.6] General minor always 2009-06-03 14:37 2021-04-06 23:27
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.4  
    Target Version:  
Summary: lvalue 3: Lvalues to mapping entries
Description: The following code:

    mapping m = ([:1]);
    m[1][2] = 5;

gives an error and leaves m as ([1: 0]).

Therefore I suggest a special LVALUE_(UN)PROTECTED_MAPENTRY which contains a (in protected lvalues a refcounted) pointer to the mapping and a copy of the index. Assignments to this lvalue would create the mapping entry, but it can not be indexed. When used as an rvalue it has to lookup in the mapping, because in the meantime this key could have been created. (In that case it could be changed to a normal LVALUE_PROTECTED on the fly.)
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
148 [LDMud 3.6] General minor always 2004-11-26 20:18 2021-04-06 23:26
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.8 and before  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.4  
    Target Version:  
Summary: Failed assignments leave behind empty mapping entries.
Description: Falls das schon bekannt ist, bitte ich um Entschuldigung:

map = ([1:2]); map[0][5]=1;

Fuehrt bei mir dazu, dass in map ein Key fuer den ersten Index angelegt wird
(also Effekt wie ein map[0]=0), obwohl die Zuweisung map[0][5]=1 einen
Fehler ausloest (Index out of bounds).

(map[0])[5]=1 verhaelt sich uebrigens nicht so.

---------------------------------
The problem is in how the expressions are parsed. In 'map[0][5] = 1', the
'map[0]' is parsed as possible lvalue, thus generating the opcodes
'push_indexed_lvalue', followed by 'index_lvalue'.

On the other hand '(map[0])[5]' parses the 'map[0]' as normal rvalue, leading
to the opcode sequence 'index' followed by 'index_lvalue'.

Given the obscurity in the parser when it comes to generating lvalues, I don't
know how to fix this yet.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000660)
fufu   
2008-07-02 06:15   
This is tricky.

In map[0][5] = 1, map[0] doesn't have to be an lvalue, and parsing it as an rvalue should fix the problem.

However, this idea fails for ranges, so map[0][5..5] = ({1}) would still create a new mapping entry.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
152 [LDMud 3.6] General minor always 2004-11-26 20:31 2021-04-06 23:25
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.8 and before  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.4  
    Target Version:  
Summary: replace_program() and virtual variables
Description: Short: replace_program() and virtual variables
From: Lars, Zonk
Date: 2003-01-19
Type: Bug
State: New

replace_program() can replace with a program only if it either doesn't
have virtually inherited variables, or is the first program inherited.

Reason is that replace_program() expects the variables of the program
in one block, starting at variable_index_offset. However, with virtual
inherites the virtually inherited variables are collected in a block
at the beginning of the variable block, so that replace_program() extracts
the wrong variables during the replacement. Only if the replaced program happens
to be the first inherited program, the variable_index_offset is 0 and
the extraction code by accident does the right thing.

The proper solution would be to use the inheritance/variable information
to extract and rebuild both virtual and nonvirtual variable blocks; however
at the moment I don't understand the structure well enough to do it.

Here are the test programs:

--- test.c ---
inherit "/test_a";
inherit "/test_c";

--- test_a.c ---
string target_program = "test_a";

--- test_c.c ---
virtual inherit "/test_b";
string var2 = "test_c";

void create()
{
  replace_program("/test_c");
  set_var("content"); call_out( "write_var", 2 );
}

--- test_b.c ---
string var;

void set_var( string value )
{ var = value; write( "object="+object_name()+" [set_var()] var="+var+"\n" ); }

public void write_var()
{ write( "object="+object_name()+" [write_var()] var="+var+"\n" ); }

------
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
235 [LDMud 3.6] Efuns feature N/A 2004-11-26 23:40 2021-04-06 23:24
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.8 and before  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.4  
    Target Version:  
Summary: Extend debug_info() to handle interactives
Description: Short: Extend the debug_info() method to handle interactives.
From: Lars
Date: 2000-12-20
Type: Feature
State: New

Let debug_info(this_interactive()) return information about the
interactive structure, especially about the charmode/noecho settings.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
499 [LDMud 3.6] General minor always 2007-01-17 04:20 2021-04-06 23:24
Reporter: fippo Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.713  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.4  
    Target Version: 3.3.721  
Summary: yet another tls bug
Description: http://lpc.pages.de/download/pkg-tls-fix-2308.patch
sometimes command giver is not properly set and the drivers behaves in strange ways... this patch fixes the behaviour but may be sub-optimal (i.e. paranoia_giver may be unnecessary).

Another feature would be to remove the line
SSL_CTX_set_default_passwd_cb(context, no_passphrase_callback);
from pkg-tls.c (and no_passphrase-callback, which is then no longer necessary).
The driver will then prompt for a password when loading encrypted key files.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000811)
willem   
2008-12-09 11:33   
Doing set_this_player(this_object()) at the beginning of the tls callback function in the mudlib will cover up the symptoms of this bug. I'm going to use this until the problem is officially fixed to avoid maintaining too many local patches.
(0001013)
Gnomi   
2009-04-08 08:08   
First part (missing command_giver) is fixed in r2539.
(0002173)
zesstra   
2012-12-09 02:47   
I am not sure that prompting for passwords is a generally good idea in the driver.
(e.g. launching it by init, non-interactive shells, reloading key files, automatic respawn after crashes etc.)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
885 [LDMud 3.6] Efuns minor always 2020-09-28 21:03 2021-04-06 23:23
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: MacOS X  
Priority: normal OS Version: 10.9.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.4  
    Target Version:  
Summary: to_struct causes error for to many array members for template struct
Description: The manpage of to_struct states that surplus array members are ignored when converting an array to a struct.
But instead to_struct() causes an error "Too many elements for struct ...: 7, expected 4" in this case.

Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0002555)
Gnomi   
2020-09-28 21:33   
So, do we change the documentation or the efun implementation?
(0002556)
Gnomi   
2020-11-06 17:19   
Fixed in my branch: https://github.com/amotzkau/ldmud/commit/e190dbd84bbd1b7e1b6a18122c445fefe16bdc6f

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
263 [LDMud 3.6] LPC Compiler/Preprocessor feature N/A 2004-11-27 00:14 2021-04-06 23:22
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.8 and before  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.4  
    Target Version:  
Summary: Default arguments in functions
Description: Short: default arguments for functions
Date: 2001-09-17
From: Dafire
Type: Feature
State: New

Allow default arguments in function definitions, e.g.

mixed foo (string test, string *data = ({}) )
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
740 [LDMud 3.6] LPC Language minor always 2010-03-26 09:03 2021-04-06 23:21
Reporter: Bardioc Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.4  
    Target Version:  
Summary: foreach(int foo : foo) compiles without definition of 'foo' in outer scope
Description: I found this problem because of an error. If you write

   foreach (int foo : foo)
   {
   }

the compiler will compile this and it will not lead to any runtime error, just work. 'foo' has not been defined in an outer scope.

This is always reproducable in 3.5.0 (newest svn-revision)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
887 [LDMud] LPC Compiler/Preprocessor crash always 2021-03-30 17:01 2021-03-30 19:04
Reporter: fufu Platform:  
Assigned To: fufu OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: compiler crashes when combining bytes and string literal
Description: Compiling the expression `b"" + ""` causes ldmud to crash.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002562)
fufu   
2021-03-30 17:15   
See also https://github.com/ldmud/ldmud/pull/56

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
876 [LDMud 3.6] Efuns feature always 2020-04-26 08:57 2020-09-01 22:41
Reporter: iago4 Platform:  
Assigned To: Gnomi OS:  
Priority: low OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.3  
    Target Version:  
Summary: Unicode character width efun would still be handy in 3.6
Description: I have been looking through the Unicode implementation in the 3.6x series and see that everything I wanted (reported as iago3) has been implemented seamlessly and simply, with one exception.

I believe there is still value in an efun that returns string width (in terms of how many onscreen columns the string takes up). This could be used for functions that attempt to fit or wrap text to a user's display. Unicode characters can take up more (or less) than one fixed-width space, so counting characters with sizeof() is not the same thing.

I had initially reported this with all of the other Unicode feature request bugs in bug#434, but it was closed with the others when the 3.6 Unicode plan was implemented. I have included a working sample implementation for an efun that accepts either a string or an array of int Unicode code points, and returns the width. I call it wcswidth() because that is the name of the underlying C function, but you could call it something simpler. If you want to avoid creating another new efun, you could add this functionality to the existing widthof() efun, which only accepts mappings right now.
Tags:
Steps To Reproduce:
Additional Information: /*-------------------------------------------------------------------------*/
#include <wchar.h>

svalue_t *
f_wcswidth (svalue_t * sp)

/* EFUN wcswidth()
 *
 * int wcswidth(string str|int *)
 *
 * Returns the number of screen columns the given string or array of wide characters will take up
 */

{
    size_t charwidth, wcdest_width, i;
    wcdest_width=0;
    if (sp->type == T_STRING) {
        size_t wcdest_len, orig_len, len;
        wchar_t *wcdest, *current_wchar;
        char *orig_txt, *tmp_txt, **orig_txt_ptr;
        orig_len=mstrsize(sp->u.str);
        orig_txt=get_txt(sp->u.str);
        orig_txt_ptr=malloc(sizeof(char *));
        wcdest=malloc((orig_len+1)*sizeof(wchar_t));
        wmemset(wcdest,(wchar_t)0,orig_len+1);
        wcdest_len=0;
        len=0;
        tmp_txt=orig_txt;
        *orig_txt_ptr=orig_txt;
        while(len<orig_len) {
            wcdest_len+=mbsrtowcs(wcdest+wcdest_len, (const char **)orig_txt_ptr, orig_len-len, (mbstate_t *)NULL);
            len+=strlen(tmp_txt);
            if(len<orig_len) {
                len++;
                wcdest_len++;
                tmp_txt=orig_txt+len;
                *orig_txt_ptr=tmp_txt;
            }
        }
        current_wchar=wcdest;
        for(i=0;i<wcdest_len;i++) {
            if(*current_wchar=='\t') charwidth=8; /* tabs count as eight columns wide -- why? more accurate than zero! */
            else if(*current_wchar>=0xf2040 && *current_wchar<=0xf204f) charwidth=0; /* for tengwar PUA implementation */
            else charwidth=wcwidth(*current_wchar);
            if(charwidth>0) wcdest_width+=charwidth;
            current_wchar++;
        }
        free(wcdest);
        free(orig_txt_ptr);
        free_string_svalue(sp);
        put_number(sp, (p_int)wcdest_width);
    } else if(sp->type == T_POINTER) {
        vector_t *vec;
        svalue_t *svp;
        vec=sp->u.vec;
        for(i = 0, svp = vec->item; ++i <= VEC_SIZE(vec); svp++) {
            if(svp->type == T_NUMBER) {
                if(svp->u.number=='\t') charwidth=8; /* tabs count as eight columns wide -- why? more accurate than zero! */
                else if(svp->u.number>=0xf2040 && svp->u.number<=0xf204f) charwidth=0; /* for tengwar PUA implementation */
                else charwidth=wcwidth(svp->u.number);
                if(charwidth>0) wcdest_width+=charwidth;
            }
        }
        free_svalue(sp);
        put_number(sp,wcdest_width);
    }
    return sp;
} /* f_wcswidth() */
Attached Files:
Notes
(0002523)
iago4   
2020-04-27 20:30   
I should add that the character-specific code for Private Use Area Tengwar characters should probably be removed from a driver implementation and handled on the mudlib-side. The character-specific code for tabs should probably remain.
(0002533)
iago4   
2020-07-16 17:45   
Bugfix for the previous code (it checked for a size_t negative value that would never happen):

/*-------------------------------------------------------------------------*/
#include <wchar.h>

svalue_t *
f_wcswidth (svalue_t * sp)

/* EFUN wcswidth()
 *
 * int wcswidth(string str|int *)
 *
 * Returns the number of screen columns the given string or array of wide characters will take up
 */

{
    size_t charwidth, wcdest_width, i;
    wcdest_width=0;
    if (sp->type == T_STRING) {
        size_t wcdest_len, orig_len, len;
        wchar_t *wcdest, *current_wchar;
        char *orig_txt, *tmp_txt, **orig_txt_ptr;
        orig_len=mstrsize(sp->u.str);
        orig_txt=get_txt(sp->u.str);
        orig_txt_ptr=malloc(sizeof(char *));
        wcdest=malloc((orig_len+1)*sizeof(wchar_t));
        wmemset(wcdest,(wchar_t)0,orig_len+1);
        wcdest_len=0;
        len=0;
        tmp_txt=orig_txt;
        *orig_txt_ptr=orig_txt;
        while(len<orig_len) {
            wcdest_len+=mbsrtowcs(wcdest+wcdest_len, (const char **)orig_txt_ptr, orig_len-len, (mbstate_t *)NULL);
            len+=strlen(tmp_txt);
            if(len<orig_len) {
                len++;
                wcdest_len++;
                tmp_txt=orig_txt+len;
                *orig_txt_ptr=tmp_txt;
            }
        }
        current_wchar=wcdest;
        for(i=0;i<wcdest_len;i++) {
            if(*current_wchar=='\t') charwidth=8; /* tabs count as eight columns wide -- why? more accurate than zero! */
            else if(*current_wchar>=0xf2040 && *current_wchar<=0xf204f) charwidth=0; /* for tengwar PUA implementation */
            else charwidth=wcwidth(*current_wchar);
            if(charwidth!=(size_t)-1) wcdest_width+=charwidth;
            current_wchar++;
        }
        free(wcdest);
        free(orig_txt_ptr);
        free_string_svalue(sp);
        put_number(sp, (p_int)wcdest_width);
    } else if(sp->type == T_POINTER) {
        vector_t *vec;
        svalue_t *svp;
        vec=sp->u.vec;
        for(i = 0, svp = vec->item; ++i <= VEC_SIZE(vec); svp++) {
            if(svp->type == T_NUMBER) {
                if(svp->u.number=='\t') charwidth=8; /* tabs count as eight columns wide -- why? more accurate than zero! */
                else if(svp->u.number>=0xf2040 && svp->u.number<=0xf204f) charwidth=0; /* for tengwar PUA implementation */
                else charwidth=wcwidth(svp->u.number);
                if(charwidth!=(size_t)-1) wcdest_width+=charwidth;
            }
        }
        free_svalue(sp);
        put_number(sp,wcdest_width);
    }
    return sp;
} /* f_wcswidth() */
(0002534)
Gnomi   
2020-07-16 17:51   
The current master (not released, yet) has a new efun text_width(), which calculates the on-screen width of a given text.
(0002554)
Gnomi   
2020-09-01 22:41   
The new efun text_width() calculates the displayed width for a string.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
881 [LDMud 3.6] Efuns minor always 2020-08-06 01:24 2020-09-01 22:40
Reporter: humni Platform:  
Assigned To: Gnomi OS:  
Priority: low OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.3  
    Target Version:  
Summary: sprintf problems concerning ANSI-Codecs
Description: In Morgengrauen, we have ANSI-Codecs which change the colour of the code.
They have a "size" (meaning: sizeof(ANSI_BOLD) has a value>0).
But of course, there is no character if you see the text displayed, just a change in the color.

If you now use sprintf on some "coloured" strings, the behaviour is not consistent:

sprintf("%-*s%s\n",22,ANSI_BLUE+ANSI_BOLD+"Text"+ANSI_NORMAL,"Text")
will return a blue Text with 18 following Spaces, followed by Text. This is how I would expect sprintf to work.

But

sprintf("%-*s%s\n",12,ANSI_BLUE+ANSI_BOLD+"Text"+ANSI_NORMAL,"Text")
will return
TextText

with the first Text blue and the second Text not.

Probably this happens because sprintf thinks the first Text is longer than 12 characters and doesn't change it. This may be, because

sizeof(ANSI_BOLD+ANSI_BLUE+"Text"+ANSI_NORMAL);

is 18.


Tags: sprintf
Steps To Reproduce: Using a Morgengrauen Mudlib, you may use this code:

#include <ansi.h>

#define TI this_interactive()

protected void create()
{
  tell_object(TI,"01234567890123456789012345678900123456789012345678901234567890\n");
  tell_object(TI,sprintf("%-*s%s\n",22,ANSI_BLUE+ANSI_BOLD+"Text"+ANSI_NORMAL,"QTEXT"));
  tell_object(TI,sprintf("%d\n",sizeof(ANSI_BLUE+ANSI_BOLD+"Text"+ANSI_NORMAL+"\n")));
  tell_object(TI,sprintf("%-*s%s\n",12,ANSI_BLUE+ANSI_BOLD+"Text"+ANSI_NORMAL,"QTEXT"));
}

and then just load the object.

The 18 is the length mentioned above. The first line (after the numbers to see how long the string is) seems to be as expected, the last line is not.

As a Morgengrauen mage, you may just load the object from /players/humni/temp/test1.c
Additional Information:
Attached Files:
Notes
(0002538)
zesstra   
2020-08-06 01:53   
Additional info - the defines are as follows:
#define ANSI_BOLD "ESC[1m"
#define ANSI_BLUE "ESC[34m"
#define ANSI_NORMAL "ESC[0m"
(0002539)
Gnomi   
2020-08-06 12:12   
I fixed this in my 363preparations branch that will eventually go into LDMud 3.6.3: https://github.com/amotzkau/ldmud/commit/701ff0710ddd42ef27afb5b93ce8f6294a991a49

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
878 [LDMud 3.6] Efuns minor always 2020-05-06 23:44 2020-09-01 22:38
Reporter: realms-mud Platform: x64  
Assigned To: Gnomi OS: Solaris  
Priority: normal OS Version: 11.4.20.4.0  
Status: resolved Product Version: 3.6.2  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.3  
    Target Version:  
Summary: Regular Expressions somewhat broken with 3.6.2
Description: When switching from the 3.6.1 driver to the 3.6.2 driver, I noticed that several hundred regular expression-based checks in my tests no longer work. There are work-arounds for most and I'll even agree that some of the workarounds are "more elegant" and/or "better", but previously-working valid syntax should still be honored. Both regexp and regreplace are affected.

In the "steps to reproduce", I'll give a few examples.
Tags:
Steps To Reproduce: For simplicity, consider the following method to evaluate whether or not a regexp matches a passed string:

/////////////////////////////////////////////////////////////////////////////
public void ExpectSubStringMatch(string regularExpression, string evaluatedString)
{
    if (!sizeof(regexp(({ evaluatedString}), regularExpression)))
    {
        debug_message(" -> Actual: " + evaluatedString+ ", Expected: " + regularExpression+ "\n",
            0x5);
    }
}

Here's a few that fail with the changes that were made in 3.6.2:

    ExpectSubStringMatch("Optional.*Leather needed.*1.*Metal needed.*10",
        "This option lets you craft: long sword\n"
        "Prerequisites:\n"
        " Skill: Blacksmithing of 1\n"
        " Research: Craft Long Swords\n"
        " Skill: Weapon smithing of 8\n"
        " Skill: Metal crafting of 1\n"
        "\n"
        "Materials:\n"
        " (Optional) Crystal can be used to embellish the design\n"
        " Leather needed: 1\n"
        " Metal needed: 10\n"
        " Wood needed: 1\n");

    ExpectSubStringMatch("Blah blah blah.*This item contains the following.*.3. Long sword",
        "Blah blah blah\nThis item is typical for its type.\n\n"
        "+-=-=-=-=-=-=-=-=-=-=-+ This item contains the following +=-=-=-=-=-=-=-=-=-=-+\n"
        "| Battle axe Healing Potion [3] Long sword |\n"
        "| Mana Potion Short sword |\n"
        "+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+");
-> Digging further, it looks like two wildcards in a row don't work any longer (ie: the '.*.' was the culprit here. Likewise, in another test, '..' did not evaluate correctly)

    ExpectSubStringMatch("Dracolich Form.*[*].*Dragon",
        "Dracolich Form (*) [12] - Dragon Form");
-> With this, it doesn't appear to like the [*]. "Dracolich Form.*\\*.*Dragon" evaluates. Interestingly, so does "Dracolich Form[^*]+\\*.*Dragon" (ie: not-in-set succeeds, but in-set does not in this case)
Additional Information:
Attached Files:
Notes
(0002531)
Gnomi   
2020-05-07 02:37   
Thank you for catching that. The regexp matching functions communicate mostly via global variables and I overlooked some side effect of that.

A fix is in my branch: https://github.com/amotzkau/ldmud/tree/363preparations
(0002532)
realms-mud   
2020-05-07 18:08   
Thanks for the super-fast response!

I ran your fix through my test suite and everything is working as expected.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
880 [LDMud 3.6] LPC Compiler/Preprocessor minor always 2020-07-28 01:22 2020-09-01 22:38
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: GNU/Linux  
Priority: normal OS Version: 0  
Status: resolved Product Version: 3.6.2  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.3  
    Target Version: 3.6.3  
Summary: Repeated calls to undefined function trigger warning due to strict_types without strict_types being in effect.
Description: When calling an undefined function twice (!) as part of an expression in the arguments to a callother, in addition to the error message "Undefined function ...", the warning "Function call result must be casted due to pragma strict_types" ist triggered.

Compiling this code fragment:
int seite;

mixed test()
{
  this_player()->more(buchdir()+"seite"+seite);
  this_player()->more(buchdir()+"titel");
  return 1;
}

causes the errors:
players/zesstra/foo.c line 5 before '+"seite"+s': Undefined function 'buchdir'
players/zesstra/foo.c line 6 before '+"titel");': Function buchdir undefined
players/zesstra/foo.c line 6 before ';': Function call result must be casted due to pragma strict_types

This is certainly confusing. However, I am not sure, whether it warrants fixing since compiler errors after the first one are often not reliable.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0002536)
Gnomi   
2020-07-28 17:15   
https://github.com/amotzkau/ldmud/commit/826bf5bdecea904face452b6df006fe542958d8f
(0002537)
zesstra   
2020-07-28 23:25   
Ah, yes. Makes sense. I cherry-picked it into the driver we will use tomorrow for reboot.
(0002540)
Rastullah   
2020-08-06 15:29   
Executing the following code reproduces the issue as well:

create()
{
  unknown_function(this_object());
}

testfun()
{
  return (!unknown_function(previous_object()));
}
(0002541)
zesstra   
2020-08-06 19:11   
It should be noted, that this is with a driver containing the commit https://github.com/amotzkau/ldmud/commit/826bf5bdecea904face452b6df006fe542958d8f
(0002542)
Gnomi   
2020-08-06 19:54   
Improved commit: https://github.com/amotzkau/ldmud/commit/055f19c9fef3388f812fbe1f51e24c16ea5ad7a5

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
883 [LDMud 3.6] LPC Compiler/Preprocessor feature always 2020-08-15 10:50 2020-09-01 22:37
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: MacOS X  
Priority: normal OS Version: 10.9.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.3  
    Target Version:  
Summary: structs: compatibility of inherited (super) struct in place of inheriting (sub) struct
Description: A fellow wizard in Morgengrauen sent me the following comment/suggestion:

---
I played with the struct type and came up with the following snippet:

--8<--
#pragma strong_types, rtt_checks

struct A {
  int one;
};

struct B (A) {
  int two;
};

void test () {
  struct B b = (<A> 100);
}
--8<--

This snippet compiles with LD 3.6.2. The assignment in test() is not
type-safe because a super type is assigned to a sub type. The compiler
accepted this and therefore the issue is only signaled at run time
with the error "Bad type for assignment: got 'struct A', expected
'struct B'." Would it be an improvement if the compiler rejected this
as invalid?
---
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0002546)
zesstra   
2020-08-15 10:52   
(Last edited: 2020-08-15 10:55)
Gnomi pointed out yesterday, that the behaviour is in principle consistent with the handling of other types, especially unions. Indeed, that situation is similar to:
int|float var;
int i;
In this case not only var=i; is allowed at compile-time, but also i=var, because *at runtime* var might actually point to an int and the assignment is legal:
var = 42;
i = var;

In cases of structs it is comparable to this case:
struct A {};
struct C(A) {};
struct A a;
struct C c;
c = a is allowed at compile-time, because at runtime, 'a' might contain an instance of struct C and the compiler in general doesn't know that. (We just don't have a type-tracking in the compiler that is capable of that.)
a = (<C>);
c = a; // valid

However, in this case of struct literals, the compiler does know that the assignment will be illegal at runtime. It would be consequent to dis-allow it at compile-time, like in the case of 'int i = 0.0';
(Although it is arguably a special case and might not be very common.)


View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
879 [LDMud 3.6] Runtime crash always 2020-07-27 19:30 2020-09-01 22:36
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: GNU/Linux  
Priority: high OS Version: 0  
Status: resolved Product Version: 3.6.2  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.3  
    Target Version: 3.6.3  
Summary: Crash in collect_trace() during runtime error handling
Description: During the handling of an argument type error in functions arguments, the driver crashed with a segmentation fault while accessing a string.

#0 get_txt (s=<optimized out>) at mstrings.h:278
No locals.
0000001 collect_trace (sbuf=sbuf@entry=0x7fff6bd10c10,
    rvec=rvec@entry=0x559eabbc7be8 <current_error_trace>) at interpret.c:18979
        dump_pc = <optimized out>
        prog = <optimized out>
        dump_eval_cost = 1
        p = 0x559eabb58d90 <control_stack_array+272>
        ret = 0x0
        pc = <optimized out>
        line = 366
        name = "clean_up"
        file = "d/schattenwelt/ennox/pentarena/std/arena_master.c"
        ob = 0x0
        last_catch = 0x0
        first_entry = 0x0
        last_entry = 0x0
        num_entries = 0
0000002 0x0000559eaae81e69 in dump_trace (how=<optimized out>,
    rvec=rvec@entry=0x559eabbc7be8 <current_error_trace>,
    rstr=rstr@entry=0x559eabbc7bd8 <current_error_trace_string>) at interpret.c:19059
        sbuf = {alloc_len = 0, length = 0, buf = 0x0}
        hb_obj_name = <optimized out>
0000003 0x0000559eaaede6d2 in errorf (fmt=<optimized out>,
    fmt@entry=0x559eaaf04ba0 "Bad arg %d to %s(): got '%s', expected '%s'.\n")
    at simulate.c:1009
        rt = 0x7fff6bd118f0
        object_name = 0x0
        ts = <optimized out>
        svp = <optimized out>
        error_caught = <optimized out>
        published_catch = false
        do_save_error = <optimized out>
        file = <error reading variable: Cannot access memory at address 0x6>
        malloced_error = "Bad arg 1 to clean_up(): got 'int', expected 'object'.
"
        malloced_file = <optimized out>
        malloced_name = <optimized out>
        curobj = <optimized out>
        fixed_fmt = "Bad arg %d to %.200s(): got '%.200s', expected '%.200s'.\n\000\377\377\377\377\377\377\000\000\000\000\020+\000\000X\000\000\000\000\000\000\000)\017\000\000\000\000\000\000q\356\361\252\236U\000\000\000\000\000\000\000\000\000\000 Õµ\253\236U\000\000\200\001\000\000\000\000\000\000\335u爵U\000\000\000\000\000\000\000\000\000\000@Õµ\253\236U\000\000\003\000\000\000\000\000\000\000\310\330f\234\003\177\000\000\060\000\000\000\000\000\000\000`\023U\000\000Y\017\321k\377\177\000\000\005\000\000\000\000\000\000\000\270\330f\234\003\177\000\000`Õµ\253\236U\000\000"...
        line_number = <optimized out>
        va = {{gp_offset = 40, fp_offset = 48, overflow_arg_area = 0x7fff6bd115a0,
            reg_save_area = 0x7fff6bd114b0}}
0000004 0x0000559eaae7f776 in check_function_args (fx=<optimized out>,
    progp=0x-378ea610 "d/schattenwelt/ennox/pentarena/std/arena_master.c",
    funstart=0x7f03c8716442 "\036") at interpret.c:6485
        num_csf = 0
        buff = "int\000d*\000|object>*", '\000' <repeats 495 times>
        firstarg = <optimized out>
        formal_args = 1
        i = 0
        arg_type = <optimized out>
        header = 0x7f03c8716a10
0000005 0x0000559eaae90168 in apply_low (fun=fun@entry="clean_up",
    ob=ob@entry=0x-428eff90 "d/schattenwelt/ennox/pentarena/std/arena_master",
    num_arg=num_arg@entry=1, b_ign_prot=b_ign_prot@entry=false) at interpret.c:16818
        funstart = 0x7f03c8716442 "\036"
        fx = <optimized out>
        progp = <optimized out>
        save_csp = <optimized out>
        ix = 79860
0000006 0x0000559eaae90cb3 in int_apply (fun=fun@entry="clean_up",
    ob=ob@entry=0x-428eff90 "d/schattenwelt/ennox/pentarena/std/arena_master",
    num_arg=num_arg@entry=1, b_ign_prot=false, b_use_default=b_use_default@entry=true)
    at interpret.c:16901
No locals.
0000007 0x0000559eaae9116c in sapply_int (fun="clean_up",
    ob=ob@entry=0x-428eff90 "d/schattenwelt/ennox/pentarena/std/arena_master",
    num_arg=num_arg@entry=1, b_find_static=b_find_static@entry=false,
    b_use_default=b_use_default@entry=true) at interpret.c:17063
        expected_sp = 0x-544a2d60 T_INVALID
0000008 0x0000559eaae91317 in apply (fun=<optimized out>,
    ob=ob@entry=0x-428eff90 "d/schattenwelt/ennox/pentarena/std/arena_master",
    num_arg=num_arg@entry=1) at interpret.c:17103
No locals.
0000009 0x0000559eaae40745 in process_objects () at backend.c:1424
        save_reset_state = 256
        svp = <optimized out>
        time_since_ref = 90001
        min_time_to_swap = 300
        bResetCalled = false
        did_reset = true
        did_swap = true
        obj = <optimized out>
        limit_data_clean = <optimized out>
        error_recovery_info = {rt = {last = 0x559eabbc7c60 <toplevel_context>, type = 1},
          flags = -1402174672, con = {text = {{__jmpbuf = {94139974753824,
                  -2192059183495383761, 139653571421912, 0, 1, 139653495107176,
                  -5379622419619121873, -2192057245403581137}, __mask_was_saved = 0,
                __saved_mask = {__val = {139653495107176, 140735002253748, 110,
                    1595862920, 1, 139654383158432, 140735002253816, 139654383158432,
                    140735002253816, 94139974753824, 94139974753824, 139653571421912, 0,
                    1, 139653495107176, 140735002253824}}}}}}
0000010 0x0000559eaae41381 in backend () at backend.c:1014
        cur_time = {tv_sec = 1595862921, tv_usec = 1049}
        buff = "teile afunial mit 16+2", '\000' <repeats 978 times>...
        bufflength = 15
        prevent_object_cleanup = false
0000011 0x0000559eaae34030 in main (argc=<optimized out>, argv=<optimized out>) at main.c:708
        i = 5
        p = 0x7fff6bd16be8 "\005"
        set = {__val = {8192, 0 <repeats 15 times>}}
        rc = 0
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0002535)
zesstra   
2020-07-27 19:36   
"d/schattenwelt/ennox/pentarena/std/arena_master.c" defined the clean_up() as follows:

public void clean_up(object pl);

which obviously causes a runtime error, when the driver calls it during clean_up handling. My first idea is, that this might be relevant, but had not time so far to check for it.
(0002553)
Gnomi   
2020-09-01 22:36   
Also fixed in 3.5.3

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
699 [LDMud 3.6] General feature N/A 2009-11-02 14:58 2020-09-01 22:35
Reporter: Bardioc Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.3  
    Target Version: 3.5.1  
Summary: save/restore of structs
Description: The current implementation to save/restore structs is at least to say dangerous to use at all.

In LPC structs are internally implemented as arrays and saved in the way that their definition position (program name) comes first, followed by the elements ordered in the way of occurrence in the structure.

This is ambiguous in many ways:

1. what happens in case the struct is changed and a member is added not to the end, but in the middle or front of the structure?

A restore will cause a severe problem as wrong values are restored to wrong members!!!!!

2. what happens in case a struct hierarchy is build and a member is added to the super-type. Where is this member placed in the save file?

This is very dangerous, as it might be forgotten that the subtype and thus a save value of it changes too.

Suggestions:

Change the way structs are saved (implies a new save format)

Solution 1: Include the struct declarations in a separate part of the save-file and use the indices to restore the struct based on this additional information. At places where the struct is saved, positions relative to the declaration can be used. Compare saved declaration with current declaration and initialize all found members. Initialize all not found members with 0

Solution 2: Save the name of the member together with its value. Initialize the member if found in the current declaration, ignore if not found. Initialize all others with 0.

The second solution would cause the save files to become bigger as member names have to be saved at every occurrence.

ADDITION:

When thinking of the before mentioned problem of added struct members in between or in super types, the possibility to access members by index or initialization of structs by index should be forbidden as it might lead to hard to find errors. Imagine the following example:

struct foo
{
     string x;
};

struct baa (foo)
{
     string y;
};

struct baa mystruct = (<baa> "a", "b");

printf("x = %O, y = %O\n", mystruct->x, mystruct->y);
printf("x = %O, y = %O\n", mystruct->(0), mystruct->(1));

Exam question: what is the result?
Solution:

x = "a", y = "b"
x = "a", y = "b"

So what happens if some wizard now changes the struct foo in this way:

struct foo
{
     string x;
     string z;
}

Question: What is the result now?

x = "a", y = 0
x = "a", y = "b" <== this line is not telling the truth ... z = "b"

See the problem?

Because of all this i would strongly suggest to REMOVE the indexing by position as well as the initialization by position. I now this might break code, but this behavior is simply too dangerous to be permitted.

Any comments are welcome. Lets start a discussion here :-)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001582)
zesstra   
2009-11-02 15:10   
I discussed this briefly with Bardioc in private and I concur with this.
The issue with saving/restoring must definitely be addressed.
In addition to the names of the members we should also save the types of the members. Otherwise a change from struct a_s {int x;}; to struct a_s {mapping x;}; is not recognized. It may be bad style to do such a thing, but I think, it is our responsibility to check for this.

Concerning the indexing with numbers: We could assume, that every wizard has to right to shot himself in the foot... But I tend to agree with Bardioc. We might change remove it only in 3.5, so there will be no severe change in language during 3.3...
(0001584)
_xtian_   
2009-11-02 16:43   
Access through the numbers is useful to iterate through the struct elements.

I agree that it invites error prone code, but it also may be used to do something like:

// initialize all elements
for(i;i<sizeof(s);i++)
  s->(i)= ...;

I have already used it for similar things.
(0001585)
zesstra   
2009-11-02 17:42   
I also thought of that way to use this notation. As a comment, a simple way to achieve that result without indexing the struct itself would be to use to_struct() and to_array(). Both should be fairly efficient (because internally structs and arrays are so similar).
So for initialization one could use:
struct a_s a = to_struct(m_allocate(x,42.7), (<a_s>));
Or populate an array with individual values. Depending on the exact conditions, this _might_ be even faster than a for loop in LPC.
Of course, both is just as dangerous as the for loop. ;-)

On the other hand, if we keep indexing by numbers, there should be a HUGE warning sign in the documentation, both about indexing and struct literals.
(0001597)
Gnomi   
2009-11-04 04:45   
Concerning the type of the members: I think that this should depend on the RTTC pragma. It's the goal that assignments to variables have their type checked at runtime as well and exactly the same should restore_object do with normal variables and struct members.
(0001603)
zesstra   
2009-11-04 18:32   
Ultimately, I agree with Gnomi.
I added checks for the types of restored variables and members of structs in restore_object()/restore_struct() in 3.5. (trunk, r2798+r2799).

Concerning savefile formats: I would prefer a format which stores the struct definition separately from the variables, because it is more compact. We can write the definition before the first struct variable using it.
Interesting questions here are: could such a definition be used to create a struct type if there is none? The use of such structs would be limited, but if such a struct inherits from a base struct still existing, it might be useful. But what if a program defining the correct struct type is loaded later...?
(0001604)
zesstra   
2009-11-04 18:47   
Ah, BTW: concerning the types there are two things:
a) check upon restore the correct types. This should depend on RTTC.
b) storing the types of members in the savefile to distinguish between two structs (old in the savefile, new one in the program) having members with the same name but different types. Here I am not so sure. So if the first a_s is in the savefile and the second in the program, the struct type from the savefile could be just regarded as unknown (and we don't restore unknown structs right now...):
struct a_s {int x};
struct a_s {string x};
(0001610)
_xtian_   
2009-11-05 16:12   
Correct me if I misunterstood, but the only legal form af a struct should be the one that has been compiled to date (the time of the restore). If a save-file containes a struct-definition it should only be used to compare it to the target format of the struct and to possibly convert it. The data in the save-file should not generate a new struct sub-type that has not been declared in running code.
Else strange old struct definitions could always crop up and lead to unclear errors that are not reproducible.

I even think that restoring to an unknown struct-type should throw an error because it is unpredictable what would happen next.

Also concerning the last note: Doesn't b) ==> a) ?
(0001612)
zesstra   
2009-11-05 16:38   
a) just means that we check if the member of the current struct is allowed to hold the type in the savefile. That you can do without having the struct definition saved.

b) is to compare the types of members of the current struct and the struct in the savefile (so the struct at the time of save_svalue()) to find structs having the same members but different types.
(0001735)
zesstra   
2010-02-16 16:17   
I think we should discuss a reasonable savefile format to store the struct definitions at the time of the save_svalue()...
As I said I would prefer to store the struct template only once in the savefile and not for every occurrence of a struct of that type. In that case we need to store the definitions before any variables using them, I would just argue for putting it before any variables.
But we also run into the problem of nested structs and struct inheritance and how to represent that. We might first store a list of structs referenced in the savefile and after that a block with struct definitions. In case of inheritance chains both lists may be sorted base-struct-first.
(0001738)
_xtian_   
2010-02-16 18:36   
There is also save/restore_value() to consider. As with save/restore_object() the question is, if it could be used to generate struct definitions at runtime - in my last comment I made my argument against that.

Maybe the easiest way to change the savefile format would be to dictate declared-where-first-used rule. In a one value format like save_value() this would change nothing. In a save_object() szenario the first saved definition of the struct would be used for all following ones with the same name. My two cents.
(0001739)
zesstra   
2010-02-17 05:18   
Yes, I agree with argument against generating struct definition upon restoring structs.

Ok, we can also mix the definition between the variables. But I think it might make things more complicated: if a mapping/array/struct contains a struct we have to write the struct definition before the variable which contains them. And if we write the defs when we reach a struct in a mapping, we already wrote a part of the mapping to the buffer. But IMHO we should not mix variables contents with 'inline' struct definition. A solution might be to write the defs to a different buffer and concatenate them in the end. But because we anyway iterate two times over the variables of an object and we anyway can't write the defs within a save_svalue() (because then the variable name was already written) we might also write all used struct defs in the beginning between header and variables...

BTW: I initially thought we don't have to care especially about inherited ones, because the members are copied to the inheritee, but then a struct might be restored which is incompatible to its (current) base struct.

BTW2: Changing the savefile format might cause problems with users of save_value(), depending on how the use it (e.g. rely on header+content are always only 2 lines), but I guess not too many use save_value().

If we read a struct definition during restore, we can directly compare the definition with the current definition in the system (if any) and abort the restore if they don't match and are not upgradable... (The other possible behaviour is to silently ignore any variables without matching struct definition, but I don't like that too much.)

Upgrading structs:
Reasonable if the current struct definition has more members or members in different sequence.
If member types changed, I would not regard them as upgradable (exception: change of 'mixed' to specific type).
If the current struct contains less members: abort the restore, ignore the struct or ignore the non-existing members? Do we issue a runtime warning?
(0001740)
_xtian_   
2010-02-17 17:42   
A valid reason for removing a struct element could be that you realized that you never really needed that element. Sometimes interfaces and data structures get smaller when they evolve. So a vanished element should not terminate the restoration of the other values. As for issuing a warning - I'm not sure.
(0002262)
Gnomi   
2015-08-16 18:35   
I wouldn't go that far to include a full struct definition. It's not relevant.

All we want is to put the saved values back into a struct in the most sensible way. It doesn't matter if the current struct has other base structs than the saved struct, as long as all the members are there. Also if earlier the member was int|string and is now only int, that is not an obstacle as long as the saved value is an integer.

So for me are the RTT checks enough. If the concrete value type in the savefile matches the currently declared member type, that's good enough. Comparing the earlier definitions with the current one is just an additional impediment that hinders transitions.

That's why I would stick with the problem at hand: Added/removed members and changed order of them. For this we just need the name of the members at the time of saving (and the name of the struct). And there are two problems to discuss:

1. How to format this information?
I don't have a strong opinion on this one. Because save_value(({(<s>)})) must also work (and most programs expect save_value to return exactly two lines), I think it would be best to be inlined with the content.
Something like (<"struct_name filename.c 0000001 member1,member2,member3">,1,2,3)
where all future occurrences can have (<"struct_name filename.c 0000001">,5,6,7).
The 0000001 would be a savefile-internal counter and not the struct id that it is now (because the structname/filename is not enough, there might be two different versions of a struct of the same name floating around).

2. What to do with vanished members?
Because restore_objects also ignores vanished variables, I would do the same with vanished members. Ignore silently. Otherwise the removal of a member would be a big pain (you have to modify all savefiles *by hand* or give the struct a new name and load/copy to new struct/save for each file).
(0002551)
zesstra   
2020-08-25 20:39   
Uh, long forgotten...
After re-thinking about this, I think, I agree with Gnomi so far.
Concerning the format: I also don't have a strong opinion about it and my suggestion is to choose whichever has advantages for the implementation of save_*/restore_*. Both variants are compact concerning the savefile size, but the inline variant might save a loop. It complicates reading the savefile by a human, but not too much.
(0002552)
Gnomi   
2020-08-25 20:42   
This is implemented in https://github.com/amotzkau/ldmud/commit/bebb18e80164d5f1f5069aff51e60b7382a5267a.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
884 [LDMud] Implementation minor always 2020-08-15 11:07 2020-08-24 00:19
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: MacOS X  
Priority: normal OS Version: 10.9.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: to_struct: error converting related structs
Description: When the program given below is compiled, the blueprint destroyed and loaded again, the to_struct() call fails with the error:
"Can't convert struct A struct_convert.c #548395 into struct B struct_convert.c #592866. Neither is a base of the other."

I suspect, this might be an issue with the struct reactivation when reloading programs, e.g. one is reactivated and the other not.

Tags:
Steps To Reproduce:
#pragma strong_types,pragma rtt_checks

struct A {
  int one;
};

struct B (A) {
  int two;
};

void test () {
  struct B b = to_struct((<A> 100), ());
} 
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0002550)
Gnomi   
2020-08-24 00:19   
Fixed in my 363preparations branch.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
838 [LDMud] LPC Compiler/Preprocessor major always 2015-01-09 00:10 2020-08-24 00:19
Reporter: Gnomi Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Struct reactivation fails when used in complex types
Description: When a program is recompiled (destroyed and loaded again) the compiler tries to match struct definitions. It does this by comparing the new definitions in the new program with old ones still present in the memory that have the same name (program name + struct name). If they're the same it replaces the new struct type with the old one in: other struct definitions, variable definition, function return types and function arguments. In the end if no struct definitions have changed they should be the same as before (remember that struct definitions are inherited, so they may be inheritors that have inherited the old ond some the new program, they should still be able to exchange structs).

This approach has several drawbacks:
1. The replacement only looks at plain struct types, not at arrays of this struct or union types with this struct (or arrays of unions with the struct or unions with the array of struct, or array of array of structs and so on...) Therefore functions returning such complex types or structs containing complex types with a to-be-reactivated struct still refer to the new struct that shouldn't exist anymore.

2. Self referencing structs won't get reactivated. A struct like
  struct list { struct list next; };
will never be regarded as the same definition, because its member type is different (it references -of course - the new struct list, not the old one), therefore it's a change in the definition.

3. Deliberate changes of the definition of structs breaks LPC code. If I add a member to a struct, this struct logically can still be accessed by every object that expects the old struct definition (it has all the old members), but the LPC runtime regards them as entirely different types and thus throws RTTC errors. This might also be true when I remove a member (I might do a carefully planned transition where at the end I remove deprecated members), but it is not possible during runtime, because the types change.


1. is a regressions introduced by the union type system: Before that there were no complex types except arrays of structs and these were handled. Now replacing them within complex types is computationally expensive.

2. is also a regression, originally members that are structs themselves were compared by their definition. This can be fixed. But note that this in-depth comparision needs also be done for complex types (arrays and unions containing structs).

3. is a conceptual problem.

To solve 3 (and thus solve 1 and 2), I propose that structs should be treated as equal (for type check purposes) when they have the same name and the same defining program. When Code accesses a struct that has another definition then the code was compiled with: Do a lookup by member name. If the member does not exist, then read-access shall return 0 and write access shall throw an error.
Tags:
Steps To Reproduce: Testcase (another testcase is attached)
=======================================

master.c
--------
#include "/inc/base.inc"

void run_test()
{
    int errors;
    object ob;

    msg("\nRunning test for #0000xxx:\n"
          "--------------------------\n");

    load_object("a1");
    destruct(find_object("i"));
    ob = load_object("a2");

    shutdown(catch(ob->test()) && 1);
}

string *epilog(int eflag)
{
    run_test();
    return 0;
}

a1.c
----
inherit "i";

a2.c
----
inherit "i";

i.c
---
#pragma save_types, strong_types, rtt_checks

struct abc
{};

struct abc* fun() { return ({ (<abc>) }); }

void test()
{
    fun();
}

Additional Information:
Attached Files: tests.tgz (626 bytes) 2015-01-09 00:10
http://ldmud.eu/file_download.php?file_id=287&type=bug
Notes
(0002243)
Gnomi   
2015-01-09 00:14   
With the proposed solution the struct reactivation becomes an optimization and not a necessary language feature.
(0002249)
guest   
2015-02-12 12:59   
Fix committed in revision 44445fee9d845a46e3c2814bb3c0f86e7615b7ba to master branch (see changeset 988 for details). Thank you for reporting!
(0002274)
guest   
2016-01-20 17:31   
Fix committed in revision c15f41739f5e7fbcbac7b10eddd1f3d5df3ffff5 to 3.5.0 branch (see changeset 1046 for details). Thank you for reporting!
(0002310)
Gnomi   
2018-01-29 19:59   
Fix committed in revision 44445fee9d845a46e3c2814bb3c0f86e7615b7ba to master branch (see changeset 1405 for details). Thank you for reporting!
(0002361)
Gnomi   
2018-01-29 22:57   
Fix committed in revision 44445fee9d845a46e3c2814bb3c0f86e7615b7ba to master branch (see changeset 2732 for details). Thank you for reporting!
(0002412)
Gnomi   
2018-01-30 04:59   
Fix committed in revision 44445fee9d845a46e3c2814bb3c0f86e7615b7ba to master branch (see changeset 3818 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
873 [LDMud] Other minor always 2020-01-10 19:41 2020-04-29 00:26
Reporter: realms-mud Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: LDMud 3.6.* performance significantly worse than 3.5.0
Description: I noticed that the changes from 3.5.0 to 3.6.0 (and 3.6.1) come with a pretty significant performance hit.

Here's some output from one of my more CPU-intensive tests first running with the 3.5.0 driver and then with the 3.6.0 driver. I did test with 3.6.1, but since the speed was roughly the same as 3.6.0, I did not bother throwing that data on here as well:

First, 3.5.0:

2020.01.10 12:55:28 LDMud 3.5.0 (3.5.0) (release)
Compiling file: /lib/tests/modules/crafting/craftWeaponTest.c
Testing lib/tests/modules/crafting/craftWeaponTest
[ PASSED ] CraftSelectedOptionBecomesEnabledWhenAllCriteriaMet (5181ms)
[ PASSED ] ChoosingCraftSelectedFailsWhenDisabled (135ms)
[ PASSED ] CraftingASwordGeneratesTheCorrectItemAndReducesMaterials (197ms)
[ PASSED ] CraftingIsNotAffectedByNotApplicableLimitedByCraftingTypeResearch (186ms)
[ PASSED ] CraftingItemIsNotAffectedByCraftingBonusesWhenOfDifferentType (190ms)
[ PASSED ] CraftingItemIsAffectedByCraftingBonusesWhenOfType (188ms)
[ PASSED ] CraftingSetsEnchantments (369ms)
Test executed: lib/tests/modules/crafting/craftWeaponTest -> [ PASSED ]
 -> built in 6484 ms.


Next, 3.6.0 -

2020.01.10 12:55:48 LDMud 3.6.0 (3.6.0) (release)
Compiling file: /lib/tests/modules/crafting/craftWeaponTest.c
Testing lib/tests/modules/crafting/craftWeaponTest
[ PASSED ] CraftSelectedOptionBecomesEnabledWhenAllCriteriaMet (11437ms)
[ PASSED ] ChoosingCraftSelectedFailsWhenDisabled (370ms)
[ PASSED ] CraftingASwordGeneratesTheCorrectItemAndReducesMaterials (458ms)
[ PASSED ] CraftingIsNotAffectedByNotApplicableLimitedByCraftingTypeResearch (469ms)
[ PASSED ] CraftingItemIsNotAffectedByCraftingBonusesWhenOfDifferentType (489ms)
[ PASSED ] CraftingItemIsAffectedByCraftingBonusesWhenOfType (481ms)
[ PASSED ] CraftingSetsEnchantments (783ms)
Test executed: lib/tests/modules/crafting/craftWeaponTest -> [ PASSED ]
 -> built in 14553 ms.

For my entire test suite, the overall execution time went from roughly 6:45 minutes to around 11:00 minutes over a half dozen runs and every test in my test suite is 30% to 100+% slower. I am also able to see this performance issue in-game, but it's much harder to accurately measure. Anecdotally, I can definitely see things that take a hundred ms in 3.5 take "a lot longer" in 3.6, but my test framework is a much more reliable measure.
Tags:
Steps To Reproduce: Find any object of observable complexity with which you can evaluate a method and execute it in both 3.5 and 3.6.
Additional Information:
Attached Files: test.tar.gz (888,164 bytes) 2020-01-13 20:06
http://ldmud.eu/file_download.php?file_id=297&type=bug
Notes
(0002498)
Gnomi   
2020-01-10 20:01   
You need to give us some more code to test it on. I checked some of our tests in the test suite and they ran in the same time in both versions.
And in our production MUD we don't have any that long running code.
(0002499)
realms-mud   
2020-01-10 22:37   
I'm trying to find something that doesn't cascade into a really painful example but I'm not having too much luck. That said, it looks like a decent test would be to grab the following files from my repo:

The test is:
https://github.com/realms-mud/core-lib/blob/master/lib/tests/items/itemTest.c

For this, you can comment out every method after CanSetBonusesOnItems() as this test takes on average 220ms on 3.5 and 470ms on 3.6 - most appears to be time spent in load_object on all of the dependencies, for what that's worth.

This has quite a few dependencies, but it should work if you just copy over the /lib directory and all of its contents to <root>/lib on your instance (ie: you will need your own master, simul_efun, etc), but any should be fine:

https://github.com/realms-mud/core-lib/tree/master/lib

Do not try to copy the rest of the mudlib over because that would bring some database dependencies (and needed DB structure) over and I don't think we want to go there.

To execute the test, you should be able to just do: load_object("/lib/tests/items/itemTest.c")->executeTests();

If this becomes painful for you, I can get you a running environment to work with.
(0002500)
Gnomi   
2020-01-11 11:53   
I added a simul-efun for format() and regreplace(), but now I get a runtime error:

2020.01.11 11:50:59 Item: The 'bonus <thing>' element must be a string as defined in the keys of the bonusList mapping in /lib/dictionaries/bonusesDictionary.c and it must be set to an appropriate value.
2020.01.11 11:50:59 program: lib/items/item.c, object: lib/items/item#0 line 93
      38 ' epilog' in ' master.c' (' master') line 27
     137 ' run_test' in ' master.c' (' master') line 15
   36498 ' executeTests' in 'lib/tests/framework/testFixture.c' ('lib/tests/items/itemTest') line 47
   74158 'CanSetBonusesOnItems' in 'lib/tests/items/itemTest.c' ('lib/tests/items/itemTest') line 27
   74194 ' set' in ' lib/items/item.c' (' lib/items/item#0') line 514
   74285 ' isValidBonus' in ' lib/items/item.c' (' lib/items/item#0') line 93
2020.01.11 11:50:59 Error in master_ob->epilog()
(0002507)
realms-mud   
2020-01-13 17:19   
Sorry about that. I'd forgotten about my format efun, but regreplace should just be the standard efun. For format(string, int), it just deals with line-wrap, so returning the passed-in string would be fine.

If I had to guess (which, admittedly, this would be a blind guess), the file_size(...) check on line 65 of lib/items/item.c would almost certainly be the culprit since that is typically a privileged check in valid_read. I know I do have some file_size(...) checks in a few other places throughout the codebase.

Are you using a master/simul_efun that I have access to? If so, I can get this running locally and given you something that'll work "out of the box" rather than playing tag on this.
(0002508)
Gnomi   
2020-01-13 17:23   
This is my master (the inc and sys directory are from ldmud's test directory):

#include "/inc/base.inc"
#include "/inc/sefun.inc"

void run_test()
{
    object ob;
    int *start, *end;

    msg("\nRealms-MUD test\n"
          "---------------\n");

    ob = load_object("lib/tests/items/itemTest");

    start = utime();
    ob->executeTests();
    end = utime();
    msg("Duration: %d\n", (end[0] - start[0]) * 1000000 + end[1] - start[1]);
    shutdown(0);

    return 0;
}

string *epilog(int eflag)
{
    set_driver_hook(H_INCLUDE_DIRS, ({ "/sys/"}));

    run_test();
    return 0;
}


And this the simul-efun:
string format(string str, int width)
{
    return str;
}

varargs string regreplace(string txt, string pattern, string|closure replacepattern, int flags)
{
    return efun::regreplace(txt, pattern, replacepattern, flags);
}
(0002509)
realms-mud   
2020-01-13 20:06   
Since I wasn't able to use your master.c (has a couple include files I don't have), I grabbed (a really awful) one that works. You should be able to just untar this tarball somewhere as a root mudlib directory and point the driver at it.

Thanks for your efforts!
(0002510)
Gnomi   
2020-01-13 20:25   
As I wrote the inc and sys directories are in the directory /test in the LDMud sources.
(0002511)
realms-mud   
2020-01-13 20:32   
I guess reading is hard for me. ;)
(0002512)
realms-mud   
2020-01-13 21:12   
It looks like all you need to do to "fix" the issue you're seeing is to change the CanSetBonusesOnItems test to remove the setup/check for "bonus fire attack". Reset isn't getting called on the objects loaded for that.... keeping that in the test is not really important in this context and only changes the execution time by about 5ms on average.

IE: Change lib/tests/items/itemTest.c to just be:
<code>
inherit "/lib/tests/framework/testFixture.c";

object Item;

void Setup()
{
    Item = clone_object("/lib/items/item");
}

void CleanUp()
{
    destruct(Item);
}

void CanSetBonusesOnItems()
{
    // Only test a few of these - the full set is tested in dictionaries/bonusesDictionaryTest
    ExpectFalse(Item->query("enchanted"), "item is enchanted");
    ExpectTrue(Item->set("bonus armor class", 5), "bonus armor class can be set");
    ExpectTrue(Item->set("bonus gem crafting", 7), "bonus armor class can be set");

    ExpectEq(5, Item->query("bonus armor class"), "bonus armor class query returns correctly");
    ExpectEq(7, Item->query("bonus gem crafting"), "bonus gem crafting query returns correctly");
    ExpectTrue(Item->query("enchanted"), "item is enchanted");
}
</code>
(0002513)
realms-mud   
2020-01-13 21:13   
... and the Mantis Wiki let me down... apologies for the fubar formatting.
(0002518)
Gnomi   
2020-01-14 11:20   
I can reproduce it and will look into it.
(0002519)
Gnomi   
2020-01-14 21:49   
Could you try the optimization branch in my repository: https://github.com/amotzkau/ldmud/tree/optimization

I found that the most of the extra time was spent on passing the source files through iconv().
As ASCII or UTF-8 files will be the most common case I implemented a shortcut for that, that just checks the input. These checks also have extra costs in comparison to 3.5.2, but they are necessary.

I would be interested how this optimization does with your test suite. The test case I have runs between 31 and 35ms, so the difference to 3.5.2 is within the margin of error...
(0002520)
realms-mud   
2020-01-15 00:43   
I did a few test runs and the results look really good:

3.5:
Test executed: lib/tests/modules/crafting/craftWeaponTest -> [ PASSED ]
 -> built in 6387 ms.

3.6:
Test executed: lib/tests/modules/crafting/craftWeaponTest -> [ PASSED ]
 -> built in 14722 ms.

Your optimization:
Test executed: lib/tests/modules/crafting/craftWeaponTest -> [ PASSED ]
 -> built in 6892 ms

A much faster test (the full itemTest.c I pointed you to earlier):
3.5: 149ms
3.6: 241ms
Your optimizations: 168ms

There's definitely a little overhead, but it's not linear like it was and overall I'd say it's pretty negligible.
(0002521)
zesstra   
2020-01-18 17:30   
I think, it is also worth pointing out that your test suite is performing that bad on 3.6.x concerning the performance because it is so heavily compiling lots of programs. Once an object is loaded, there should be not much slowdown.
(0002530)
Gnomi   
2020-04-29 00:26   
Optimization was released in LDMud 3.6.2

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
732 [LDMud] LPC Language feature N/A 2010-03-04 15:37 2020-04-29 00:14
Reporter: _xtian_ Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: strict resolved call-others? and a new operator
Description: I don't know if this has ever been proposed. Probably.

I have been thinking about an efun that does what call_resolved() does, but with the call_other syntax and throws an error when a call could not be resolved. In brief:

  call_strict( ob, "fun" );

or a more beautiful

  ob=>fun() or ob.fun() or ob==>fun() (suggestions)

throws an error at runtime, if ob has no accessible function "fun".

The reason behind this: In LPC we have no good way to express interface relationships since all our objects are of the same type and call-others at runtime don't need to be resolved. The above is a short-hand for using call_resolved() and checking for an error, but I find it much more expressive and readable and worth being implemented in the language.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001760)
zesstra   
2010-03-04 15:44   
I don't really like => or ==> because they are too easily confused with comparisons.
The dot would be better, but it may clash with the struct lookup, I don't know if the compiler is clever enough (AFAIR there was once the plan to use -> for struct lookup, which did not work for compiler reasons).
(0001761)
_xtian_   
2010-03-04 15:56   
Hmm, the dot also suggests some kind of static checking, which wouldn't be the case here ...
(0001762)
Largo   
2010-03-04 17:57   
I don't see why the dot suggests static checking more or less than the call_other() operator (->).

Why don't we couple strict function resolving to an (existing) pragma? Since load_object() has been added, the number of unresolved function calls should have been decreased significantly. ;-)

Besides: Why has call_resolved() been designed to return a success value instead of raising an error, too? One could use function_exists() if he wanted to handle non-existent functions.
(0001763)
bubbs   
2010-03-05 11:56   
Couldn't you achieve this through a simul_efun to call_other ?
(0001764)
Bardioc   
2010-03-05 14:08   
We implemented a Warning system for calls to non-existing functions in EverLIB as follows:

in our master in inaugurate_master():
set_driver_hook(H_DEFAULT_METHOD, "unresolved_method_call");

in our base object that is inherited by ALL other objects. Parts are EverLIB specific, but I think you get the idea. This works GREAT and it helped us to find ALOT of bugs. Its fast enough too!

public status unresolved_method_call(mixed result, string fun, varargs args)
{
    if (object_name(this_object()) + ".c" == __FILE__)
    {
        return FALSE;
    }

    if (member(omitted_methods, fun) || fun == "reset" || fun == "clean_up"
            || (sizeof(fun) > 0 && fun[0] == '-'))
    {
        return FALSE;
    }

    string msg;

    if (previous_object() == NULL)
    {
        msg = sprintf("Non-existing method <%O>::%s() called\n", this_object(), fun);
    }
    else
    {
        msg = sprintf("<%O> called non-existing method <%O>::%s()\n"
                      , previous_object(), this_object(), fun);
    }

    if ( this_player() != NULL
         && interactive(this_player())
         && (status) this_player()->instance_of("/class/interactive/interactive")
         && ( (status) SECURITY->user_id_exists( (string)this_player()->get_normalized_name() )
              || 1 == (int)SE_ACCESS_CONTROL->is_valid_testplayer( this_player() ) ) )
    {
        // send this to the player, but bypass the processing of it
        send_message(({ MCC_WARNING, M_PL_ONLY, "WARNING: ", msg }));
    }
    else
    {
        catch(SE_CHANNEL->send("Wrongness", master(), CHANNEL_CMD_SAY, ({ msg }), NULL));
    }

    debug_message(msg, DMSG_STAMP | DMSG_STDOUT | DMSG_STDERR | DMSG_LOGFILE);

    return FALSE;
}

So actually, we do not need to distinguish, we already have the functionality ;-)
(0001780)
_xtian_   
2010-03-10 17:41   
Thanks for the code snippets, but the original intention is not to change the behaviour of call_other but to offer a second way of external function calling ... albeit a stricter one.

In our environment the fact that a not-resolved-call-other results in a legal 0 is used quite a lot and I wouldn't want to change that default. (example: if (ob->query_weapon) // react to a weapon ...)

The stricter call would allow code like this:

if (ob->query_weapon)
  ob==>wield(); // if this weapon has not defined a wield() function
                  // this throws an error/warning. this shouldn't happen


Of course we could add a custom simul-efun that does this, but I prefer putting this in the open.
Also that way we can use a nice operator for it, if we can find a suitable one.
(0001795)
zesstra   
2010-03-14 11:17   
Another possibility would be to change the behaviour of call_other based on a pragma in the caller (or callee?)... But that would of course have a greater impact and your last example would require a different approach to detect the weapon (function_exists, symbol_function, ...).
(0002529)
Gnomi   
2020-04-29 00:14   
Implemented in 3.6.2

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
877 [LDMud 3.6] Implementation block always 2020-04-27 07:48 2020-04-28 23:47
Reporter: iago4 Platform:  
Assigned To: OS:  
Priority: immediate OS Version:  
Status: resolved Product Version: 3.6.1  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.2  
    Target Version: 3.6.2  
Summary: snoop() adds junk data to input commands
Description: Checking the snoop function in the 3.6 series, it appears that the snooper can see remainders of previously input commands in the snooped text.

For example: the the snoopee types in "get all", the snooper sees "%get all". But if the snooper types the command "l" next, the snooper sees "%let all" (the new command combined with a remainder of the old command). This only affects input text, output is unaffected. The snoopee sees nothing unusual, just the snooper.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002524)
zesstra   
2020-04-28 01:40   
Just this evening I got a report from two wizards reporting a similar problem.

A short check: this is not limited to snoopee and snooper: the snooper gets commands from arbitrary players in the mud with the beginning overwritten by the command of the snoopee.
It seems, a static buffer used in the process is not cleared before.
(0002525)
zesstra   
2020-04-28 09:38   
With this bug it is possible to read commands from third-parties, which is bad enough. But with the correct timing of a cooperating snoopee and snooper (or just bad luck), a snooper can also get to know the password of third-parties, especially in muds with little activity. This was actually demonstrated by a wizard from us in his homemud.

Therefore, we I have increased the priority on this one, but can only have a look this evening. I think, this also merits a fast bugfix release.
(0002526)
iago4   
2020-04-28 21:54   
Wow, that got serious quick. Yes, I agree it's a security issue at this point and merits a bugfix release.
(0002527)
zesstra   
2020-04-28 21:57   
Indeed. Fortunately, Gnomi has a fix for the issue ready and we will prepare a release (also including some other fixes) and announcement soon.
(0002528)
zesstra   
2020-04-28 23:44   
3.6.2 was just released and fixes the problem. Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
250 [LDMud 3.6] LPC Compiler/Preprocessor feature N/A 2004-11-27 00:00 2020-01-09 01:00
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.8 and before  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.1  
    Target Version:  
Summary: Casts should just check types, not convert them
Description: Short: Casts should just check types, not convert them.
From: Lars
Date: 2001-06-10
State: New

A cast just should generate an instruction to check the casted type
at runtime, but otherwise not convert it.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001734)
zesstra   
2010-02-15 19:22   
So assume a (int)a would check if a is of type int. What should be the reaction if it is not? Runtime error, runtime warning, message into the debug log?
(0002495)
Gnomi   
2020-01-09 01:00   
This is now the behavior of declarative casts with runtime type checks enabled.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
638 [LDMud 3.6] General minor N/A 2009-05-19 18:17 2020-01-09 00:56
Reporter: zesstra Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.1  
    Target Version: 3.3.721  
Summary: RfC: optionally instrument allocators with valgrind client requests?
Description: Valgrind is a useful tool for findings memory leaks, illegal memory accesses and alike. Unfortunately, we use custom memory allocators which impairs valgrind's ability for find leaks and illegal memory accesses.
Valgrind supports custom allocators, if they mark their memory blocks by using VALGRIND_MALLOCLIKE_BLOCK upon allocation and VALGRIND_FREELIKE_BLOCK upon free'ing memory.
These macros from valgrind evaluate to 0 and do nothing if the program is not run in valgrind. If not enabled by configure, we could define them empty and have no runtime impact at all.

a) I would like to hear your opinions about adding them (enabled by a configure switch) to our allocators in mem_alloc(), mem_free() and alike.

b) additionally valgrind supports to set blocks of memory as 'inaccessable', 'accessable, undefined' and 'accessable,defined'. We could use them in xalloc()/xfree(). Read/Write accesses to free'd blocks/chunks which are marked as not accessable will cause valgrind to issue warnings.

c) Additionally we might mark our the administrative structures (block headers) as not accessable and see if we catch bugs like 0000574.

d) In a later step we might use valgrind's support for memory pools.
 
a) and b) might be a useful thing to do and they have a low overhead in adding the stuff to our codebase and have a very low runtime overhead (even none, if not enabled in configure).
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001124)
Gnomi   
2009-05-20 02:35   
Sounds good. I have no objections.
(0001769)
zesstra   
2010-03-08 15:57   
Uh, Gnomi took over this task, so transferring the issue to him as well.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
861 [LDMud] LPC Compiler/Preprocessor minor always 2018-02-04 01:04 2019-11-24 14:45
Reporter: Gnomi Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Variable initializer uses to-be-initialized variable
Description: Given the following file:

int x = 42;

int fun() { int x = x - 1; return x; }


The function will return -1.

Another case is where you want to catch variables by reference for a closure:

closure fun()
{
    int a = 1;
    return function int() : int a = &a { return a; }
}


Here funcall(fun()) will return 0 instead of 1.

The reason is, that the expression at the right hand side of the assignment will already use the declaration left of the assignment operator. I think this behavior is not intuitive and should be changed.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002454)
Gnomi   
2018-02-07 20:39   
C has the same behavior (initializer uses the initialized variable). But most of the time it will result in undefined behavior. It's there, so you can take the address of the to-be-initialized variable and use that in the initializer.

In LPC it would be the same with the reference operator, but I see even fewer use cases here than in C.
(0002455)
zesstra   
2018-02-08 00:37   
I agree... I would prefer to use the existing variable until the initialization is complete...
I assume, in case there is no existing variable in an outer scope, such an initializer will then cause an error? The other way, that it falls back to the to-be-initialized var would be not consistent I think.
(0002457)
zesstra   
2018-02-26 21:26   
BTW: One of our wizards commented, he would expect that there would be warning that the inner/new variable shadows the outer one.
(0002458)
Gnomi   
2018-02-26 21:50   
The warning comes only if a local variable shadows another local variable. In the examples above (local variable shadowing a global variable, closure context variable shadowing outer local variable) the compiler currently doesn't give any warnings.
(0002494)
Gnomi   
2019-11-24 14:45   
Fixed in current master.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
872 [LDMud 3.6] Runtime crash sometimes 2019-11-20 22:41 2019-11-21 15:32
Reporter: Nostradamus Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: A miscalculation in efun terminal_colour will crash the driver
Description: Driver version: (3.6.0-7-ge196172a)
OS: Ubuntu Linux 18.04 LTS
Architecture: x86_64
Compilation settings:
./configure \
--prefix=/home/dragonfiredev/mud \
--bindir=/home/dragonfiredev/mud/bin \
--libdir=/home/dragonfiredev/mud/dev-lib \
--libexec=/home/dragonfiredev/mud/libexec \
--enable-use-mysql=/usr/include/mysql \
--enable-compat-mode \
--enable-erq=xerq \
--enable-dynamic-costs \
--enable-opcprof \
--enable-verbose-opcprof \
--enable-use-deprecated=no \
--enable-malloc-trace=yes \
--enable-use-alists=yes \
--enable-use-pcre=yes \
--enable-use-json=yes \
--enable-use-pgsql=no \
--enable-use-mccp=yes \
--enable-use-tls=gnu \
--enable-share-variables=no \
--enable-filename-spaces=yes \
--enable-malloc-lpc-trace=yes \
--with-read-file-max-size=200000 \
--with-max-byte-transfer=200000 \
--without-wizlist-file \
--with-optimize=no \
--with-master-name=secure/master \
--with-time-to-reset=900 \
--with-portno=1999 \
--with-udp-port=2000 \
--with-max-cost=2100000 \
--with-otable-size=8192 \
--with-htable-size=32768 \
--with-apply-cache-bits=14 \
--with-time-to-swap=0 \
--with-time-to-swap-variables=0 \
--with-max_net_connects=100 \
--with-min-malloced=0x80000 \
--with-min-small-malloced=0x80000 \
--with-hard-malloc-limit=0 \
--with-malloc=sysmalloc \
--with-heart-beat-interval=2 \
--with-alarm-time=1 \
--with-swap-file=DFDEV_SWAP \
--with-max-array-size=50000 \
--with-max-mapping-keys=50000 \
--with-max-mapping-size=100000 \
--enable-eval-cost-trace=yes \
--with-max-cost=10000000 \
--enable-use-python \
--with-setting=default

Stack trace:
warning: .dynamic section for "/usr/lib/x86_64-linux-gnu/libmysqlclient.so.20" is not at the expected address (wrong library or version mismatch?)
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `/home/dragonfiredev/mud/bin/dev-ldmud -d --debug-file /home/dragonfiredev/mud/d'.
Program terminated with signal SIGABRT, Aborted.
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
0000001 0x00007f8c4b87a801 in __GI_abort () at abort.c:79
0000002 0x000055ad67fb9560 in dump_core () at simulate.c:623
0000003 0x000055ad67fb9844 in fatal (
    fmt=0x55ad67fe26c8 "Length miscalculated in terminal_colour()\n Expected: %i (or %i) Was: %td\n In string: %.*s\n Out string: %.*s\n Indent: %i Wrap: %i, indent overflow: %s\n") at simulate.c:684
0000004 0x000055ad67f13916 in e_terminal_colour (text=0x55ad719bc518, map=0x55ad69df7638, cl=0x0, indent=0, wrap=80)
    at efuns.c:3119
0000005 0x000055ad67f13a69 in v_terminal_colour (sp=0x55ad6826a390 <value_stack_array+592>, num_arg=3) at efuns.c:3235
0000006 0x000055ad67f3482e in eval_instruction (
    first_instruction=0x55ad6ba06752 "b\003\005\017\003\006~\005*\313l\nc\313\v\336\270d\221~\006*\037\001\306m\005\n\023~\001*c\037\001p\r", initial_sp=0x55ad6826a350 <value_stack_array+528>) at interpret.c:8476
0000007 0x000055ad67f40562 in eval_instruction (first_instruction=0x55ad6eb7a152 "b\001\005\n",
    initial_sp=0x55ad6826a2b0 <value_stack_array+368>) at interpret.c:14498
0000008 0x000055ad67f444dc in apply_low (fun=0x55ad69889948, ob=0x55ad70248438, num_arg=1, b_ign_prot=false)
    at interpret.c:16785
0000009 0x000055ad67f44694 in int_apply (fun=0x55ad6a556db8, ob=0x55ad70248438, num_arg=1, b_ign_prot=false,
    b_use_default=true) at interpret.c:16863
0000010 0x000055ad67f42e55 in eval_instruction (first_instruction=0x55ad693b02c2 "b\001\t\037",
    initial_sp=0x55ad6826a220 <value_stack_array+224>) at interpret.c:16083
0000011 0x000055ad67f43fa5 in apply_low (fun=0x55ad6931ef78, ob=0x55ad693b7438, num_arg=1, b_ign_prot=false)
    at interpret.c:16664
0000012 0x000055ad67f44694 in int_apply (fun=0x55ad6931ef78, ob=0x55ad693b7438, num_arg=1, b_ign_prot=false,
    b_use_default=true) at interpret.c:16863
---Type <return> to continue, or q <return> to quit---
0000013 0x000055ad67f42e55 in eval_instruction (first_instruction=0x55ad6935f0d2 "\017\003;\v\022\064l\031\v\023~",
    initial_sp=0x55ad6826a150 <value_stack_array+16>) at interpret.c:16083
#14 0x000055ad67f43fa5 in apply_low (fun=0x55ad6931ef78, ob=0x55ad72860c48, num_arg=1, b_ign_prot=false)
    at interpret.c:16664
#15 0x000055ad67f44694 in int_apply (fun=0x55ad6931ef78, ob=0x55ad72860c48, num_arg=1, b_ign_prot=false,
    b_use_default=true) at interpret.c:16863
#16 0x000055ad67f44a90 in sapply_int (fun=0x55ad6931ef78, ob=0x55ad72860c48, num_arg=1, b_find_static=false,
    b_use_default=true) at interpret.c:17025
#17 0x000055ad67fc0192 in execute_callback (cb=0x55ad6c444ee0, nargs=1, keep=true, toplevel=true) at simulate.c:4278
#18 0x000055ad67ed8f93 in parse_command (buff=0x7ffed8f00050 "grep -R hell *", from_efun=false) at actions.c:1005
#19 0x000055ad67ed949c in execute_command (str=0x7ffed8f00050 "grep -R hell *", ob=0x55ad72860c48) at actions.c:1161
#20 0x000055ad67ee394b in backend () at backend.c:942
#21 0x000055ad67f5990b in main (argc=6, argv=0x7ffed8f062d8) at main.c:706
(gdb)
Tags: crash
Steps To Reproduce: Our best results at reproducing the crash are by 'grepping' big files/input's.
Additional Information: Mud is running in "UTF-8 mode" but pretty much all files are ascii encoded.
Core dump is available upon request
Attached Files:
Notes
(0002487)
Gnomi   
2019-11-20 23:03   
Could you please provide the coredump and corresponding binary?
(0002488)
Nostradamus   
2019-11-20 23:13   
New infomation has come to light. The crash might be due to a Python efun function (grep tool) that looks like this:

def do_grep(name, where, arg):
    myCmd = os.popen('grep --include \*.h --include \*.c '+arg+' '+name+' /mud/lib'+where).read()
    myOutput = re.sub('/mud/lib','',myCmd)
    myOutput = re.sub(name, '%^BLDCYN%^'+name+'%^OFF%^',myOutput)
    return myOutput

Binary and core:
https://nas.zitz.dk/~ralph/ldmud
https://nas.zitz.dk/~ralph/core
(0002489)
Gnomi   
2019-11-20 23:15   
I could download the binary, but I get HTTP 403 for the core.
(0002490)
Nostradamus   
2019-11-20 23:50   
Apologies, the permissions on the file were too restrictive. Please try again
(0002491)
Gnomi   
2019-11-21 00:03   
The binary and core file don't seem to match. According to the core file the binary was named "dev-ldmud", is this a different one?
(0002492)
gorgar   
2019-11-21 01:21   
#Gnomi - dev-ldmud is a symlink:
dev-ldmud -> ldmud
(0002493)
Gnomi   
2019-11-21 15:32   
Fixed in the current master.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
871 [LDMud] Compilation, Installation minor have not tried 2019-11-17 20:27 2019-11-19 16:46
Reporter: Deaddy Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: ldmud 3.6 compiled with gcc 9.2 segfaults at start (probably due to memory allocator)
Description: I build the ldmud with settings/morgengrauen. Afterwards execution of ldmud immediately segfaults.
When I add with_malloc=sysmalloc to settings/morgengrauen after Zesstra's suggestion, this error disappears. Happens with current git version (I actually tested multiple checkouts on the master branch).
Tags:
Steps To Reproduce: git clone https://github.com/ldmud/ldmud.git
cd ldmud
settings/morgengrauen
make all
./ldmud
Additional Information: COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/9.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-9.2.0/configure --disable-libssp --disable-multilib --enable-version-specific-runtime-libs --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/9.2.0 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/9.2.0 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/9.2.0/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/9.2.0/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/include/g++-v9.2.0 --enable-clocale=gnu --host=x86_64-pc-linux-gnu --enable-obsolete --disable-werror --enable-libmudflap --enable-secureplt --enable-lto --with-system-zlib --without-cloog --with-bugurl=http://bugs.funtoo.org --with-pkgversion='Funtoo 9.2.0' --enable-stage1-checking=assert,runtime,misc,tree,gc,rtlflag --enable-checking=assert,runtime --enable-languages=c,c++,fortran --disable-libgcj --enable-threads=posix --enable-__cxa_atexit --enable-libstdcxx-time --enable-libgomp --enable-bootstrap --enable-shared --build=x86_64-pc-linux-gnu --disable-libsanitizer --enable-default-pie --enable-default-ssp --disable-libstdcxx-pch --disable-vtable-verify --disable-libvtv --with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/9.2.0/python --enable-nls --with-included-gettext --with-arch=znver1
Thread model: posix
gcc version 9.2.0 (Funtoo 9.2.0)

Faulty ldmud binary is somewhat temporarily available under
http://deaddy.net:8000/ldmud
and coredump
http://deaddy.net:8000/core
If it's broken mud tm deaddy@morgengrauen or tizona@morgengrauen so I can restart the server, at least a few days it should be able to reside there.
Attached Files:
Notes
(0002483)
Gnomi   
2019-11-17 22:08   
Could you please try the following branch: https://github.com/amotzkau/ldmud/tree/871-nullpointer
I don't have GCC 9 to check for myself.
(0002484)
Deaddy   
2019-11-18 21:35   
I can't build that one because of openssl:
make: *** [<builtin>: pkg-openssl.o] Error
IIRC I only managed to build 3.6 versions since some openssl update.
(0002485)
Gnomi   
2019-11-18 22:02   
I don't understand. My branch is just the master you built with a few lines in slaballoc.c changed. Nothing related to openssl.
(0002486)
Deaddy   
2019-11-19 07:25   
Excuse me, I forgot to checkout the branch.

That seems to fix it.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
432 [LDMud 3.6] General feature N/A 2006-01-06 20:32 2019-09-24 10:27
Reporter: iago3 Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.4.0  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.6.0  
    Target Version:  
Summary: Add string efuns with multibyte character support
Description: This is a "parent" bug for multibyte support in string efuns IN GENERAL. The specific efuns and implementations are filed as separate bugs. "Big picture" discussions can go here. My goal is that all text handled and stored by the mudlib should be in one multibyte character set (typically UTF-8), which can then be converted on-the-fly as it is displayed (see bug#426 for conversion issues).

Here were my design considerations when creating string efuns with multibyte character support. Some of them may be based on faulty assumptions. If so, please correct them and make any required changes to the efuns I've created.

1) "Multibyte" refers to strings encoded in the native multibyte character set specified by the driver host's locale. For different hosts, this could be different values. If a different multibyte encoding from the native one is needed, convert_charset should be used in conjunction with the efun. Sticking to the native charset should make integration with other applications--Perl regular expressions, for example--work transparently. The driver could perhaps allow a configuration option to specify a locale for the driver, but that is not something I'd recommend.

2) I see no reason to create a new "wide character" datatype. A simple array of integers should suffice to represent a wide character string, and provide sufficient values well into the forseeable future. Direct manipulation of wide characters from within the mudlib should be possible, but limited.

3) Old efuns should only be changed when there would be no significant difference in behavior on old systems--otherwise, new efuns should be created. For example, strlen() should not be changed to count the number of multibyte characters in a string because people may be relying on it to return the number of bytes (not characters) in a string. capitalize() can be changed because its behavior outside US-ASCII is undefined, and UTF-8 is a superset of US-ASCII. [Is this a safe assumption? We could also make a wcapitalize()...]

4) Multibyte string efuns should allow strings that contain \0 characters, like existing string efuns (this makes the code much more complicated, but more compatible).

The efuns I've created are:

int wcslen(string|int*)
Returns the number of multibyte characters in the given multibyte string or array of wide characters (in the case of an array, it's simply the size of the array)

int wcswidth(string|int*)
Returns the number of screen columns the given multibyte string or array of wide characters will occupy. The behavior of this function is a little funny due to the funny behavior of POSIX wcwidth(). I've modified it to be slightly more useful for our purposes. Characters normally reporting a negative column width are assigned zero width. Tab characters, which normally report a width of zero (because it's variable), are assigned a width of 8.

string wcstombs(int|int*)
Takes a single wide character or array of wide characters and returns a multibyte string. If strings are mixed into the array of wide characters, they will be inserted into the resulting string at those positions, unmodified.

int *mbstowcs(string)
Takes a multibyte string and returns an array of wide characters.

string substr(string,int,int)
Returns a substring of the given multibyte string. The second argument is the start and the third argument is the number of characters. Example: For US-ASCII strings, string[2..3] and substr(string,2,2) would be equivalent. Only the latter is safe to use on multibyte strings.

The efuns I've changed are: capitalize, lower_case, and upper_case.

Please keep in mind: I am not a programmer. If my ideas are flawed, or if my implementations are bad, blame my lack of schooling. Because of this, it's not a bad idea to check my code for simple mistakes any freshman CS student would make.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000472)
iago3   
2006-01-06 20:53   
Added bugs 0000433-440 for each function. There are more string functions to potentially convert, but these should cover the basics.
(0000482)
fippo   
2006-03-02 08:37   
What about adding a 'multibyte'-flag to the mstring structure to specify, if the string is a multibyte-string?

E.g. if a string is supplied as input to strlen and that flag is set, strlen will act as your wcslen() does, otherwise it will retain its current behaviour.

The only new efun that are needed then would be some 'toggleWCS', which sets or unsets this flag.

Note:
If people want the number of bytes in a string, they should use sizeof(), not strlen.
(0000483)
Gnomi   
2006-03-02 08:56   
> If people want the number of bytes in a string, they should use sizeof(), not strlen.

This may break things, because currently sizeof is a synonym for strlen (in regard to strings) and is used as such. (I prefer the use of sizeof, because I somehow expect strlen to be declared as obsoleted by sizeof sometime in the future.)

But I like the idea of a multibyte flag instead of additional efuns, because then you can introduce multibyte strings in a whole MUD without greater changes in the mudlib.
(0000484)
iago3   
2006-03-02 16:04   
The only benefit I see from using the multibyte flag is maybe being able to safely merge wcslen and strlen. We would still need four new efuns: wcswidth, wcstombs, mbstowcs, and substr. We could probably safely modify the existing capitalize, lower_case, and upper_case efuns regardless of whether we implement the multibyte flag or not.

Having existing code "just work" is nice, but in many cases it simply cannot be done. For example, as far as I can tell, all mudlibs assume a string with a length of one character takes up one column on the screen. Having wcslen and wcswidth as different efuns would break this old coding habit, but would not break old strlen-based mudlibs.

Also, I know it is very common to have code like string1[0..strlen(string2)]--which requires that strlen return the number of bytes, not characters, in a string. This is not necessarily a bad coding habit--in C, strlen also merely returns the bytes in a string, and people are used to that. If you want characters in C, you use wcslen.

I'm not saying LPC should always emulate the way C does things, but I think there are valid reasons for separate efuns. I too don't want to break existing mudlibs.

If we do implement a multibyte flag, we would need a quick-and-easy way for people to make all strings multibyte by default if their mudlib can handle it.
(0000485)
Gnomi   
2006-03-02 17:04   
Why should [..] applied to a multibyte string work on byte basis and not with characters? Then str[..strlen(str2)] would work fine.
(0000490)
iago3   
2006-03-03 20:32   
Fair enough, I suppose we could change [..] and [..<2], etc to use characters rather than bytes. This would get rid of the need for a new substr function!

So, we're talking about:
- Making a "multibyte" flag for the mstring structure, and a way to set the string on or off by default globally.
- Changing the following efuns to handle both "normal" and multibyte strings: strlen, capitalize, lower_case, and upper_case
- Creating the following new efuns: wcswidth, wcstombs, mbstowcs
- Changing [..]-type operators to function like the sample code originally proposed for substr()

So that's only three new efuns, plus whatever we need to manipulate the multibyte flag. Not bad!
(0000647)
zesstra   
2008-07-01 11:20   
I suggest to plan multibyte char support also for 3.5, not for 3.3 anymore.
(0000658)
menaures   
2008-07-02 06:06   
Is it really necessary to have a separate set of efuns for multibyte?

Quote from the original bug "strlen() should not be changed to count the number of multibyte characters in a string because people may be relying on it to return the number of bytes (not characters) in a string."

I see many more cases where strlen actually refers to the number of characters, and not number of bytes, e.g. max length of a characters name or similar player input and similar string length limits, width of a string (in characters) for string formatting, etc. Plus, code that works with strings as bytes, is likely to be broken anyway as that code is unlikely to handle multibyte strings correctly today.

I'd hate having to replace strlen/sizeof with some new function everywhere where you work with strings as text and not bytes (and in a MUD I think that's practically everywhere).

The only EFuns I can think of that work with bytes instead of characters, are read_bytes, write_bytes, and file_size. And out of these only read_bytes would be prone to returning only half a character.

Personally I'd like to see multibyte strings as default for everything and add special functions only for those who need to do something very unusual for a MUD environment, like working with single bytes or even binary data. The move to multibyte is unlikely to not break anything anyway.
(0000659)
Gnomi   
2008-07-02 06:09   
(Last edited: 2008-07-02 06:09)
See the third comment, I'm in favor of a multibyte flag so that just the current efuns and operators behave differently.


View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
843 [LDMud] LPC Compiler/Preprocessor minor always 2015-09-01 22:33 2019-08-29 23:39
Reporter: _xtian_ Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: struct runtime lookup regression
Description: When upgrading to a september 2015 version of 3.5 (from early 2014 version), I found a regression in the struct runtime lookup code.

the following used to compile (note the use of polymorphism for the struct argument):

---

struct a_t {
  mapping m; // compiles without this line
};

struct b_t (a_t) {
  int i;
};

void fun(struct a_t a, string s)
{
  a->(s)= 42;
}

void create()
{
  struct b_t b = (<b_t>);

  fun(b, "i");

  printf("%O\n", b);
}
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002263)
Gnomi   
2015-09-01 22:55   
Oh, this is soo mean. I was so glad to have finally solved Lars' test case t-040413:

struct Door
{
    string flags;
};

struct Exit
{
    string flags;
};

struct Exits
{
    struct Exit up;
    struct Exit down;
};

struct Room
{
    struct Exits exit;
};

void main()
{
    struct Room room;
    string dir;

    // The in the following line the driver should be able to determine
    // that only a struct Exit could be the result of the computed lookup.

    room->exit->(dir)->flags;
}

But given the example in the bug report that test scenario is not true, because room->exit could be some derived struct containing other entries that are not a struct Exit.

So, the solution would be to just undo f69c91bb464077b3465d8ae5793dd041591b6a95 and remove that test scenario.
(0002264)
_xtian_   
2015-09-06 05:44   
Concerning Lars' test case:

- If find it is ambig, because structs do implement polymorphism. It is a bad test case.
- with the usage of ->(dir) the programmer explicitly states that he wants runtime lookup, anyway, doesn't he? In that case compile-time lookup seems unexpected.

I would compare the case to C++ dynamic_cast. You wouldn't want the compiler to start guessing types based on some arbitrary scope.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
866 [LDMud 3.5] LPC Compiler/Preprocessor crash always 2018-08-27 00:43 2019-04-05 21:31
Reporter: willem Platform:  
Assigned To: Gnomi OS:  
Priority: high OS Version:  
Status: resolved Product Version: 3.5.1  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.2  
    Target Version: 3.5.2  
Summary: Improper use of reserved word 'function' crashes the driver
Description: Improper use of reserved word 'function' crashes the driver.
Tags: crash
Steps To Reproduce: Compile this file:
#pragma weak_types

test1() {

  function = allocate(1);
}

test2(str) {
  string who;

  if (sscanf(str,"%s arrives", who) != 1) return 0;
}
Additional Information: Driver version: 3.5.1-4-g7466f90d
Error in debug log: List of locals clobbered: depth 3, block_depth 2
Attached Files:
Notes
(0002462)
zesstra   
2018-08-27 20:12   
Thank you for reporting!

Works for me as well with even a bit more reduction:

void test1() {
  function = 42;
}
void test2() {
  int who;
  printf(who);
}
(0002463)
Gnomi   
2018-08-30 23:28   
Fix committed in revision ee2d87d7d999978422d24b739f42330c533e48bc to master branch (see changeset 4152 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
863 [LDMud 3.5] Runtime minor always 2018-02-06 00:08 2019-04-05 21:31
Reporter: rjsalts Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.5.1  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.2  
    Target Version:  
Summary: ldmud --help output causes unreproducible build of manpages
Description: When running ldmud --help the first line outputs the time and date as well as the source of entropy (e.g. 2018.02.06 10:03:45 Seeding PRNG from /dev/urandom). Because this is captured by help2man the lmud.1 manpage is always different, even if you're setting the SOURCE_DATE_EPOCH environment variable for help2man to create a reproducible build. Can this output be suppressed when running the ldmud executable with the --help option?
Tags:
Steps To Reproduce: run ldmud --help
Additional Information:
Attached Files:
Notes
(0002451)
zesstra   
2018-02-06 23:13   
In principle, yes. However... The argument parser currently expects that some parts of the driver are already initialized. These are printing these messages. It needs more work than just calling the argument parser earlier and we can't know if --help was given before parsing the arguments...
(0002452)
rjsalts   
2018-02-06 23:50   
If it's very difficult the non-deterministic output could be worked around when generating the manpage.

if help2man ran a wrapper script which did ldmud "$@" | tail -n +2 it would strip the offending line.
(0002453)
Gnomi   
2018-02-07 18:55   
It seems to me that the early seeding is done, because the option parser doesn't remember whether --random-seed was given and thus seeding from the random device would not be allowed afterwards. If we would track that, we could seed after argument parsing.

In light of --randomdevice it also seems the correct approach, so the driver doesn't access any file (from the compile time defaults) that the user doesn't want us to.
(0002456)
Gnomi   
2018-02-17 15:38   
Fix committed in revision 7466f90df8bcf27abc6b6f03be2862e2b9f8c054 to master branch (see changeset 4151 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
860 [LDMud 3.5] LPC Compiler/Preprocessor crash unable to reproduce 2018-01-17 18:07 2019-04-05 21:31
Reporter: manuel Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.5.0  
Product Build: Resolution: unable to reproduce  
Projection: none      
ETA: none Fixed in Version: 3.5.2  
    Target Version: 3.5.1  
Summary: LPC compiler of LDMud 3.5 is aborted in inherit_virtual_variables
Description: While loading a list of ca. 50 (some of them faulty) LPC objects LDMud 3.5 was aborted by SIGABRT.


debug log:

ldmud: prolang.y:15393: inherit_virtual_variables: Assertion `last_variable_index == first_variable_index + progp->num_variables - progp->num_virtual_variables' failed.


backtrace core:

Core was generated by `/home/mud/bin/ldmud 12345 12346 -u 12347 -m /home/mud/mudlib -s v0 --tls-key /h'.
Program terminated with signal SIGABRT, Aborted.
#0 0xf7721c89 in __kernel_vsyscall ()
(gdb) bt
#0 0xf7721c89 in __kernel_vsyscall ()
0000001 0xf6db8dc0 in ?? ()
0000002 0x00000000 in ?? () by


I haven't found anything in the debug log that explains this error. Nor have I been able to reproduce it. "Unable to reproduce" doesn't mean that the error itself is necessarily irreproducable. I just wasn't able to locate the cause.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002445)
Gnomi   
2018-01-30 23:34   
Hello Manuel,

could you please test the current master branch of LDMud? This seems like something that could have been fixed with the last changes there.

Regards,
Gnomi
(0002469)
Gnomi   
2019-02-03 13:57   
Closing this, because I think this is already fixed in master.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
855 [LDMud 3.5] Runtime minor always 2017-12-16 11:14 2019-04-05 21:31
Reporter: manuel Platform:  
Assigned To: Gnomi OS:  
Priority: low OS Version:  
Status: resolved Product Version: 3.5.0  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.2  
    Target Version: 3.5.1  
Summary: Bad argument in example sefun set_connection_charset
Description: The example sefun in mudlib/deprecated/set_connection_charset.c chokes with bad argument to interactive() if no interactive is around.

That's because the call to this_interactive returns 0 (if no interactive is around) and feeds it to interactive(), which expects an object instead of an int. This is a rather common situation when the sefun is called during the setup of a session.
Tags:
Steps To Reproduce: Install the example set_connection_charset.c as a sefun and call it without an interactive around.
Additional Information:
Attached Files:
Notes
(0002283)
manuel   
2017-12-16 11:56   
Sorry, severity shouldn't be block but minor. My mistake.
(0002448)
Gnomi   
2018-02-04 00:09   
Fix committed in revision ddf06a06afd9516310c204afbd4ee394295ec510 to master branch (see changeset 4129 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
864 [LDMud 3.5] Compilation, Installation minor always 2018-03-24 02:36 2019-04-05 21:11
Reporter: abathur Platform:  
Assigned To: Gnomi OS: nixos  
Priority: normal OS Version: 17.09  
Status: resolved Product Version: 3.5.1  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.2  
    Target Version:  
Summary: compile error with format-security hardening flag
Description: Not certain if this needs reporting or not, but I'm building ldmud on NixOS and ran into a problem with the hardening flags it passes by default causing a compile error. I've included a full build log, and the conversation I was having in the NixOS IRC.

I can ignore this specific hardening flag so it isn't a short-term issue for me.

I gather the extent to which it's a security issue depends on what error string comes back from mysql, and whether an attacker could influence its content. I'm hoping the compile log is sufficient to reproduce this on a non-nixos system, but I'll look into providing more instructions if it isn't.
Tags:
Steps To Reproduce:
Additional Information: abathur | got it to build by disabling the "format" hardening flag; on a scale of one to bad, how bad?
clever | abathur: depends on what triggered the warning, what was the error without that setting?
abathur | not still in scrollback as an error, but this is the equivalent warning:pkg-mysql.c:328:5: warning: format not a string literal and no format arguments [-Wformat-security]
abathur | meh, missed: errorf(err_string);
clever | ah, so it was basically printf(variable1);
clever | and potentialy, if an attacker can control that variable, he can exploit the machine
clever | https://github.com/ldmud/ldmud/blob/master/src/pkg-mysql.c#L317-L328
clever | in this case, the string came from mysql_error
clever | things can still malfunction in fun ways if the error happens to contain a %
clever | it should use something other then errorf
abathur | so, probably worth filing an issue with its maintainers about, in your estimation?
clever | abathur: yeah
Attached Files: hard (174,946 bytes) 2018-03-24 02:36
http://ldmud.eu/file_download.php?file_id=295&type=bug
default.nix (1,452 bytes) 2019-04-03 05:26
http://ldmud.eu/file_download.php?file_id=296&type=bug
Notes
(0002470)
Gnomi   
2019-04-02 20:04   
Just so I can test it: How do you build LDMud with NixOS? What is the command line, what are the prerequisites
(Explained for someone who doesn't know NixOS.)
(0002471)
abathur   
2019-04-03 05:26   
Grumble. I typed all of this out and Mantis ate my post with some gripe about a security token timeout. I'm too tired for the long version, at this point.

1. If you don't already have a NixOS VM image sitting around, it should be fine to do this with the Nix package manager on any/most linux/unixes. Instructions: https://nixos.org/nix/download.html
2. Download the attached default.nix, place it in a new directory, and cd to this directory
3. Run nix-build. As uploaded, this will fail. To see a successful build, uncomment line 75 (a success will add a "result" link to a directory containing the build outputs).

If you want to build it against a different LDMud, there are a few options:
- any ref/tag should be valid for the "version" on line 4
- replace the owner/repo on lines 10/11
- either change above will require updating the hash on 13, but the simple way is to just let it fail and copy the expected hash from the output

You can also replace the whole block from 9-14 with something like `src = ./projects/my-ldmud;` or whatever, but let me know if you need this and can't get it working.
(0002472)
Gnomi   
2019-04-05 21:11   
Fixed in the current master. It compiled successfully with the given build recipe.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
868 [LDMud] Runtime crash always 2018-10-23 21:32 2018-10-25 14:42
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: MacOS X  
Priority: high OS Version: 10.9.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Lambas with return in expression crashes driver
Description: A lambda with a return in an "unfinished" expression crashes the driver, e.g.
lambda(0, ({#'+,3,({#'return,2})}))
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0002465)
Gnomi   
2018-10-25 14:42   
Fix committed in revision 5dd77264fa5f76e94e62e678c17629cd9a94698d to master branch (see changeset 4155 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
867 [LDMud] Runtime crash sometimes 2018-10-22 22:02 2018-10-23 18:28
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: MacOS X  
Priority: normal OS Version: 10.9.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Crash when applying lambda
Description: When creating an object with the program given below, the driver usually crashes with an "'illegal' instruction encountered." or a segmentation fault 11. One reported "Bad stack at F_RETRN, 1 values too high"
Other possibilities are various errors like "Bad arg 1 to add_action(): got 'invalid', expected 'string/closure'.", "Undefined function: Dangling function call in lambda closure", "Bad arg 1 to x++: got 'number', expected 'lvalue'."

The exact error seems to be influenced by the state of the compiler. If it does not crash, various ones can be provoked by compiling different programs before the test program.

2018.10.22 21:35:25 'illegal' instruction encountered.
2018.10.22 21:35:25 Current object was test
test test.c line 5
0x10d58c022: 97 256 clear_locals (0: 28) line 5
0x10d58c025: 22 61532 closure (0: 28) line 6
0x10d58c02a: 22 61480 closure (1: 29) line 8
0x10d58c02f: 22 61501 closure (2: 30) line 10
0x10d58c034: 22 59392 closure (3: 31) line 12
0x10d58c039: 156 1 aggregate (4: 32) line 13
0x10d58c03c: 22 61773 closure (4: 32) line 14
0x10d58c041: 16 const1 (5: 33) line 15
0x10d58c042: 156 4 aggregate (6: 34) line 16
0x10d58c045: 18 9 clit (3: 31) line 17
0x10d58c047: 156 3 aggregate (4: 32) line 18
0x10d58c04a: 156 2 aggregate (2: 30) line 19
0x10d58c04d: 125 0 push_local_variable_lvalue (1: 29)
0x10d58c04f: 41 (void)= (2: 30)
0x10d58c050: 10 0 cstring0 (0: 28) line 21
0x10d58c052: 276 55 quote (1: 29)
0x10d58c054: 22 61773 closure (1: 29)
0x10d58c059: 15 const0 (2: 30)
0x10d58c05a: 158 513 m_caggregate (3: 31)
0x10d58c05d: 120 0 push_identifier_lvalue (1: 29)
0x10d58c05f: 41 (void)= (2: 30)
0x10d58c060: 98 save_arg_frame (0: 28) line 23
0x10d58c061: 8 0 identifier (1: 29)
0x10d58c063: 262 41 m_indices (2: 30)
0x10d58c065: 30 0 local (2: 30)
0x10d58c067: 333 18 lambda (3: 31)
0x10d58c069: 8 0 identifier (2: 30)
0x10d58c06b: 15 const0 (3: 31)
0x10d58c06c: 339 24 m_values (4: 32)
0x10d58c06e: 381 apply (3: 31)
test <lambda ?> line 0
0x10a20fc52: 18 9 clit (0: 31) line 0
0x10a20fc54: 8 0 identifier (1: 32)
0x10a20fc56: 162 0 lambda_cconstant (2: 33)
0x10a20fc58: 16 const1 (3: 34)
0x10a20fc59: 142 map_index_lvalue (4: 35)
0x10a20fc5a: 40 = (2: 33)
0x10a20fc5b: 10 1 cstring0 (1: 32)
0x10a20fc5e: 0 0 14 0 0 48 0 0
    2149 ' ParseLine' in ' obj/tools/MGtool.c' ('obj/tools/MGtool#251') line 1548
    2505 ' CallFunc' in ' obj/tools/MGtool.c' ('obj/tools/MGtool#251') line 1616
    3402 ' Xload' in 'obj/tools/MGtool.c (/obj/tools/MGtool/toolcmd.c)' ('obj/tools/MGtool#251') line 1035
    7586 ' CATCH' in ('obj/tools/MGtool#251')
    7616 ' create' in ' test.c' (' test') line 23
    7624 <lambda 0x10a20fc52> in ' test.c' (' test') offset 12
2018.10.22 21:35:25 LDMud aborting on fatal error.
Tags:
Steps To Reproduce: Start the driver and load a file containing the following program:

mapping memory;

void create()
{
  mixed code=({
  #',,
  ({
    #'=,
    ({
      #'[,
      ({
        #'memory
      }),
      #'lambda,
      1
    }),
    9
  })
});

  memory=([ quote("'@"): #'lambda; 0 ]);

  apply(lambda(m_indices(memory), code), m_values(memory));
}

Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0002464)
Gnomi   
2018-10-23 18:28   
Fix committed in revision a91d988e954fb562abee2060f49c4842b232677f to master branch (see changeset 4154 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
857 [LDMud 3.5] Other minor always 2017-12-30 02:00 2018-02-02 16:22
Reporter: manuel Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.5.0  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.1  
    Target Version: 3.5.1  
Summary: debug_info.h for the replacement sefun debug_info lacks defines
Description: The header mudlib/deprecated/debug_info.h comming with 3.5 lacks the defines for Indices into the subarrays resulting from debug_info(DINFO_TRACE, 0) and the values for entry TRACE_TYPE. These defines used to be present in 3.3 mudlib/sys/debug_info.h.

If you use the replacment sefun example and also install the changed header, it might break old objects which expect the now missing defines that were still present in 3.3.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002290)
zesstra   
2018-01-09 00:05   
Right... However, these defines still exist with these names in driver_info.h, so we must only define them if not already defined by inclusion of driver_info.h.
(0002447)
zesstra   
2018-02-02 16:19   
Fix committed in revision 301da1a7f7233e520185cb0d4401a62ab65c8a56 to master branch (see changeset 4128 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
835 [LDMud 3.5] Other minor N/A 2014-09-05 23:44 2018-01-30 23:18
Reporter: zesstra Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.1  
    Target Version:  
Summary: sqlite: enable the error and warning log
Description: If using sqlite3, the global error and warning log should be enabled and the messages either stored (e.g. ringbuffer) for retrieval or just printed to the standard driver log.
It may contain important info about problems when using sqlite and it should not be too difficult to use.
Details:
https://www.sqlite.org/errlog.html
Tags: sqlite
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002444)
Gnomi   
2018-01-30 23:09   
Fix committed in revision 344e7e1633c7384c6e4a0ce32a79c2ea2a11362a to master branch (see changeset 4118 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
854 [LDMud 3.5] Runtime crash always 2017-12-16 10:20 2018-01-30 22:39
Reporter: manuel Platform:  
Assigned To: Gnomi OS: Debian  
Priority: high OS Version: 9 (stretch)  
Status: resolved Product Version: 3.5.0  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.1  
    Target Version: 3.5.1  
Summary: Crash with bad type 1 in swap_svalues()
Description: Ldmud 3.5.0 crashes with 'bad type 1 in swap_svalues()' on the first time variables are swapped out after a restart of the driver. See the attached log.
Tags: crash
Steps To Reproduce: Start ldmud 3.5.0 with the current test mudlib of Final Frontier. Wait until the first swapping of variables occurs.

The occurance of the crash can be avoided, delayed or accelerated with setting the -s v<time> parameter of ldmud to respective values.

I haven't been able yet to reproduce this with a minimal setup, so the crash might depend on the presence of certain objects or object dumps in the current test mudlib of Final Frontier.
Additional Information: Type 1 is T_LVALUE, which is unkown to swap_svalues. So far as I see, the list of types known to swap_svalues hasn't changed since ldmud 3.3.

The setup is ldmud 3.5.0 compiled and linked as 32-bit binary on a 64-bit system. It may be the case that a 64-bit version of ldmud was used before on the same mudlib. I painstakingly tried to remove all object dumps or var saves that might have been written under 64-bit, but I can't be completely sure that I succeeded.

Testing different mudlib versions or platforms would be very time time consuming because of all the dependies of the mudlib I'd have to take care of to make it running under the different test setups. So I hope somebody has another idea how to tackle the crash.

I may provide a core, if requested.
Attached Files: swap-crash.log (20,216 bytes) 2017-12-16 10:20
http://ldmud.eu/file_download.php?file_id=291&type=bug
Notes
(0002286)
zesstra   
2017-12-16 22:45   
I guess, the re-worked lvalue handling is the key here - there seems to be an lvalue where there should not be one.

Since this error will probably indeed depend on specific cirumstances, so please save a core file. ;-) Then we first might pin-point the origin of the specific variable here...

I will assign this directly to Gnomi, since he is the most qualified one to look into it.
(0002289)
manuel   
2017-12-27 19:22   
I have figured out a way to reproduce the crash. Try something like:

    mapping testmap;
    testmap["some_new_key"] = 1;

In the debug log you will get:

    (index_lvalue)Indexing on illegal type 'number'.

This seems to be a genuine ldmud error, not something related to LPC checks.

The object will still load. If the mapping is a global, ldmud will crash as soon as swapping starts for this object.

I have doubts though that this is the only way to make swap_svalues crash, because I have also observe crashes of this kind without beeing able to locate the mentioned debug log message.
(0002443)
Gnomi   
2018-01-30 22:09   
Fix committed in revision 289020b80657cd707b3ca6bb64dfbe6d62d4ecb9 to master branch (see changeset 4116 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
772 [LDMud 3.5] Efuns crash always 2011-02-13 17:15 2018-01-30 04:59
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/LInux  
Priority: normal OS Version: 5.0  
Status: resolved Product Version: 3.5.0  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Calling destruct in __INIT crashes the driver
Description: When an object is destructed before the H_CREATE_* function is called, the driver crashes with: "apply() on destructed object '...' function '...'."
Tags:
Steps To Reproduce: int wegdamit()
{
    destruct(this_object());
    return 1;
}
int kaputt = wegdamit();

void create()
{
}
Additional Information:
System Description
Attached Files:
Notes
(0001991)
Gnomi   
2011-02-14 20:11   
process_string also crashes:

string kaputt() { destruct(this_object()); return "KAPUTT";}
string okay() { return "OKAY"; }

void create()
{
    process_string("@@kaputt@@ -> @@okay@@");
}
(0002025)
Gnomi   
2011-02-23 00:17   
Fix committed in revision 8792ccbeb263e76df46ad2b9db51d80b58329abf to master-3.3 branch (see changeset 794 for details). Thank you for reporting!
(0002331)
Gnomi   
2018-01-29 19:59   
Fix committed in revision 8792ccbeb263e76df46ad2b9db51d80b58329abf to master-3.3 branch (see changeset 2220 for details). Thank you for reporting!
(0002382)
Gnomi   
2018-01-29 22:57   
Fix committed in revision 8792ccbeb263e76df46ad2b9db51d80b58329abf to master-3.3 branch (see changeset 3564 for details). Thank you for reporting!
(0002433)
Gnomi   
2018-01-30 04:59   
Fix committed in revision 56f9f3ba3fc34b538c31ee4e088dbb995e9cf0c8 to master branch (see changeset 3997 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
770 [LDMud 3.5] Compilation, Installation minor always 2011-01-21 19:21 2018-01-30 04:59
Reporter: _xtian_ Platform: 64bit 3.5  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.3.720  
Summary: bitwise AND doesnt work on ints > 32bit
Description: Note: We are on a 64bit platform now.

zlpc return 0x1000000000
Got=68719476736

> zlpc return __INT_MAX__
Got=9223372036854775807

> zlpc return 0x1000000000 & 0x1000000000
Got=0

Zesstra thinks the interpreter may use "int" internally for F_AND
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001952)
zesstra   
2011-01-21 19:47   
The interpreter assigns the result of the AND to an int (instead of p_int), which cuts off the higher 32 bits of the value and the remaining part is 0.

OR, XOR, leftshift, rightshift and modulo have the same problem.
(0001966)
zesstra   
2011-02-13 22:34   
Fix committed in revision 45c011affccfc92df723f6824a170a11d8dee4e6 to master branch (see changeset 759 for details). Thank you for reporting!
(0002333)
zesstra   
2018-01-29 19:59   
Fix committed in revision 45c011affccfc92df723f6824a170a11d8dee4e6 to master branch (see changeset 1590 for details). Thank you for reporting!
(0002384)
zesstra   
2018-01-29 22:57   
Fix committed in revision 45c011affccfc92df723f6824a170a11d8dee4e6 to master branch (see changeset 2921 for details). Thank you for reporting!
(0002435)
zesstra   
2018-01-30 04:59   
Fix committed in revision 45c011affccfc92df723f6824a170a11d8dee4e6 to master branch (see changeset 4003 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
767 [LDMud 3.5] Documentation minor N/A 2011-01-08 21:16 2018-01-30 04:59
Reporter: Sorcerer Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: Error in 'varargs' man-page
Description: [...]
void fun (string arg1, int arg2, varargs int * arg3)

This allows fun() to be called with three or more arguments.
[...]

Should read "...with two or more arguments..." (as also shown in the examples below this statement).

This bug applies to 3.5, but also to 3.3.717 and probably all other versions.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001947)
zesstra   
2011-01-09 13:35   
Fix committed in revision 0bb050c76ec70a92ba96483bfab31c956999d8b7 to master-3.3 branch (see changeset 739 for details). Thank you for reporting!
(0002335)
zesstra   
2018-01-29 19:59   
Fix committed in revision 0bb050c76ec70a92ba96483bfab31c956999d8b7 to master-3.3 branch (see changeset 2246 for details). Thank you for reporting!
(0002386)
zesstra   
2018-01-29 22:57   
Fix committed in revision 0bb050c76ec70a92ba96483bfab31c956999d8b7 to master-3.3 branch (see changeset 3591 for details). Thank you for reporting!
(0002437)
zesstra   
2018-01-30 04:59   
Fix committed in revision b30fcb8f00c37766b3de254100ecefb3d1f5d230 to master branch (see changeset 4022 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
761 [LDMud 3.3] Documentation text always 2010-10-02 09:26 2018-01-30 04:59
Reporter: Sorcerer Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.719  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: Typo in manpage for m_contains
Description: "...which massed be passed by reference..." should read
"...which must be passed by reference...".

Applies to 3.3 as well and probably 3.2, too.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001915)
zesstra   
2010-11-17 20:55   
Fix committed to master-3.3 branch.
(0002338)
zesstra   
2018-01-29 19:59   
Fix committed in revision ab96bb3d2105ec2ed9862d938cad7eaa4971a13a to master-3.3 branch (see changeset 2252 for details). Thank you for reporting!
(0002389)
zesstra   
2018-01-29 22:57   
Fix committed in revision ab96bb3d2105ec2ed9862d938cad7eaa4971a13a to master-3.3 branch (see changeset 3597 for details). Thank you for reporting!
(0002440)
zesstra   
2018-01-30 04:59   
Fix committed in revision 4f7ed71bc93b52e42d4ee8a877f091f16d0123d6 to master branch (see changeset 4034 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
760 [LDMud 3.3] Documentation text always 2010-10-02 09:14 2018-01-30 04:59
Reporter: Sorcerer Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: error in manpage for regreplace
Description: The manpage for regreplace (English and German versions) gives the following example:
txt = regreplace(txt, "HOUSE", #'lower_case, 1);
But since regreplace will pass the substring AND the position to the closure this will yield an error due to too many arguments to (efun::)lower_case(). My suggestion is to change the line to read:
txt = regreplace(txt, "HOUSE", (: lower_case($1) :), 1);

This also applies to the manpages of 3.3 and probably also 3.2.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001913)
zesstra   
2010-11-17 11:31   
Fix committed to master branch.
(0001914)
zesstra   
2010-11-17 11:45   
Fix committed to master-3.3 branch.
(0002339)
zesstra   
2018-01-29 19:59   
Fix committed in revision 4ef2f7c605717241f0bfb11c612a3d25005f79d8 to master-3.3 branch (see changeset 2253 for details). Thank you for reporting!
(0002390)
zesstra   
2018-01-29 22:57   
Fix committed in revision 4ef2f7c605717241f0bfb11c612a3d25005f79d8 to master-3.3 branch (see changeset 3598 for details). Thank you for reporting!
(0002441)
zesstra   
2018-01-30 04:59   
Fix committed in revision 496e83d18e617d45df5d8662ea5a1716b018041e to master branch (see changeset 4035 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
743 [LDMud 3.5] Runtime major always 2010-04-04 04:39 2018-01-30 04:59
Reporter: _xtian_ Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: 3.5.0 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: 3.5.0-current skipping heart_beats
Description: A few days ago we switched from a several months old 3.5.0 to a current (march 2010) 3.5.0 and immediately players started complaining that timers (that were actually fired by their heart_beats) were noticeably delayed.

Measuring several objects heart_beat showed that about every 10% HBs of an object were delayed. Instead of a 2s delay, they had a 4s delay. This occured all the time - like I said easily for every 10% of HBs.

Switching back to an older build of 3.5.0 solved the problem.

If you can tell me where I can look-up the build number at runtime, I'll tell you which builds were involved.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001820)
zesstra   
2010-04-21 17:34   
Concerning the 'look up revision at run-time': AFAIK it is not possible. The information should be in the debug file, but obviously does not help right now for older reversions.

Concerning the problem: interesting. ;-) I guess I will have to start with some testcase first (or do you have a portable one ready?). Do you have any further info about the circumstances or do you just need 100 objects with no code but a heart_heat() in them?
(0001821)
zesstra   
2010-04-21 18:03   
First try: I just cloned 300 objects with heartbeats and monitored if the HBs are skipped/delayed and the number of HB objects and processed HB objects in each cycle (via debug_info, DID_ST_HBEAT_OBJS, DID_ST_HBEAT_PROCESSED, DID_ST_HBEAT_AVG_PROC). So far I did not notice any problems, no skipped/delayed HBs on my machine at home.
(0001822)
_xtian_   
2010-04-21 18:05   
I just have an object that notifies me on every HB.
Hmm, what else can I tell you. I can reproduce it in our develmud (on the server) but not in my homemud. The Develmud has <10 object with HBs, but a lot more call-outs running (if that is relevant) than the homemud.
Or the server load somehow factors into this.
(0001823)
zesstra   
2010-04-21 18:22   
Mhmm, the server load can influence it, because the drivers signal to execute the heartbeats is alarm/ITIMER_REAL and that can be delayed (or even missed on heavy server loads). But usually that delays should not be in the range of seconds. (What average loads and peak loads do you have?) It may be interesting to find out if a the HBs in a limited number of objects are missed or the complete HB cycle is delayed.
(0001825)
_xtian_   
2010-04-21 18:39   
(Last edited: 2010-04-21 18:48)
The CPU never goes above 20%.
All my testobjects delay at the same time.

EDIT: Yep, approx 38 from 40 objects with HBs enabled delay at the same time. Looks like the whole queue.

(0001828)
_xtian_   
2010-04-24 05:32   
after bisecting: the regression appears in rev 2874
(0001829)
zesstra   
2010-04-25 17:43   
r2874? Are you sure? I read it again and still can't think of a reason, why this should introduce skipped heartbeats. It just synchronizes the alarms of the driver with full realtime seconds, making the first timer interval after bootup a little bit shorter.
(Out of curiosity: do you have any "Last alarm was x seconds ago - restarting it." messages in your debug log?)
(0001830)
zesstra   
2010-04-26 10:53   
Ah, another thing: could you please measure the time between your heartbeats with utime() instead of time()?
(0001831)
zesstra   
2010-04-26 15:35   
Ok, problem found, I guess. r2874 is not faulty in itself (the problem could occur without it as well), but increases the chance for a very unlucky timing:
r2874 tries to synchronize the time of alarms with whole seconds. The driver works with a granularity of seconds. Now consider: Alarm1 at 2.000001s. Alarm2 at 3.999999s. First thing: time() returns 2 and 3 at the time of the two alarms. The difference is < __HEART_BEAT_INTERVAL__ and the heartbeat is not executed, although _nearly_ __HEART_BEAT_INTERVAL__ has passed. Result: a heartbeat delayed by __ALARM_TIME__.
Second possibility: Alarm1 at 1.999999s, Alarm2 at 4.000001s. The heartbeat is executed properly, about 2s passed since the last one, but the LPC internal time() will return 1 and 4, which looks like a delayed heartbeat (by one second).
(0001832)
zesstra   
2010-04-26 16:15   
Ok, I changed the way current_time is determined in r2902. Could you please test in your mud if it solves your problems?
(0001834)
zesstra   
2010-04-26 16:41   
Xtian reported success, so I am closing. In case of problems, please tell me to re-open.
(0001910)
zesstra   
2010-11-16 10:42   
Fix committed to master branch.
(0002340)
zesstra   
2018-01-29 19:59   
Fix committed in revision 06ea2820f6c36c54f5766f51fde1c6f9bd0c53bf to master branch (see changeset 1640 for details). Thank you for reporting!
(0002391)
zesstra   
2018-01-29 22:57   
Fix committed in revision 06ea2820f6c36c54f5766f51fde1c6f9bd0c53bf to master branch (see changeset 2972 for details). Thank you for reporting!
(0002442)
zesstra   
2018-01-30 04:59   
Fix committed in revision 06ea2820f6c36c54f5766f51fde1c6f9bd0c53bf to master branch (see changeset 4053 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
729 [LDMud 3.3] Compilation, Installation minor always 2010-02-23 08:55 2018-01-30 04:59
Reporter: graveluth Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.719  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: Replacement of macro parameters doesn't strip trailing whitespaces
Description: The macro:

#define quote(X) "X"

with the usage (please note the whitespace before the closing parenthesis):

quote( foo )

leads to:

"foo "
Tags:
Steps To Reproduce:
Additional Information: Please, also note that this bug is obsolete if something like the C preprocessor # is introduced (see issue 0000174)
Attached Files:
Notes
(0001927)
zesstra   
2010-11-20 19:21   
Mhmmm. As far as I can see, it should be sufficient to skip the whitespace in the default case of the big switch in _expand_define(). That will also skip any other whitespace in the argument list, not only the trailing.
(0001941)
zesstra   
2011-01-06 23:59   
Fix committed in revision a5dacaba7c482f961a32336441d05ce302cfa630 to master-3.3 branch (see changeset 735 for details). Thank you for reporting!
(0001942)
zesstra   
2011-01-07 22:12   
Ok, never be too unimaginative. Of course it is not a good idea to skip all whitespaces in the arguments. Thanks Bardioc.
I was completely fixated on the fact that we also have to skip whitespace before and after each individual argument (not only before and after the last argument) and completely missed the whitespace within an argument which has to survive. *sigh*
(0001943)
zesstra   
2011-01-08 00:08   
I revised my changes from yesterday to skip only the leading and trailing whitespace of each argument and committed it to trunk/master.
I hope, there aren't any wizards who depend on the old behaviour of preserving most of the whitespace...

Could you please test and report back if this does not introduce new/other problems?
(0001944)
graveluth   
2011-01-08 14:43   
From my point of view this works fine - I couldn't find any new bugs so far.

Thanks for fixing.
(0001945)
zesstra   
2011-01-08 19:33   
Great. If there are any, you can re-open the issue.
(0001946)
zesstra   
2011-01-09 00:17   
Fix committed in revision a13299814b82b459bb2fe7a03d9850b57d401938 to master-3.3 branch (see changeset 737 for details). Thank you for reporting!
(0002336)
zesstra   
2018-01-29 19:59   
Fix committed in revision a5dacaba7c482f961a32336441d05ce302cfa630 to master-3.3 branch (see changeset 2250 for details). Thank you for reporting!
(0002387)
zesstra   
2018-01-29 22:57   
Fix committed in revision a5dacaba7c482f961a32336441d05ce302cfa630 to master-3.3 branch (see changeset 3595 for details). Thank you for reporting!
(0002438)
zesstra   
2018-01-30 04:59   
Fix committed in revision fb9e37b807285445be0d7f9c7250536334afc707 to master branch (see changeset 4027 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
590 [LDMud 3.3] Portability minor N/A 2008-12-30 13:02 2018-01-30 04:59
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: low OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.721  
    Target Version: 3.3.721  
Summary: Remove MAXINT from driver.h and change code which uses it.
Description: 1) MAXINT is defined in driver.h to 0x7fffffffU if it is not defined. I think, something like this should actually be defined in port.h.

2) MAXINT seems to used as the upper limit of p_int, not the upper limit of 'int'. In this case, code should use the correct constants from port.h (like PINT_MAX) for the used data type.

Candidates for checking are:
- closure.c in store_case_labels()
- access_check.c in read_access_file()
- mapping.c in get_new_hash()
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002043)
zesstra   
2011-02-25 00:17   
Fix committed in revision 6537a6681bdcae2d6b9e851e4a8c5ce27b47f278 to master-3.3 branch (see changeset 796 for details). Thank you for reporting!
(0002330)
zesstra   
2018-01-29 19:59   
Fix committed in revision 6537a6681bdcae2d6b9e851e4a8c5ce27b47f278 to master-3.3 branch (see changeset 2215 for details). Thank you for reporting!
(0002381)
zesstra   
2018-01-29 22:57   
Fix committed in revision 6537a6681bdcae2d6b9e851e4a8c5ce27b47f278 to master-3.3 branch (see changeset 3559 for details). Thank you for reporting!
(0002432)
zesstra   
2018-01-30 04:59   
Fix committed in revision 320039ae47c4f7f65202b71fb865520d6af46739 to master branch (see changeset 3996 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
302 [LDMud 3.5] Runtime feature N/A 2004-11-27 01:04 2018-01-30 04:59
Reporter: lars Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Memory usage as runtime limit
Description: ort: Memory usage as runtime limit
From: Menaures
Date: 2002-09-16
Type: Feature
State: New

 -- Since not all memory use is under control of the wizard (loading objects,
    swapping, activities by called objecs), this is tricky.
    It would be necessary to experiment first to see if we can actually
    track the memory usage, and maybe store it on a uid/object basis (like
    the eval costs).

Wäre es möglich, eine Speichergrenze einzuführen? Ich stelle mir das ähnlich
vor wie die Evalgrenze. Man darf während einer Ausführung nur eine bestimmte
Anzahl Bytes belegen.

Hintergrund:
Bisher ist es möglich, mit den simpelsten Einzeilern in kürzester Zeit den
gesamten MUD-Speicher vollzumüllen. Besonders ärgerlich wird das, wenn es aus
Versehen passiert, z.B. das Abbruchkriterium einer Schleife fehlt und man
addiert fröhlich strings solange, bis der Speicher voll ist (und hält dafür
nebenbei das MUD für 15 Minuten an, bis es sich danach verabschiedet).

Mit einer Speichergrenze von bleistiftsweise 4 Megabytes (oder ähnlich hohe
Zahl, die nie jemand braucht), würde bei erreichen dieses Limits ein RTE
geworfen werden, ähnlich einer Too Long Evaluation.

Damit könnten solche Fälle wenigstens nicht mehr 'aus Versehen' eintreten.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001294)
zesstra   
2009-09-26 17:52   
Uh, seems to me quite complex and/or costly and probably also in parts undeterministic for wizards (e.g. might a string consume quite different amounts of memory depending it whether it is already a shared string). That will make it difficult to safe-guard critical code against abortions in the wrong moment. At least, without introducing transactions as well...
(0001329)
Gnomi   
2009-09-29 05:31   
As Lars already pointed out, a memory limit per execution thread might be very unpredictable. Therefore such a limit must be very broad, but that might be feasible.

A limit per uid is expensive to track (each mapping, array, string must then store their list of uids they belong to, which must be updated on each assignment). So I'd rather not do that.
(0001480)
zesstra   
2009-10-05 18:59   
I agree. The part with the max consumption per execution thread might be done by monitoring the difference in allocated memory between execution start and now for allocators which support it. It is crude, but if the limit should be very broad...
(0001984)
zesstra   
2011-02-14 17:24   
The current suggestion then would be: simply monitor the difference between currently allocated memory and allocated memory at execution start and abort if that exceeds a certain value?

Or should be just abandon the idea?
(0001989)
Gnomi   
2011-02-14 18:29   
I like the idea and it seems simple enough.
(0001995)
zesstra   
2011-02-16 00:17   
Fix committed in revision 2540c460af23372b707a59b779e59b11faa60bde to master branch (see changeset 764 for details). Thank you for reporting!
(0002332)
zesstra   
2018-01-29 19:59   
Fix committed in revision 2540c460af23372b707a59b779e59b11faa60bde to master branch (see changeset 1585 for details). Thank you for reporting!
(0002383)
zesstra   
2018-01-29 22:57   
Fix committed in revision 2540c460af23372b707a59b779e59b11faa60bde to master branch (see changeset 2916 for details). Thank you for reporting!
(0002434)
zesstra   
2018-01-30 04:59   
Fix committed in revision 2540c460af23372b707a59b779e59b11faa60bde to master branch (see changeset 3998 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
257 [LDMud 3.5] LPC Compiler/Preprocessor feature N/A 2004-11-27 00:09 2018-01-30 04:59
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: WIldcarded super calls with arguments
Description: Short: Allow wildcarded calls with arguments
From: Lars
Date: 2001-08-02
Type: Feature
State: New

Allow wildcarded calls with arguments, e.g. "*":foo(i).

For this, implement a new opcode ROLLOVER, which takes this stack

   mixed* results = ({ r1, r2, r3 })
   arg1
   arg2
   arg3
   arg4
   r4 <--- sp

and leaves it behind as

   mixed* results = ({ r1, r2, r3, r4 })
   arg1
   arg2
   arg3
   arg4
   arg1
   arg2
   arg3
   arg4 <--- sp

so the sequence could be

   compute arg1
   compute arg2
   compute arg3
   compute arg4
   const0
   rollover
   call fun
   rollover
   call fun
   roll over
   call fun
   ...

With modifications of course.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001648)
Sorcerer   
2009-11-23 06:40   
Just wanted to bring this issue back to the top, since I intended to post the identical feature request against 3.5.x.
(0001649)
zesstra   
2009-11-23 07:26   
I transferred the issue to 3.5. Once we have dealt with it, we should decide if we backport it.
(0002047)
Gnomi   
2011-03-06 20:52   
(Last edited: 2011-03-06 22:09)
I plan to implement this in the following way:

New opcodes:
  ARRAY <n>, it's the same as aggregate(<n>), but <n> is put into the program, not on the stack.
  DUP_N <offset> <num>, copies values stack[1-offset-num] ... stack[-offset] on top of the stack.
  PUT_RESULT <offset> <num>, removes the top value off the stack und puts it into the array stack[-offset-1] at position <num>

For three inherited functions and two arguments there would be the following program and the corresponding stack.

ARRAY 3
    ({0,0,0})

SAVE_ARG_FRAME
    ({0,0,0})
    ArgFrame

Compute arguments
    ({0,0,0})
    ArgFrame
    Arg1
    Arg2

SAVE_ARG_FRAME
    ({0,0,0})
    ArgFrame
    Arg1
    Arg2
    ArgFrame

DUP_N 1 2
    ({0,0,0})
    ArgFrame
    Arg1
    Arg2
    ArgFrame
    Arg1
    Arg2

CALL_INHERITED
    ({0,0,0})
    ArgFrame
    Arg1
    Arg2
    ArgFrame
    Result1

PUT_RESULT 4 0
    ({Result1, 0, 0})
    ArgFrame
    Arg1
    Arg2
    ArgFrame

DUP_N 1 2
    ({Result1, 0, 0})
    ArgFrame
    Arg1
    Arg2
    ArgFrame
    Arg1
    Arg2

CALL_INHERITED
    ({Result1, 0, 0})
    ArgFrame
    Arg1
    Arg2
    ArgFrame
    Result1

RESTORE_ARG_FRAME
    ({Result1, 0, 0})
    ArgFrame
    Arg1
    Arg2
    Result1

PUT_RESULT 3 1
    ({Result1, Result2, 0})
    ArgFrame
    Arg1
    Arg2

CALL_INHERITED
    ({Result1, Result2, 0})
    ArgFrame
    Result3

RESTORE_ARG_FRAME
    ({Result1, Result2, 0})
    Result3

PUT_RESULT 0 2
    ({Result1, Result2, Result3})

(0002048)
Gnomi   
2011-03-09 00:17   
Fix committed in revision da2157dbc0690d11f30a0d0f400eab953adf9d92 to master branch (see changeset 797 for details). Thank you for reporting!
(0002329)
Gnomi   
2018-01-29 19:59   
Fix committed in revision da2157dbc0690d11f30a0d0f400eab953adf9d92 to master branch (see changeset 1582 for details). Thank you for reporting!
(0002380)
Gnomi   
2018-01-29 22:57   
Fix committed in revision da2157dbc0690d11f30a0d0f400eab953adf9d92 to master branch (see changeset 2913 for details). Thank you for reporting!
(0002431)
Gnomi   
2018-01-30 04:59   
Fix committed in revision da2157dbc0690d11f30a0d0f400eab953adf9d92 to master branch (see changeset 3995 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
178 [LDMud 3.5] Compilation, Installation feature N/A 2004-11-26 22:19 2018-01-30 04:59
Reporter: lars Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Make garbage_collection() and shutdown() privileged.
Description: Short: shutdown()/ garbage_collection() priviledged
From: Matthew Julius <julius.2@wright.edu>
Date: Fri, 08 Jan 1999 16:29:08 -0500
Type: Feature
State: Unclassified

Make shutdown() and garbage_collection() call master::privilege_violation().

Note: Most muds solve that with nomask simul-efuns.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001320)
zesstra   
2009-09-27 18:41   
I am in favor of this, it is much more consistent.
(0001393)
fufu   
2009-10-01 14:41   
I would rather move in the opposite direction and not call privilege_violation for any efuns at all, leaving just two causes: "limited" and "nomask simul_efun". But perhaps that's just me.

What about set_environment?
(0001447)
zesstra   
2009-10-04 11:56   
Mhmm, ok, I prefer to have the checks for privileges in one spot, no matter which they are. I see one big advantage in privilege_violation in the master: The checks can be implemented by
switch(fun) {
  default: return -1;
  ...
}
This causes access to forgotten or new efuns to be denied. With the sefun approach you should better not forget an efun - especially a nuisance for new ones.
Furthermore, I see one a difference between that approach: if you just restrict things by "nomask simul_efun" and sefuns, then privileged objects use efun::fun() and that is a compile-time decision for a given program. (And that program you have to safe-guard accordingly.) In privilege_violation the check is usually based on the object currently executing the program, which is IMHO in most cases what you want.
I am more comfortable by the central place of privilege checks in privilege_violation. It seems more robust to me.

set_environment() should IMHO also cause a privilege_violation, as well as set_this_player(). But these two efuns are a bit more difficult, because they are usually bound to the moved object, which are usually not privileged.
(0001513)
zesstra   
2009-10-07 09:09   
Setting to feedback for further discussion before I make any changes. ;-)
(0001515)
Sorcerer   
2009-10-08 07:31   
I agree with Zesstra with respect to having all privilege checks in one place. The main reason being the argument given above concerning privileged objects and/or new efuns.
(0001912)
zesstra   
2010-11-16 19:10   
Ok, as far as I see there are two (three, counting the reporter) in favor, one against and a lot of indifferent people. So I will continue.
(0001917)
zesstra   
2010-11-18 00:19   
Fix committed in revision e73d914a767c759afccd677b9d4857b22b8bfc81 to master branch (see changeset 724 for details). Thank you for reporting!
(0002337)
zesstra   
2018-01-29 19:59   
Fix committed in revision e73d914a767c759afccd677b9d4857b22b8bfc81 to master branch (see changeset 1617 for details). Thank you for reporting!
(0002388)
zesstra   
2018-01-29 22:57   
Fix committed in revision e73d914a767c759afccd677b9d4857b22b8bfc81 to master branch (see changeset 2949 for details). Thank you for reporting!
(0002439)
zesstra   
2018-01-30 04:59   
Fix committed in revision e73d914a767c759afccd677b9d4857b22b8bfc81 to master branch (see changeset 4030 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
859 [LDMud 3.5] LPC Compiler/Preprocessor crash always 2018-01-17 17:51 2018-01-30 04:59
Reporter: manuel Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.5.0  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.1  
    Target Version:  
Summary: LDMud 3.5 crashes on simple syntax mistake
Description: In an LPC program a line like "a, b" (two strings separated by a comma) on the global level (not inside a function) makes the driver segfault with:

test.c line 1: Missing type before 'b '.
Segmentation fault (core dumped)
Tags:
Steps To Reproduce: Make an LPC object with the line "a, b". Compile.
Additional Information:
Attached Files:
Notes
(0002291)
zesstra   
2018-01-28 22:31   
Fix committed in revision 2aa52c15942c6edfcd32dce6e391043c0caa36ab to master branch (see changeset 1138 for details). Thank you for reporting!
(0002298)
Gnomi   
2018-01-29 19:59   
Fix committed in revision 2aa52c15942c6edfcd32dce6e391043c0caa36ab to master branch (see changeset 1202 for details). Thank you for reporting!
(0002344)
Gnomi   
2018-01-29 20:34   
Fix committed in revision 2aa52c15942c6edfcd32dce6e391043c0caa36ab to master branch (see changeset 2365 for details). Thank you for reporting!
(0002349)
Gnomi   
2018-01-29 22:57   
Fix committed in revision 2aa52c15942c6edfcd32dce6e391043c0caa36ab to master branch (see changeset 2525 for details). Thank you for reporting!
(0002400)
Gnomi   
2018-01-30 04:59   
Fix committed in revision 2aa52c15942c6edfcd32dce6e391043c0caa36ab to master branch (see changeset 2400 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
851 [LDMud 3.5] Compilation, Installation minor always 2017-06-17 18:37 2018-01-30 04:59
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: MacOS X  
Priority: normal OS Version: 10.9.x  
Status: resolved Product Version: 3.5.0  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Tests fail without python support
Description: When compiled without python support, all tests fail, because during tests the driver is started with --python-script, which is an unknown argument.
Tags: testsuite
Steps To Reproduce: cd test
./run.sh
...
Test t-lvalues.c FAILED.
ldmud: Unknown option '--python-script'.
...
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0002292)
zesstra   
2018-01-28 22:31   
Fix committed in revision 4baeda32f3423e23ed43998adba19ee37c61ae45 to master branch (see changeset 1140 for details). Thank you for reporting!
(0002299)
Gnomi   
2018-01-29 19:59   
Fix committed in revision 4baeda32f3423e23ed43998adba19ee37c61ae45 to master branch (see changeset 1204 for details). Thank you for reporting!
(0002345)
Gnomi   
2018-01-29 20:34   
Fix committed in revision 4baeda32f3423e23ed43998adba19ee37c61ae45 to master branch (see changeset 2403 for details). Thank you for reporting!
(0002350)
Gnomi   
2018-01-29 22:57   
Fix committed in revision 4baeda32f3423e23ed43998adba19ee37c61ae45 to master branch (see changeset 2527 for details). Thank you for reporting!
(0002401)
Gnomi   
2018-01-30 04:59   
Fix committed in revision 4baeda32f3423e23ed43998adba19ee37c61ae45 to master branch (see changeset 2402 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
849 [LDMud 3.5] Networking minor N/A 2016-01-20 16:55 2018-01-30 04:59
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.5.0  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Make ciphers lists configurable
Description: The ciphers lists (OpenSSL) or priorities (GnuTLS) should be configurable for the administrator by configure_driver().
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002271)
zesstra   
2016-01-20 17:00   
Fix committed in revision 7ab9377e76fea0dd82734212f8b05542c6c9be80 to master branch (see changeset 1043 for details). Thank you for reporting!
(0002306)
zesstra   
2018-01-29 19:59   
Fix committed in revision 7ab9377e76fea0dd82734212f8b05542c6c9be80 to master branch (see changeset 1351 for details). Thank you for reporting!
(0002357)
zesstra   
2018-01-29 22:57   
Fix committed in revision 7ab9377e76fea0dd82734212f8b05542c6c9be80 to master branch (see changeset 2677 for details). Thank you for reporting!
(0002408)
zesstra   
2018-01-30 04:59   
Fix committed in revision 7ab9377e76fea0dd82734212f8b05542c6c9be80 to master branch (see changeset 3764 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
846 [LDMud 3.5] Networking feature N/A 2016-01-14 13:35 2018-01-30 04:59
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.5.0  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Make DH parameters configurable
Description: The Diffie-Hellman Keyexchange parameters should be configurable. Either via a command-line parameters or via configure_driver.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002270)
zesstra   
2016-01-20 17:00   
Fix committed in revision 69cec783fbde5b1601acfb7fe033f59c99b42141 to master branch (see changeset 1042 for details). Thank you for reporting!
(0002307)
zesstra   
2018-01-29 19:59   
Fix committed in revision 69cec783fbde5b1601acfb7fe033f59c99b42141 to master branch (see changeset 1352 for details). Thank you for reporting!
(0002358)
zesstra   
2018-01-29 22:57   
Fix committed in revision 69cec783fbde5b1601acfb7fe033f59c99b42141 to master branch (see changeset 2678 for details). Thank you for reporting!
(0002409)
zesstra   
2018-01-30 04:59   
Fix committed in revision 69cec783fbde5b1601acfb7fe033f59c99b42141 to master branch (see changeset 3765 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
841 [LDMud 3.5] Runtime crash always 2015-06-07 01:19 2018-01-30 04:59
Reporter: abathur Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Hard crash with inline closures
Description: We ran into a hard crash earlier this week while I've been working on a representative LPC test case for developing a syntax highlighter (this was on 3.3.719). Today I had time to do some more work on the syntax test and was able to reproduce a crash in 3.5.0.3 (more precisely: Current Commit: 3.5.0.3-8-g874d088). I assume this is the same crash on both versions, but I can't swear by that.

I took a while this afternoon to drill down to a pretty minimal test case, which is attached (yes; even though the closures don't reference each other, both are necessary.) Also found this in the log:

2015.06.06 22:51:52 allocation from free list for 80 bytes: block 0x2fb39ae (user 0x2fb39be) magic match failed, expected 624a92f0, found 624a92f00000
Tags:
Steps To Reproduce: 1.) find_and_load_object(closure_crash.c)
2.) wait a few seconds (the two runs I did with this final draft of the test case took 3-4 seconds to actually crash).

Note: assumes your MUD will apply reset() in order to self-destruct. If not you may need to modify the file or use some other means of destructing it.
Additional Information:
Attached Files: closure_crash.c (141 bytes) 2015-06-07 01:19
http://ldmud.eu/file_download.php?file_id=290&type=bug
Notes
(0002257)
guest   
2015-06-18 22:17   
Fix committed in revision f6469558302de635caf768dd561054d7555baf73 to master branch (see changeset 999 for details). Thank you for reporting!
(0002258)
Gnomi   
2015-06-18 22:36   
Thanks for the test case. With that file the bug was pretty easy to find.
(0002259)
zesstra   
2015-06-18 23:04   
Should we port it to 3.3?
(0002260)
Gnomi   
2015-06-19 18:54   
Yes, at a first glance seems to be the same on 3.3, so I'll fix it there, too.
(0002308)
Gnomi   
2018-01-29 19:59   
Fix committed in revision f6469558302de635caf768dd561054d7555baf73 to master branch (see changeset 1394 for details). Thank you for reporting!
(0002359)
Gnomi   
2018-01-29 22:57   
Fix committed in revision f6469558302de635caf768dd561054d7555baf73 to master branch (see changeset 2721 for details). Thank you for reporting!
(0002410)
Gnomi   
2018-01-30 04:59   
Fix committed in revision f6469558302de635caf768dd561054d7555baf73 to master branch (see changeset 3807 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
839 [LDMud 3.5] Implementation minor always 2015-01-23 21:28 2018-01-30 04:59
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: sprintf: incorrect behaviour of %b.
Description: %b prints only the least significant bit...
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
837 [LDMud 3.5] Implementation crash always 2015-01-08 21:33 2018-01-30 04:59
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: urgent OS Version: 10.9.x  
Status: resolved Product Version: 3.5.0  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: struct_epilog(): crash updating function return types when encountering functions without return type
Description: When struct_epilog() tries to update function return values it accesses them without checking if the function actually was compiled with types.
5628 if (f->type->t_class == TCLASS_STRUCT
(lldb) print f->type
(lpctype_t *) $1 = 0x0000000000000000

Nastingly enough this does only occur when recompiling such a program the second time... ;-)
Tags:
Steps To Reproduce: Loading stest1 crashes the driver reliably:

> stest1.c
void create()
{
  object o = load_object("/players/zesstra/stest2");
  destruct(o);
  load_object("/players/zesstra/stest2");
}

> stest2.c
struct XXX { };
get() {;}
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0002242)
zesstra   
2015-01-08 22:24   
After discussing with Gnomi: it seems only the function return values can have NULL as type. This requires special care for them and make the code harder to read and a lot more error-prone. We think the best is to always store a type. If we don't one from LPC source, we use TYPE_ANY.
(0002245)
zesstra   
2015-02-01 20:03   
Fix committed in revision c888b7d2a8038d4cb2013e1dbaabb03a4e277627 to master branch (see changeset 976 for details). Thank you for reporting!
(0002312)
zesstra   
2018-01-29 19:59   
Fix committed in revision c888b7d2a8038d4cb2013e1dbaabb03a4e277627 to master branch (see changeset 1417 for details). Thank you for reporting!
(0002363)
zesstra   
2018-01-29 22:57   
Fix committed in revision c888b7d2a8038d4cb2013e1dbaabb03a4e277627 to master branch (see changeset 2745 for details). Thank you for reporting!
(0002414)
zesstra   
2018-01-30 04:59   
Fix committed in revision c888b7d2a8038d4cb2013e1dbaabb03a4e277627 to master branch (see changeset 3830 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
836 [LDMud 3.5] Runtime crash always 2014-09-07 22:35 2018-01-30 04:59
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: high OS Version: 10.9.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Crash when determining a result type of a struct member lookup operation when struct is unknown.
Description: During get_struct_member_result_type() struct_find_member() and struct_t_size() may be called with the struct being NULL. This is not handled by the two called functions - however, I am not sure if they should. (Would be more robust, if they do.)
get_struct_member_result_type() should probably detect that and not call them in the first hand.

Preceding the crash is a compile error due to an unknown struct:
secure/errord.c line 1: Unknown struct 'fullissue_s' before ' issue)'.

The crashing code is basically (with no struct fullissue_s defined anywhere):
int db_insert_issue(struct fullissue_s issue)
{
  return issue->id;
}

This is especially unfortunate, because a typo in the struct name will lead to the crash if a struct member is referenced.
Tags: structs
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0002239)
zesstra   
2014-09-08 00:31   
I have a fix for it in get_struct_member_result_type() and get_lpctype_name_buf(), but maybe there are better ways of handling it. Details tomorrow.
(0002240)
zesstra   
2014-09-08 20:05   
Fix committed in revision 604e228d2f2a6afcebb260e75b1c4ef626bbfa61 to master branch (see changeset 966 for details). Thank you for reporting!
(0002313)
zesstra   
2018-01-29 19:59   
Fix committed in revision 604e228d2f2a6afcebb260e75b1c4ef626bbfa61 to master branch (see changeset 1427 for details). Thank you for reporting!
(0002364)
zesstra   
2018-01-29 22:57   
Fix committed in revision 604e228d2f2a6afcebb260e75b1c4ef626bbfa61 to master branch (see changeset 2755 for details). Thank you for reporting!
(0002415)
zesstra   
2018-01-30 04:59   
Fix committed in revision 604e228d2f2a6afcebb260e75b1c4ef626bbfa61 to master branch (see changeset 3840 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
833 [LDMud 3.5] LPC Compiler/Preprocessor crash always 2014-02-24 21:33 2018-01-30 04:59
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: MacOS X  
Priority: normal OS Version: 10.9.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: lexer crashes upon specially crafted precompiler directive #if
Description: The following code can crash the driver, if special circumstances are met:
#if \
 __VERSION_MAJOR
int run_test() { return 1; }
#endif

1) The __VERSION_MAJOR does not exist (otherwise the precompiler just behaves wrongly).
2) The line after the #if is at a position in the file that the input buffer of the lexxer is full within that line (so it has to be at multiples of 2048 bytes).

And yes. I caused the crash by accident and did not find it by looking at the lexer...

At test case will be pushed shortly (courtesy of Gnomi).
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0002237)
zesstra   
2014-02-25 23:41   
I guess, I found the culprit. skip_to() is called with nothing left in the buffer, but does not check itself if the first character it processes is actually the \0 at the end of the buffer... And then it just reads happily along outside of the buffer.
(0002246)
guest   
2015-02-06 15:39   
Fix committed in revision 8aa760447fdb0488f22ccd97ceb2f7b602a8c3f0 to master branch (see changeset 983 for details). Thank you for reporting!
(0002311)
Gnomi   
2018-01-29 19:59   
Fix committed in revision 8aa760447fdb0488f22ccd97ceb2f7b602a8c3f0 to master branch (see changeset 1410 for details). Thank you for reporting!
(0002362)
Gnomi   
2018-01-29 22:57   
Fix committed in revision 8aa760447fdb0488f22ccd97ceb2f7b602a8c3f0 to master branch (see changeset 2738 for details). Thank you for reporting!
(0002413)
Gnomi   
2018-01-30 04:59   
Fix committed in revision 8aa760447fdb0488f22ccd97ceb2f7b602a8c3f0 to master branch (see changeset 3823 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
828 [LDMud 3.5] Efuns major N/A 2013-09-27 23:02 2018-01-30 04:59
Reporter: zesstra Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Secure or remove export_uid().
Description: export_uid() can be used to change an objects UID to the calling objects euid if the target object has no euid.

seteuid() usually calls valid_seteuid(), BUT: it does NOT if an object clears its euid.

The result is that there is no nice way to prevent that objects change UIDs and it can be a major loop hole in UID based access rights.
(I don't consider an sefun export_uid() "nice".)

Suggestions:
1) call valid_seteuid() in the master also for clearing the euid.
2) raise a privilege violation for export_uid().
3) remove export_uid() altogether.

Concerning 3) I quote the source of export_uid:
 * TODO: seteuid() goes through the mudlib, why not this one, too?
 * TODO:: Actually, this efun is redundant, archaic and should
 * TODO:: vanish altogether.

Actually my suggestion is 3) for 3.5.0 and also 1) for the sake of consistency of seteuid().
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002209)
fufu   
2013-09-28 15:03   
I wouldn't miss this function. So 3) for 3.5.0 sounds good.

I disagree with 1): conceptually, set_euid(0) only drops privileges, and I see no reason to ever forbid that. The presence of export_uid() does not change that (yes, objects with euid 0 may experience sudden increases of power, but that's the fault of whoever exported their uid to them). It's just very very hard to use export_uid() safely.

The purpose of export_uid() is delegation. It comes with a hefty contract, something like

=== export_uid(X) (called by Y) contract ===
I, the undersigned, hereby grant all my rights and privileges to X. X may act on my behalf to the full extend that LPC code permits. I take full responsibility for X' actions.

Y <unreadable>
===

Calls to export_uid() should be audited, which points towards 2) as the proper solution.

Because of its contract, there is little use for export_uid() inside a mudlib. I believe it was designed for a very narrow purpose, namely for wizard tools developed in various home directories. When a wizard developed a tool, often other wizards would want to try it out. To use the tool, those wizards would have to copy it to their own home directory; (e)uids would cause trouble otherwise. export_uid() offers an alternative to copying: The wizard could grant her power to the tool (the initial euid would be 0 already on the muds I've seen) and then use it as her own.
(0002210)
fufu   
2013-09-28 19:19   
On second thought, why does export_uid change the uid of an object and not its euid? That's strange, and indeed dangerous. Changing the euid should be enough for delegation.
(0002211)
zesstra   
2013-09-29 18:13   
I agree Fuchur.
And for changing the euid we already have a function - although in that case privileges are not pushed, but requested...

Concerning the problem with the wizard tools: we use the 'backbone uid mechanism', i.e. in specific directories (where objects would get the backbone uid) every object created gets the (e)UID of the object creating the new object. That UID is meant to be permanent and the mudlib master decides. That solves it sufficiently for us.

Concerning dropping the euid: yes, there seems to be little reason to forbid it. But if we raise a privilege violation upon every attempt of changing an euid it is the decision of the mud(lib) and that seems to be more 'consistent' to me. But I can live without it since we would not limit changing the euid to 0.
(0002214)
Gnomi   
2013-09-30 12:38   
I agreee with Fuchur, that export_uid should be renamed to export_euid and change the euid. We have to keep in mind that mudlibs must be adapted accordingly, this can not be simulated, because uids become constant this way.

I'm a bit hesitant about removing this functin altogether, because it's not easy to simulate it safely. (We have the backbone uid mechanism only for mudlib objects. For wizard tools that other wizards provide there is a trust mechanism, that exports the uid only if the tool hasn't modified since the permission was given.)

Maybe extend seteuid(string euid) to seteuid(string euid, object ob)? That way export_euid can be implemented and has master oversight. (But this is a dangerous change as valid_seteuid must now also check previous_object(), maybe only allow it from master and simul-efun...)
(0002215)
zesstra   
2013-10-01 00:07   
We also use the BB mechanism only for mudlib objects and wizard tools located in a directory only admins have write-access to.

I think, I prefer to have a seteuid() like you described to a separate export_euid(). It is probably OK since mud admins anyway have to read the migration documents for 3.5...

(Just my personal opinion FTR: I think, immutable UIDs are a sane thing given that we have eUIDs.)
(0002279)
zesstra   
2016-12-08 23:35   
I guess, seteuid() with the ability to set the euid of other objects would be the most appealing approach for me. However, I don't have much preference for seteuid() or export_euid()...
But why not give valid_seteuid() both the changed object and (as new 3rd argument) the changing object as arguments?
(0002280)
Gnomi   
2016-12-09 00:47   
On existing implementations of valid_seteuid() the new third parameter would be silently ignored (if some mud admin overlooked that change and didn't adapt the mudlib accordingly). I'm not sure about the security implications of that. Other objects would then be able to do euid changes that only the object could do to itself.

That's why I'm thinking about entirely new interface for that, something like configure_object(ob, OC_EUID) with its privilege checks.
(0002281)
zesstra   
2016-12-30 18:59   
Ah, yes. This is clear - my confusion was the the requirement to check previous_object() instead of an explicit argument.

I believe, during the update to 3.5.x mud admins anyway have to check for a bunch of stuff. However, a new interface is a safer way, I agree. And operators could create a simul_efun facilitating configure_object(ob, OC_EUID) if desired.

From my viewpoint as admin in Morgengrauen: I can live with both approaches, we use export_uid and allow it anyway only for ROOT objects.
(0002293)
zesstra   
2018-01-28 22:31   
Fix committed in revision cf06dff217a9ec4bed455885400b1832ff798a26 to master branch (see changeset 1142 for details). Thank you for reporting!
(0002300)
Gnomi   
2018-01-29 19:59   
Fix committed in revision cf06dff217a9ec4bed455885400b1832ff798a26 to master branch (see changeset 1206 for details). Thank you for reporting!
(0002346)
Gnomi   
2018-01-29 20:34   
Fix committed in revision cf06dff217a9ec4bed455885400b1832ff798a26 to master branch (see changeset 2407 for details). Thank you for reporting!
(0002351)
Gnomi   
2018-01-29 22:57   
Fix committed in revision cf06dff217a9ec4bed455885400b1832ff798a26 to master branch (see changeset 2529 for details). Thank you for reporting!
(0002402)
Gnomi   
2018-01-30 04:59   
Fix committed in revision cf06dff217a9ec4bed455885400b1832ff798a26 to master branch (see changeset 2406 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
825 [LDMud 3.5] Implementation minor N/A 2013-08-18 20:52 2018-01-30 04:59
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.6.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: sprintf.c contains several theoretical buffer overflows with checks and fatal() calls
Description: sprintf.c has 3 occurances of this construct:

(writing with strcat/sprintf in temp)
tmpl = strlen(temp);
if ((size_t)tmpl >= sizeof(temp))
     fatal("Local buffer overflow in sprintf() for int.\n");

These calls to fatal() are completely unnecessary, because we could use snprintf() or strncat() and prevent the buffer overflow in the first place.
Tags: sprintf
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0002208)
zesstra   
2013-08-31 01:08   
Fixed in master now.
(0002317)
zesstra   
2018-01-29 19:59   
Fix committed in revision ebf1fc941bd0668866cdaceeab81860617e3ec01 to master branch (see changeset 1485 for details). Thank you for reporting!
(0002368)
zesstra   
2018-01-29 22:57   
Fix committed in revision ebf1fc941bd0668866cdaceeab81860617e3ec01 to master branch (see changeset 2814 for details). Thank you for reporting!
(0002419)
zesstra   
2018-01-30 04:59   
Fix committed in revision ebf1fc941bd0668866cdaceeab81860617e3ec01 to master branch (see changeset 3898 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
818 [LDMud 3.5] Documentation text N/A 2013-05-26 20:43 2018-01-30 04:59
Reporter: Sorcerer Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: Typos in German man pages for efuns
Description: call_out.de:
... einen Loop erzeug (keine Rekurison). -> erzeugt

interactive.de:
Wird <obj> weggelassen, wird this_object()verwendet. -> this_object()
verwendet. (Leerstelle)

call_out_info.de:
Liefert Informationen ueber alle haengigen call_out()s. -> laufende call_out()s. (Nicht wirklich ein Typo, aber 'laufende' wird auch in anderen Manpages als Uebersetzung fuer 'pending' verwendet und 'haengig' ist eher in der Schweiz gebraeuchlich.)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002319)
Gnomi   
2018-01-29 19:59   
Fix committed in revision 5e4bd1e54a9fc599c7781e17ddf4e9a856c2ad3d to master branch (see changeset 1498 for details). Thank you for reporting!
(0002370)
Gnomi   
2018-01-29 22:57   
Fix committed in revision 5e4bd1e54a9fc599c7781e17ddf4e9a856c2ad3d to master branch (see changeset 2827 for details). Thank you for reporting!
(0002421)
Gnomi   
2018-01-30 04:59   
Fix committed in revision 5e4bd1e54a9fc599c7781e17ddf4e9a856c2ad3d to master branch (see changeset 3911 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
816 [LDMud 3.3] Runtime crash always 2013-02-23 14:05 2018-01-30 04:59
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: immediate OS Version: 10.6.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.721  
    Target Version: 3.3.721  
Summary: Crash during compact_mapping()
Description: LDMud crashed in svalue_cmp() during compact_mapping(), because the number of values in the hash part of the mapping was not correct.

The happened, because resize_mapping (used for copy_mapping(), copy(), m_reallocate()) skipped keys referencing destructed objects, but did not correct the number of keys in the hash part, resulting in a hash part having less keys than stated in .hash.used. With the 'right' number of destructed keys and non-destructed keys, this led to the crash.
(The bug was in the driver since 2007, so this situation seems to be rather rare in practice - however after 6 years MG crashed 2 times in 2 days because of this...)
Tags:
Steps To Reproduce: mapping m;
void create()
{
    if (clonep()) return;
    mapping m2 = ([clone_object(__FILE__): 1, clone_object(__FILE__)
        :2, 1:2, 2:3, 3:4, 4:5, 5:6, 6:7, 7:8, 8:9, 9:10, 10:11,
      11:12, 12:13,13:14]);
    object* keys = m_indices(m2);
    filter(keys,#'objectp)->remove();
    m=m_reallocate(m2,1);
    efun::garbage_collection("/log/gc");
}
void remove() {destruct(this_object());}
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0002185)
zesstra   
2013-02-24 00:23   
Fix committed in revision e76051d15a884d138443e90612de382654767acf to master-3.3 branch (see changeset 892 for details). Thank you for reporting!
(0002186)
zesstra   
2013-02-24 00:23   
Fix committed in revision ceffa04550b6cd7d0b30ef6401fe860e288173a9 to master branch (see changeset 893 for details). Thank you for reporting!
(0002320)
zesstra   
2018-01-29 19:59   
Fix committed in revision e76051d15a884d138443e90612de382654767acf to master-3.3 branch (see changeset 2198 for details). Thank you for reporting!
(0002371)
zesstra   
2018-01-29 22:57   
Fix committed in revision e76051d15a884d138443e90612de382654767acf to master-3.3 branch (see changeset 3542 for details). Thank you for reporting!
(0002422)
zesstra   
2018-01-30 04:59   
Fix committed in revision ceffa04550b6cd7d0b30ef6401fe860e288173a9 to master branch (see changeset 3915 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
809 [LDMud 3.5] Efuns minor always 2012-08-26 15:37 2018-01-30 04:59
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.5.0  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: object_info returns wrong data for OIM_TOTAL_DATA_SIZE
Description: # object_info(find_object("/p/daemon/pathd"), OINFO_MEMORY, OIM_TOTAL_DATA_SIZE)
-> Result: 140622890962784

# debug_info(DINFO_MEMORY,find_object("/p/daemon/pathd"))
-> data size 6456183 (9627190)

Obviously, something is wrong here...
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002156)
zesstra   
2012-12-04 19:18   
Fix committed in revision 7856c1472afc12a04de2db5e71391c80fcf3656b to master branch (see changeset 874 for details). Thank you for reporting!
(0002157)
zesstra   
2012-12-04 19:19   
Fix committed in revision 0f1746d220d95b82ac5ae705a0390348c0534374 to master-3.3 branch (see changeset 875 for details). Thank you for reporting!
(0002324)
zesstra   
2018-01-29 19:59   
Fix committed in revision 0f1746d220d95b82ac5ae705a0390348c0534374 to master-3.3 branch (see changeset 2204 for details). Thank you for reporting!
(0002375)
zesstra   
2018-01-29 22:57   
Fix committed in revision 0f1746d220d95b82ac5ae705a0390348c0534374 to master-3.3 branch (see changeset 3548 for details). Thank you for reporting!
(0002426)
zesstra   
2018-01-30 04:59   
Fix committed in revision 7856c1472afc12a04de2db5e71391c80fcf3656b to master branch (see changeset 3928 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
808 [LDMud 3.5] Documentation text N/A 2012-08-23 22:52 2018-01-30 04:59
Reporter: Sorcerer Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: add details to query_idle() man-page
Description: A wizard in our mud suggested to add to the man page of query_idle() a comment on the behavior upon passing a non-interactive object as argument. My suggestions for the addition follow below:

English:
Query how many seconds a user object <ob> has been idle. If <ob> is not an interactive user an error will be thrown.

German:
Gibt an, seit wie vielen Sekunden ein Player Objekt <ob> idle ist. Falls <ob> kein interaktiver Spieler ist, wird eine Fehlermeldung ausgegeben.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002158)
zesstra   
2012-12-04 19:44   
Fix committed in revision 141480d56990b1d6ad0accad7d0db76b072fa365 to master-3.3 branch (see changeset 876 for details). Thank you for reporting!
(0002159)
zesstra   
2012-12-04 19:44   
Fix committed in revision f7b08ec5bccb78a1d111d54fc47657aa5d07e244 to master branch (see changeset 877 for details). Thank you for reporting!
(0002323)
zesstra   
2018-01-29 19:59   
Fix committed in revision 141480d56990b1d6ad0accad7d0db76b072fa365 to master-3.3 branch (see changeset 2203 for details). Thank you for reporting!
(0002374)
zesstra   
2018-01-29 22:57   
Fix committed in revision 141480d56990b1d6ad0accad7d0db76b072fa365 to master-3.3 branch (see changeset 3547 for details). Thank you for reporting!
(0002425)
zesstra   
2018-01-30 04:59   
Fix committed in revision f7b08ec5bccb78a1d111d54fc47657aa5d07e244 to master branch (see changeset 3927 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
802 [LDMud 3.5] Implementation minor always 2012-02-17 22:49 2018-01-30 04:59
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: MacOS X  
Priority: normal OS Version: 10.6.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Lower 11 bits missing for 64 bit wide random numbers
Description: The result of random(__INT_MAX__) on LP64 platforms has only 53 random bits, the lower 11 bits are always 0. One effect is, that all these numbers are even.
The reason is that we intermediately convert the result of the PRNG to double, which has only a precision of 53 bits, so the rest get lost.

The simplest way is to use long double intermediately, but this does not work with all platforms/compilers (e.g. MS VC++ uses long double as synonym for double).
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files: mult.c (1,362 bytes) 2015-05-10 22:44
http://ldmud.eu/file_download.php?file_id=289&type=bug
Notes
(0002171)
zesstra   
2012-12-08 21:52   
Ok, I had a look into two possibilities to fix this:

1) Use the scaling method with intermediate floats. This needs long double, which are less portable.
2) Since the MT has a quite good distribution, we might get away with just using plain modulo. This would be more portable.

I will attach a comparison between the current state and the two alternatives. The spreadsheet contains some raw data for equally long bitstreams generated by random(2^n) and three graphs comparing the bits of entropy per bit, the Chi^2 and the serial correlation factor.
Based on that I think the difference in quality between both approaches is not to great.
What do you think?
(0002180)
Gnomi   
2012-12-28 09:49   
(Last edited: 2012-12-28 09:49)
Or we could do integer arithmetic, this function does rand * n >> BITS, assuming that rand has BITS number of random bits:

p_uint scale(p_uint rand, p_uint n)
{
#define BITS (sizeof(p_int)*8)
#define HBITS (BITS/2)
#define HMASK ((1<<HBITS) - 1)

    p_uint rand_h = rand >> HBITS;
    p_uint rand_l = rand & HMASK;

    p_uint n_h = n >> HBITS;
    p_uint n_l = n & HMASK;

    p_uint result_h = rand_h * n_h;
    p_uint result_l = rand_h * n_l;

    result_h += result_l >> HBITS;
    result_l &= HMASK;
    result_l += rand_l * n_h;
    result_h += result_l >> HBITS;
    result_l &= HMASK;
    result_l += (rand_l * n_l) >> HBITS;
    result_h += result_l >> HBITS;

    return result_h;
}

(0002294)
zesstra   
2018-01-28 22:31   
Fix committed in revision 82f7fccf36d8e5767384750adce3a004d78f878c to master branch (see changeset 1143 for details). Thank you for reporting!
(0002301)
Gnomi   
2018-01-29 19:59   
Fix committed in revision 82f7fccf36d8e5767384750adce3a004d78f878c to master branch (see changeset 1207 for details). Thank you for reporting!
(0002347)
Gnomi   
2018-01-29 20:34   
Fix committed in revision 82f7fccf36d8e5767384750adce3a004d78f878c to master branch (see changeset 2408 for details). Thank you for reporting!
(0002352)
Gnomi   
2018-01-29 22:57   
Fix committed in revision 82f7fccf36d8e5767384750adce3a004d78f878c to master branch (see changeset 2530 for details). Thank you for reporting!
(0002403)
Gnomi   
2018-01-30 04:59   
Fix committed in revision 82f7fccf36d8e5767384750adce3a004d78f878c to master branch (see changeset 2409 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
798 [LDMud 3.5] Efuns minor always 2011-12-09 17:56 2018-01-30 04:59
Reporter: Sorcerer Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: deprecate/remove strlen()
Description: As far as I can tell, strlen() does exactly the same as sizeof() with the one exception that it only accepts strings as argument. But exactly in this there is an inconsistency: usually, efuns that expect strings as argument throw an error upon passing 0. strlen accepts 0.

So, if there are no internal differences between strlen() and sizeof() that favor strlen() I suggest to deprecate it and in some future after 3.5 remove it. If someone really needs it at that point for compatibility, a sefun returning sizeof() does the trick.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002088)
zesstra   
2011-12-10 00:47   
These two efuns currently have the same result, but not really the same meaning.
We discussed that 2-3 years ago in some issue about wide char strings.
As soon as we will introduce wide char strings (e.g. UTF16), sizeof() and strlen() will start to differ (sizeof(): no of bytes, strlen(): no of characters).
Therefore I always recommend to use strlen() if a wizard wants to know the no of characters.
So I don't think we should deprecate strlen().
(0002089)
Gnomi   
2011-12-10 00:54   
I disagree. Even with unicode support sizeof() should return the number of characters, not bytes. Sizeof() never returns the number of bytes, it returns the number of elements in arrays, mappings or strings. And it does so because the number of bytes are not relevant to the wizard in any way. Also for wide strings all string indexing functions would work on a character basis, so the byte count is never needed.
(0002090)
Gnomi   
2011-12-10 01:00   
So I'm in favor of deprecating strlen().
(0002091)
zesstra   
2011-12-10 01:02   
I was sure, the discussion a few years ago was in the other direction. ;-) But maybe it was not you, but someone else. I agree, that the indexing operator for strings should work on the basis of characters.
One problem is, that for some applications you have to know to length of a string in bytes (e.g. you want to send over the network and no \0 termination). They might be rarely used in MUDs, but I would take them into account.
(0002092)
Gnomi   
2011-12-10 01:08   
When sending a unicode string you first have to convert it into a specific encoding, yielding a kind of array of bytes. This byte array is no more a unicode string, but would be treated like a ASCII string (the kind we have now), where strlen() and sizeof() would return the number of bytes (as it is now).
(0002233)
zesstra   
2014-02-23 23:41   
I will add a comment to the manpage of strlen(). But we will wait a bit for deprecating strlen() in the code so that our users can first work on a plethora of new type errors in their mudlibs. ;-)
(0002255)
zesstra   
2015-05-10 22:29   
We will also remove this one in 3.5.0 since it is a simple replacement by script or sefun.
(0002273)
zesstra   
2016-01-20 17:17   
Fix committed in revision 41a17400ede247f0ef6b894d204f66baddbc41ab to master branch (see changeset 1044 for details). Thank you for reporting!
(0002305)
zesstra   
2018-01-29 19:59   
Fix committed in revision 41a17400ede247f0ef6b894d204f66baddbc41ab to master branch (see changeset 1350 for details). Thank you for reporting!
(0002356)
zesstra   
2018-01-29 22:57   
Fix committed in revision 41a17400ede247f0ef6b894d204f66baddbc41ab to master branch (see changeset 2676 for details). Thank you for reporting!
(0002407)
zesstra   
2018-01-30 04:59   
Fix committed in revision 41a17400ede247f0ef6b894d204f66baddbc41ab to master branch (see changeset 3763 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
794 [LDMud] Documentation text N/A 2011-11-23 07:48 2018-01-30 04:59
Reporter: _xtian_ Platform:  
Assigned To: zesstra OS:  
Priority: low OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: add to doc/modyfiers
Description: add to private function part:

change:
       private -- such functions can only be called with an internal
                     call from within this file. Not even inheriting
                     objects can call these functions. You can nevertheless
                     build an lfun-closure with #' out of a private function.


       private -- such functions can only be called with an internal
                     call from within this file. Not even inheriting
                     objects can call these functions. You can nevertheless
                     build an lfun-closure with #' out of a private function
+ (but you cannot save and restore it).

Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002223)
ldmud-bugs   
2014-02-23 20:23   
Fix committed in revision 696aee6297ae079cd0562deab88b028cc8f8d8bf to master branch (see changeset 933 for details). Thank you for reporting!
(0002225)
ldmud-bugs   
2014-02-23 20:26   
Fix committed in revision 07bc181cdf7918be8e11ccff40630908a53f3806 to umaster-3.3 branch (see changeset 935 for details). Thank you for reporting!
(0002316)
zesstra   
2018-01-29 19:59   
Fix committed in revision 07bc181cdf7918be8e11ccff40630908a53f3806 to master-3.3 branch (see changeset 2197 for details). Thank you for reporting!
(0002367)
zesstra   
2018-01-29 22:57   
Fix committed in revision 07bc181cdf7918be8e11ccff40630908a53f3806 to master-3.3 branch (see changeset 3541 for details). Thank you for reporting!
(0002418)
zesstra   
2018-01-30 04:59   
Fix committed in revision 696aee6297ae079cd0562deab88b028cc8f8d8bf to master branch (see changeset 3852 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
791 [LDMud 3.5] Efuns minor always 2011-10-31 19:54 2018-01-30 04:59
Reporter: Leonidas Platform: Win32  
Assigned To: zesstra OS: Windows  
Priority: low OS Version: Win7-64  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: ldmud-3.5.0_svn2973: 32bit-restore_object() does not balk at reading 64bit-integers in a mapping
Description: Modified value in savefile of player (XP stored as int value in a mapping assigned to string key). Upon login no error/warning occured - bits 33-64 seem to be simply ignored.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002160)
zesstra   
2012-12-04 21:27   
I have prepared a patch for issuing a warning in this case. However, I would like to have comments on it, because:
a) should it be a hard error or the warning?
b) I changed the number parsing to use strtoimax() - anybody thinks this is a problem?
c) I think, in case of int number a wrong adresse in <pt> was returned - the address of the delimeter, not the address of the char behind the delimeter. (line 8371)
d) a second patch changes restoring floats on foreign hosts to use strtod() instead of the deprecated atof(). Throws a warning upon overflows now as well.

The diff and the two commits are at:
https://github.com/zesstra/ldmud/compare/master...791-intoverflow
(0002183)
zesstra   
2013-01-21 23:56   
Fix committed in revision 890dfee0e56ef559c9af0ad11e7511313a0b166d to master branch (see changeset 888 for details). Thank you for reporting!
(0002321)
zesstra   
2018-01-29 19:59   
Fix committed in revision 890dfee0e56ef559c9af0ad11e7511313a0b166d to master branch (see changeset 1506 for details). Thank you for reporting!
(0002372)
zesstra   
2018-01-29 22:57   
Fix committed in revision 890dfee0e56ef559c9af0ad11e7511313a0b166d to master branch (see changeset 2836 for details). Thank you for reporting!
(0002423)
zesstra   
2018-01-30 04:59   
Fix committed in revision 890dfee0e56ef559c9af0ad11e7511313a0b166d to master branch (see changeset 3919 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
790 [LDMud] LPC Language tweak N/A 2011-10-27 11:32 2018-01-30 04:59
Reporter: _xtian_ Platform:  
Assigned To: zesstra OS:  
Priority: low OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: officially deprecate "static" (in variables and functions)
Description: I thought, I'd just put this up on the agenda:

pro deprecation:
- completely different use of "static" in other languages confuses a lot of programmers
- in variables: has been replaced by "nosave" for ages
- in functions: has no real unique use. Security mechanisms are better implemented via stack-based approach (see comments in https://ldmud.eu/mantis/view.php?id=751)

con deprecation:
- mudlibs have to be changed. not a lot of programmers left.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002070)
zesstra   
2011-10-27 11:58   
Pheeewww. While I am usually in favor of clean-up, I think, I am very reluctant in this case:
1) MG has about 45000 variables+function which use static. That is a lot and probably similar in other muds.
2) protected and static are not completely equivalent. There are still applications where I deliberately use static, because I want that call_other(this_object, ...) can call the function.
Also, I am actually not sure at the moment, if you can execute protected functions in this_object() with command() as it is possible with static...
(0002071)
zesstra   
2011-10-31 13:43   
Setting to feedback until we got feedback from several people.
(0002075)
_xtian_   
2011-11-01 17:34   
Yes, with less and less programmers we should not burden us with uneccesary incompatible changes, you are right.
But maybe just a comment in the documentation would be nice? (you shouldn't use this in new code)
(0002224)
ldmud-bugs   
2014-02-23 20:23   
Fix committed in revision 9f018133b1c1c5b473a751d862addb563e0710b0 to master branch (see changeset 934 for details). Thank you for reporting!
(0002226)
ldmud-bugs   
2014-02-23 20:26   
Fix committed in revision 632d68bf9427f177312b38461690923790302efd to umaster-3.3 branch (see changeset 936 for details). Thank you for reporting!
(0002315)
zesstra   
2018-01-29 19:59   
Fix committed in revision 632d68bf9427f177312b38461690923790302efd to master-3.3 branch (see changeset 2196 for details). Thank you for reporting!
(0002366)
zesstra   
2018-01-29 22:57   
Fix committed in revision 632d68bf9427f177312b38461690923790302efd to master-3.3 branch (see changeset 3540 for details). Thank you for reporting!
(0002417)
zesstra   
2018-01-30 04:59   
Fix committed in revision 9f018133b1c1c5b473a751d862addb563e0710b0 to master branch (see changeset 3851 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
788 [LDMud 3.3] Networking major always 2011-10-09 13:28 2018-01-30 04:59
Reporter: _xtian_ Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.721  
    Target Version:  
Summary: long telnet neg messages are cut off
Description: In comm.c::telnet_neg() long telnet negotiations are cut off after 2048 (minus overhead) chars. The assumption here is that telnet negs should simply not be that long.

The assumption is obviously false. For one there are no limits in the standard and then there are important use-cases where longer texts need to be transmitted over telnet subneg channels.

See:
ATCP composer (sending entire texts over telnet negs): http://www.mudstandards.org/ATCP_composer

See:
As an example Mushclient allowing telnet negs to be any length: http://www.gammon.com.au/scripts/showrelnote.php?version=4.48&productid=0

I am marking this as major bug, since it hinders all ldmud-running MUDs to fully adapt ATCP or GMCP features.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002062)
zesstra   
2011-10-09 22:27   
Well... The limit of 2048 is not just for telnet negs. It is also the size of a users text buffer for incoming data (network receive buffer) and thus the maximum length for every user command.
You might increase them, it is a compile-time constant in comm.h (MAX_TXT).

There are various places where buffers with this length are allocated on the stack. That basically means that we can't easily make them a) runtime-configurable or b) arbitrary length.
But if somebody wants to work on that... (But it might be more reasonable (see below) to define a protocol which can negotiate the length of sub negotiation messages).

Side remark: I am pretty sure, there are a lot telnet implementations which have such limits (I know of some) despite the standard not defining one...
(0002063)
zesstra   
2011-10-09 22:31   
BTW: one might argue, that a) the standard did not have in mind to transfer huge chunks of data via the telnet option subnegotation (since it is about negotiating telnet options/behaviour) and b) since the standard does not define a minimum length any length the implementation chooses, fulfills the standard.
(0002064)
zesstra   
2011-10-10 15:37   
BTW: Why does the composer package anyway send messages incompatible to the ATCP message specification from http://www.mudstandards.org/ATCP_Message_Format?
"Messages going to the server must be less than 2048 bytes in length."

(The 2048 are IMHO still a curious convention: the underlying network buffers are likely to be a power of 2 in size, but you will have some overhead, i.e. the ATCP messages should be slightly smaller than a power of two.)
(0002065)
_xtian_   
2011-10-16 13:45   
I checked and the ATCP link (or specification) you quoted is out of date or they just ignored that constraint later on. Fact is, clients and servers of muds implementing this are both able to send longer texts.

I understand you don't believe in the rationale behind these newer protocols. But ATCP (and GMCP in minor extend) are gaining quite a following and a lot of servers are adding it. It is a step toward enhancing game-experience for players as it allows construction of GUIs and so on ... Personally, I am glad, the community is embracing this and starting to think more about usability of their games. So please don't dismiss ATCP/GMCP related issues referring to other implementations that also don't have those features implemented or speculate about other ways how things may have been more to your liking. These protocols are here, in heavy use (at least in the english speaking community) and we should not lock ourselves out of that.

Having argued, why I think this is important, on a more technical note:
1) the long telnet neg message is not just cut off, as my title suggested, but alltogether discarded. The rest of the long telnet neg is displayed in the normal text stream.

2) a solution that just concats to a LPC string that will be passed to the telnet_neg-hook of the mudlib would be enough, as mudlibs will have to self implement the ATCP stuff themselves anyway.
(0002066)
Gnomi   
2011-10-16 15:25   
There must be some constraint of the length of commands or telnet negotiations, otherwise you could implement DOS attacks by causing an out-of-memory condition. So what will the new limit be?
(0002067)
_xtian_   
2011-10-17 07:49   
I am told IRE muds cut off composer messages at ~20k text.
(0002068)
Gnomi   
2011-10-17 11:20   
So, would setting MAX_TEXT in comm.h to 20480 solve this problem?
(0002069)
_xtian_   
2011-10-26 18:49   
@gnomi: Would probably solve my problem, yes. But I'm not sure if that buffer Define is not used elsewhere.
(0002074)
_xtian_   
2011-11-01 17:32   
I'm fieldtesting a MAX_TEXT of 20480 atm. Will keep you updated.
(0002166)
zesstra   
2012-12-05 20:29   
BTW: How did these tests work? ;-)
(0002167)
_xtian_   
2012-12-06 07:49   
I observed no problems in the past year.
Allow me to suggest making the higher value the new standard.
(0002168)
zesstra   
2012-12-06 20:10   
Fix committed in revision f8edc687ea7e6841fa19325be0d287affcd48258 to master branch (see changeset 878 for details). Thank you for reporting!
(0002169)
zesstra   
2012-12-06 20:12   
Fix committed in revision 4c5e08509dea53cb14ec02d83b16aa9fa30be434 to master-3.3 branch (see changeset 879 for details). Thank you for reporting!
(0002322)
zesstra   
2018-01-29 19:59   
Fix committed in revision 4c5e08509dea53cb14ec02d83b16aa9fa30be434 to master-3.3 branch (see changeset 2202 for details). Thank you for reporting!
(0002373)
zesstra   
2018-01-29 22:57   
Fix committed in revision 4c5e08509dea53cb14ec02d83b16aa9fa30be434 to master-3.3 branch (see changeset 3546 for details). Thank you for reporting!
(0002424)
zesstra   
2018-01-30 04:59   
Fix committed in revision f8edc687ea7e6841fa19325be0d287affcd48258 to master branch (see changeset 3926 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
784 [LDMud 3.3] Compilation, Installation minor always 2011-05-29 18:23 2018-01-30 04:59
Reporter: arkas Platform:  
Assigned To: zesstra OS:  
Priority: high OS Version:  
Status: resolved Product Version: 3.3.720  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.721  
    Target Version: 3.3.721  
Summary: iconv version check
Description: src/configure checks for broken iconv in glibc 2.0-2.2 with egrep ' 2\.[0-2]'. This matches on newer versions (i. e. "iconvconfig (Debian EGLIBC 2.11.2-10) 2.11.2") too.
' 2\.[0-2]\.' seems to be more appropriate.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: iconv_check.patch (560 bytes) 2011-05-29 18:23
http://ldmud.eu/file_download.php?file_id=269&type=bug
Notes
(0002055)
zesstra   
2011-05-29 19:48   
I actually would suggest to remove that specific check altogether - glibc-2.0.* should be very rare by now.
(0002060)
zesstra   
2011-09-21 13:11   
I believe this is fixes in trunk and trunk-3.3 by removing the whole check for these ancient glibc.
I am sorry that it took so long, I originally wanted to solve it within my autoconf work (write a new configure.in from scratch), but the was severely delayed...
(0002128)
zesstra   
2012-06-04 22:48   
Fix committed in revision 3fce191ce47bd7f259112f476e484392cd165812 to master-3.3 branch (see changeset 849 for details). Thank you for reporting!
(0002328)
zesstra   
2018-01-29 19:59   
Fix committed in revision 3fce191ce47bd7f259112f476e484392cd165812 to master-3.3 branch (see changeset 2211 for details). Thank you for reporting!
(0002379)
zesstra   
2018-01-29 22:57   
Fix committed in revision 3fce191ce47bd7f259112f476e484392cd165812 to master-3.3 branch (see changeset 3555 for details). Thank you for reporting!
(0002430)
zesstra   
2018-01-30 04:59   
Fix committed in revision 8e1af96cdbf514b447cc784d02a5d9c9d81cbdfb to master branch (see changeset 3985 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
778 [LDMud 3.5] Implementation minor have not tried 2011-02-14 15:16 2018-01-30 04:59
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Permamently activate new cleanup behaviour: remove NEW_CLEANUP and LOG_NEW_CLEANUP
Description: see title
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002163)
zesstra   
2012-12-05 01:11   
Note to myself: switch NEW_CLEANUP should be removed, but LOG_NEW_CLEANUP helped me to debug something shortly ago, so maybe keep it...
(0002253)
zesstra   
2015-05-06 20:21   
The debug logging code remains in the driver for now. But it was renamed to LOG_CLEANUP.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
776 [LDMud 3.5] LPC Language minor N/A 2011-02-14 14:34 2018-01-30 04:59
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: RfC: Remove alists permanently
Description: Should we remove alists from the driver permanently?
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001975)
zesstra   
2011-02-14 14:35   
I have to admit: I am not objective here, because the alists are still used in Morgengrauen. Not often, but at some places.
Therefore, I will absent.
(0001993)
Sorcerer   
2011-02-14 23:42   
I also used alists in several places in the past and since they are working fine and do not interfere with more up-to-date implementations I would prefer them to stay.
Of course, I am also biased by my own older works, as Zesstra stated above but shouldn't exactly those biases be reflected here? If we want a "clean, up-to-date language", we have to throw alists out. But I think, what we rather want to have is a language that is not overweighted with old stuff but not at the cost of sacrificing backwards compatibility, if a lot of people use it.

-1 for removing alists (+1 for keeping them ;-) )
(0002018)
fufu   
2011-02-21 11:01   
I'm in favor of removing alists, but I have no strong arguments for or against. (I'm biased too: Wunderland does not use alists.)
(0002020)
Gnomi   
2011-02-21 23:55   
+1 for removing alists. (I'm biased, UNItopia threw them out ten years ago.)

Of course we should provide replacement-simul-efuns for backward compatibility.
(0002027)
Coogan   
2011-02-24 00:50   
-1 for removing alists, as they are still used in Tubmud esp. in some core files of the lib.
But I'd agree to set their state to deprecated.
(0002136)
zesstra   
2012-06-09 11:43   
After giving it some thoughts again: If we provide replace sefuns, I am actually fine with removing them.
So, I will change my vote to +1 for removing from LDMud LPC.
(0002162)
zesstra   
2012-12-05 00:23   
We now have a few less alists in Morgengrauen... ;-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
775 [LDMud 3.5] LPC Language minor N/A 2011-02-14 13:35 2018-01-30 04:59
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Remove add_light() / configuration switch USE_SET_LIGHT
Description: I suggest to remove add_light() for good.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002250)
zesstra   
2015-05-01 12:06   
Fix committed in revision e7d2b16c72db603252e4184e7ff5154d29db6032 to master branch (see changeset 991 for details). Thank you for reporting!
(0002309)
zesstra   
2018-01-29 19:59   
Fix committed in revision e7d2b16c72db603252e4184e7ff5154d29db6032 to master branch (see changeset 1402 for details). Thank you for reporting!
(0002360)
zesstra   
2018-01-29 22:57   
Fix committed in revision e7d2b16c72db603252e4184e7ff5154d29db6032 to master branch (see changeset 2729 for details). Thank you for reporting!
(0002411)
zesstra   
2018-01-30 04:59   
Fix committed in revision e7d2b16c72db603252e4184e7ff5154d29db6032 to master branch (see changeset 3815 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
774 [LDMud 3.5] LPC Compiler/Preprocessor minor N/A 2011-02-14 00:20 2018-01-30 04:59
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Remove configuration switch USE_ARRAY_CALLS
Description: Since we decided on keeping the call-others on arrays in 0000213 we still have to decide if we keep the configuration switch USE_ARRAY_CALLS.

The suggestion is to remove the switch and always allow callother on arrays in order to restrict fragmentation of the LDMud-LPC.

For Muds who don't want to have them in the code, there would be two options: a) disallow them in the codestyle or b) disallow them in a sefun if a) ist not sufficient.

I arbitrarily decide that this issue has a discussion timeout of 30 days. ;-)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001969)
zesstra   
2011-02-14 00:21   
Please throw in you opinion.
(0001971)
zesstra   
2011-02-14 00:30   
My vote: +1 for removing the configuration switch
(0001977)
graveluth   
2011-02-14 15:21   
+1 for removing the configuration switch
(0001978)
_xtian_   
2011-02-14 15:29   
+1 for removing configuration
(0001992)
Sorcerer   
2011-02-14 23:36   
+1 in favor of removing this switch
(0002017)
fufu   
2011-02-21 10:44   
-1 from me, still for the reasons I gave in 0000213 and 0000663.
(0002019)
Gnomi   
2011-02-21 23:51   
+1 for removing the configuration switch.
(0002052)
zesstra   
2011-05-26 22:23   
Ok, the 30 days were slightly longer... Looking at the poll results this is then settled and feedback phase is over...
(0002133)
zesstra   
2012-06-06 23:32   
Fix committed in revision 847b430b418e42caaffeab19daf5f692bfe09b80 to master branch (see changeset 852 for details). Thank you for reporting!
(0002326)
zesstra   
2018-01-29 19:59   
Fix committed in revision 847b430b418e42caaffeab19daf5f692bfe09b80 to master branch (see changeset 1534 for details). Thank you for reporting!
(0002377)
zesstra   
2018-01-29 22:57   
Fix committed in revision 847b430b418e42caaffeab19daf5f692bfe09b80 to master branch (see changeset 2864 for details). Thank you for reporting!
(0002428)
zesstra   
2018-01-30 04:59   
Fix committed in revision 847b430b418e42caaffeab19daf5f692bfe09b80 to master branch (see changeset 3947 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
771 [LDMud 3.5] LPC Language minor always 2011-02-09 15:04 2018-01-30 04:59
Reporter: _xtian_ Platform: 3.5  
Assigned To: Gnomi OS: linux  
Priority: low OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: private public void fun() is legal
Description: The parser accepts "private public" as function modifier.
Even in strict_type and strong_type pragmas.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001964)
zesstra   
2011-02-11 00:19   
I did not look into details, but I expect the private in 'private public' takes precedence... Although its quite ridiculous.
BTW: the compiler also accepts 'private static' which is AFAIK also completely senseless. (But I maybe wrong.)
(0002049)
_xtian_   
2011-04-27 05:54   
In my mind "private public" should just not compile.

On the other hand I have often seen "private static" functions - a misconception some programmers take from other programming languages - so here it might be better just to throw a warning.
(0002296)
zesstra   
2018-01-28 22:31   
Fix committed in revision 3dec4517cd33d0b26a93e4de77f736c135d45ce4 to master branch (see changeset 1180 for details). Thank you for reporting!
(0002303)
Gnomi   
2018-01-29 19:59   
Fix committed in revision 3dec4517cd33d0b26a93e4de77f736c135d45ce4 to master branch (see changeset 1244 for details). Thank you for reporting!
(0002354)
Gnomi   
2018-01-29 22:57   
Fix committed in revision 3dec4517cd33d0b26a93e4de77f736c135d45ce4 to master branch (see changeset 2568 for details). Thank you for reporting!
(0002405)
Gnomi   
2018-01-30 04:59   
Fix committed in revision 3dec4517cd33d0b26a93e4de77f736c135d45ce4 to master branch (see changeset 2461 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
769 [LDMud 3.5] LPC Compiler/Preprocessor minor N/A 2011-01-12 22:35 2018-01-30 04:59
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: String storage in LPC compiler: hash table needlessly complex?
Description: The compiler uses a short hash table (prog_string_indizes[256]) for keeping track of strings in a program. Additionally, it has a [32], where it stores which hash chains in prog_string_indizes are in use. It decides this like this:
  /* Bitflags showing which entries in prog_string_indizes[] are valid:
   * if (_tags[n] & (1 << b)) then _indizes[n*8 + b] is valid.
   */

I actually think this is needlessly complicated. It could just store -1 in prog_string_indizes for unused entries/chains.

My guess is that in former times the coder did not want to initialize the 256-long hash table and did initialize the 32-long prog_string_tags table instead (anyone with a better guess?). However, this assumption is not necessarily true. On my machine memset() takes actually longer to write 32 bytes than to write 256 bytes (x86_64, on x86 the 32 bytes are written marginally faster than 256). And besides the more complex code the prices is to do two calculations each time a string is searched (granted: they are fast and simple).

I tend to remove this prog_string_tags, but I would like to hear some opinions.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002031)
Coogan   
2011-02-24 01:16   
Who's opinions do you want to hear? I doubt that more than a handful of persons know the driver that good from the inside.
(0002044)
zesstra   
2011-02-25 10:19   
Sometimes someone remembers a specific reason. ;-)
(0002045)
lars   
2011-02-26 02:55   
I don't know the exact reason either, but this may have been a micro-optimization aimed at reducing the amount of data read from memory when searching for a hash spot. Given the architecture changes over the last 20 years, the original reasoning (whatever it was) may no longer apply.

I suggest you benchmark the code with a realistic pool of strings to hash, both with and without the tags. If there's no discernable difference in speed, I don't remember any need to keep prog_string_tags.

(Disclaimer: I haven't looked at the code for several years now)
(0002134)
zesstra   
2012-06-07 00:17   
Fix committed in revision cf34204e7f9322d3c9fc5f16628e11c05ac13b3a to master branch (see changeset 854 for details). Thank you for reporting!
(0002325)
zesstra   
2018-01-29 19:59   
Fix committed in revision cf34204e7f9322d3c9fc5f16628e11c05ac13b3a to master branch (see changeset 1532 for details). Thank you for reporting!
(0002376)
zesstra   
2018-01-29 22:57   
Fix committed in revision cf34204e7f9322d3c9fc5f16628e11c05ac13b3a to master branch (see changeset 2862 for details). Thank you for reporting!
(0002427)
zesstra   
2018-01-30 04:59   
Fix committed in revision cf34204e7f9322d3c9fc5f16628e11c05ac13b3a to master branch (see changeset 3945 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
768 [LDMud 3.5] Implementation minor N/A 2011-01-11 21:22 2018-01-30 04:59
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Check Murmurhash3 as general hash function instead of Murmurhash2
Description: Murmurhash3 increases hashing speed - especially on 64 bit platforms - and does not have a weakness of Murmurhash2 which we use currently on the trunk.
http://code.google.com/p/smhasher/
Tags:
Steps To Reproduce:
Additional Information: http://code.google.com/p/smhasher/wiki/MurmurHash
http://sites.google.com/site/murmurhash/
Attached Files:
Notes
(0002131)
zesstra   
2012-06-05 21:00   
Note: Murmurhash is public domain. From the projects homepage:
"All MurmurHash versions are public domain software, and the author disclaims all copyright to their code."
https://code.google.com/p/smhasher/
(0002132)
zesstra   
2012-06-06 22:55   
Fix committed in revision 822084d42b40554e45f64037ba245fa3241c10b5 to master branch (see changeset 851 for details). Thank you for reporting!
(0002327)
zesstra   
2018-01-29 19:59   
Fix committed in revision 822084d42b40554e45f64037ba245fa3241c10b5 to master branch (see changeset 1535 for details). Thank you for reporting!
(0002378)
zesstra   
2018-01-29 22:57   
Fix committed in revision 822084d42b40554e45f64037ba245fa3241c10b5 to master branch (see changeset 2865 for details). Thank you for reporting!
(0002429)
zesstra   
2018-01-30 04:59   
Fix committed in revision 822084d42b40554e45f64037ba245fa3241c10b5 to master branch (see changeset 3948 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
763 [LDMud 3.5] Runtime feature N/A 2010-11-11 17:37 2018-01-30 04:59
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: Introduce pragma to downgrade RTTC errors to warnings
Description: Xtian on ldmud-talk expressed the wish to convert the errors raised during RTT checks into warnings to ease the conversion/transition process.
While I don't like to downgrade the errors to warnings in general, an additional pragma would be OK.
Tags:
Steps To Reproduce:
Additional Information: http://mail63.csoft.net/pipermail/ldmud-talk/2010-November/000212.html
http://mail63.csoft.net/pipermail/ldmud-talk/2010-November/000214.html

Hello World,

On 11.11.10 11:51, xtian wrote:
> > When you enable run time type checks (these are rather new in the 3.5
> > branch) the driver throws fully-fledged errors when it encounters an
> > invalid type.
There are three reasons this being errors instead of warnings:
If you use type checks (strong_/strict_types, the compile-time equivalent of
rtt_checks), the compiler will regard incompatible types as errors. My opinion
is, that it should also be an error at runtime for consistency reasons - it is
still a programming error. (I know LPC was basically type-less - that is not
the point here because the programmer explicitly requested typechecks.)
Second reason is that if a programmer requests a specific type and enables the
RTTC, she relies on receiving only compatible types and usually does not
bother with own typechecks. If that assumption is not true, the programmers
code will probably fail at some point. Therefore I have to keep my own checks
if there are only warning upon incompatible types.
Third reason is my experience, that very few people take warnings serious and
the vast majority just ignores them.
That being the rationale for throwing errors - but please stay with me until
the end of this mail.

> > Now we (avalon) tried that out on a few corelib files and always hat to
> > revert rather quickly because - well we were flooded with errors and
> > players just couldn't continue playing normally. So for us, at the moment,
> > throwing errors does hinder adaption of this new feature. And I was rather
> > looking forward to using the checks generously.
We had similar experience when enabling strong_types+save_types in the corelib
- it took me several months of testing and fixing in my homemud until I could
enable them for good in MorgenGrauen. In case of the RTTC I enabled them in my
homemud and used a kind lib tester (It loads every known object, clones them
if suitable and moves some testplayers into every room, looking at all the
details in them... Not bulletproof, but very handy nonetheless). After that we
could enable them for real - there were errors, but not too many to handle them.

> > Enabling RTTC in an testing environment will never catch all the problems,
> > so players will always stumble over such an error - and for them something
> > will thus not work.
Yes. There is nothing better for testing than real players.
I think, it is acceptable for players to encounter the one or other bug, if
they are dealt with quickly and it does not happen too often. We therefore
accept a certain amount of false-negatives. (I accept that you might have
other demands in your mud, just wanted to add my point of view.)

> > In short, throwing errors (for a language change or enhancement) is not
> > suitable for a productive environment.
No mud (I know of) is a pure 'productive environment'. There is always more or
less development in the live mud and there are always errors in presence of
players.

> > I would much rather have the RTTC throw warnings. (the mudlib can always
> > convert them to errors if it likes). This gives the wizards all the time
> > they need to correct code while not interrupting normal gameply.
For mainly the first two reasons given above I would definitely not like to
raise only warnings during the RTTC. But I see your wish for a smoother
transition if you are confident that warnings are sufficient in your mud.
But instead of an optional pragma which optionally upgrades warnings to errors
I suggest an optional pragma which reduces the errors to warnings.
You then may still apply domain-specific combinations of rtt_checks and
rttc_onlywarn in the autoinclude hook and remove the downgrading pragma once
you feel confident (hopefully soon ;-) ).

Side note: I feel not too good about using sloppy/pedantic for this purpose,
because it enables errors I might not really want to have if I only want to
have consistent type checks and rely on compatible argument/return types. Or
to put it differently: for having a usable enforcement of types I should not
have to buy a whole different class of errors as well.
The warnings pedantic changes to errors are really a lot _less_ serious than
invalid types when the programmer wants to have only compatible types.

Bye,
Zesstra@MG
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0002084)
zesstra   
2011-11-22 11:09   
I am afraid, I won't find time for this too soon. So if anybody else wants to work on it, please feel free.
Note: It is not as simple as it looks (set a flag, call warnf instead of errorf), because the stuff manipulates the stack to get to the needed information and that can't be done in case of warnings. It therefore requires some more changes.
(0002295)
zesstra   
2018-01-28 22:31   
Fix committed in revision a3089ceb747b8b996cb5222549c9424369211f92 to master branch (see changeset 1144 for details). Thank you for reporting!
(0002302)
Gnomi   
2018-01-29 19:59   
Fix committed in revision a3089ceb747b8b996cb5222549c9424369211f92 to master branch (see changeset 1208 for details). Thank you for reporting!
(0002348)
Gnomi   
2018-01-29 20:34   
Fix committed in revision a3089ceb747b8b996cb5222549c9424369211f92 to master branch (see changeset 2410 for details). Thank you for reporting!
(0002353)
Gnomi   
2018-01-29 22:57   
Fix committed in revision a3089ceb747b8b996cb5222549c9424369211f92 to master branch (see changeset 2531 for details). Thank you for reporting!
(0002404)
Gnomi   
2018-01-30 04:59   
Fix committed in revision a3089ceb747b8b996cb5222549c9424369211f92 to master branch (see changeset 2412 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
737 [LDMud 3.3] Networking minor random 2010-03-16 16:34 2018-01-30 04:59
Reporter: zesstra Platform: i686  
Assigned To: zesstra OS: GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: Disconnects of TLS connections with SSL_ERROR_WANT_READ.
Description: Few players here have sporadic TLS disconnects when much data is transfered, but one player also claims it happens with specific (but unknown) text. The debug log states:
TLS: Received corrupted data (2). Closing the connection.
2 is here SSL_ERROR_WANT_READ, which is IMHO the equivalent to EGAIN.

This error message originates in pkg-openssl:tls_read() and is called by get_message(). In case of SSL_ERROR_WANT_READ/SSL_ERROR_WANT_WRITE is retries to read up to 6 times and then calls tls_deinit_connection().

Gnomi commented: Is it necessary to close the connection in that case?
I also tend to change this to just wait until the next cycle to read again. But then we would have to change get_message() (and un-encrypted connections) as well, because they also disconnect upon any error in read()/tls_read(), including EAGAIN.

I think, usually this should not happen in the first place, because we do a select() before and read only sockets for which data should be available... But in rare cases select() does not seem to be sufficient for TLS connections to guarantee that...
Tags:
Steps To Reproduce:
Additional Information:
System Description MorgenGrauen server
Debian Etch.
Attached Files:
Notes
(0001807)
zesstra   
2010-03-16 16:53   
Some more digging into our debug log shows, that some of the disconnects are with errors SSL_ERROR_SSL and SSL_ERROR_SYSCALL as well. These look weird and may well be not our responsibility. But we should try do create better error messages than just issue to plain numbers by using ERR_error_string() and maybe process the error queue.
(0001808)
Gnomi   
2010-03-16 17:04   
There is a difference between encrypted and unencrypted sessions regarding EAGAIN. While on unencrypted sockets select() should guarantee that there is at least one byte to read, this is not necessarily true for encrypted sockets, because the SSL layer may consume some bytes itself. That's why I think it should be legitimate for tls_read() to try again on an EAGAIN later (and not terminate the socket).
(0001809)
zesstra   
2010-03-16 17:18   
And additionally it might also be that upon read the SSL engine first has to write something and vice versa because the might be a handshake going on. Did some search in the net this evening and the SSL people seem to recommend just to repeat the operation some time later (they say one should use select()). So this seems to be the right thing to do. We could either set errno to EAGAIN and change get_message() to not disconnect in that case or return 0 as pretend a sucessful read of 0 bytes.

Oh, BTW: There seems to be an error: tls_read() returns ret. In case of errors it is <0, but ret = SSL_get_error(ip->tls_session, ret); changes it to positive numbers. And these are returned to get_message() which regards the tls_read() then successfull... And because a positive return value of tls_read() is regarded as the number of bytes read, this changes (falsely) the ip->text_end pointer (and the statistics). IMHO garbage will then be processed as player input, between 1 and 8 bytes.
(0001810)
zesstra   
2010-03-17 17:55   
Mhmm, we might have been wrong:

>When an SSL_read() operation has to be repeated because of SSL_ERROR_WANT_READ
>or SSL_ERROR_WANT_WRITE, it must be repeated with the same arguments.
I think, we can't guarantee that if we we defer back to get_message() or comm_send_buf() to try later again. The buffer addresses will be still the same, but the sizes to read/write maybe not... In this case, we may have no choice but to disconnect if we don't want to rewrite larger parts of the comm code?
(0001940)
zesstra   
2011-01-05 21:54   
Ok, some more research... SSL_write() needs to be called with the exact arguments, because it may already have committed a part of the buffer to the network even if it returns -1. Therefore one has to retry with the exact same arguments until SSL_write() returns > 0. The long explanation can be found in this thread:
http://readlist.com/lists/openssl.org/openssl-users/0/1726.html

If we can't send the data immediately we copy it into a queue of buffers, so the buffer address changes. However, we can make OpenSSL to accept a different buffer for the next call as long as the _content_ of the buffer is the same by setting SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER in the SSL context.

Additionally, we need to do a similar thing for pkg-gnutls.c as well. However in that case, we have to to call gnutls_record_send() and gnutls_record_recv() with either exactly the same parameters (impractical in our case, see above) or with NULL until the interrupted operation succeeds (NULL causes these functions to resume the last call). We might use a static var in the functions to record the success state of the last call.

In both cases, we have to ensure that we try to resend the very same content during retries. This should be the case because the buffers in the queue are not changed.
(0001996)
zesstra   
2011-02-19 16:07   
Addition to 0000737:0001940:
GnuTLS stores the content in an internal buffer in case of GNUTLS_E_INTERRUPTED or GNUTLS_E_AGAIN. If gnutls_record_send() is called and there is content in this buffer, it will send the content of this internal buffer instead the content of <buffer>. According to the documentation we should call again with NULL as buffer in this case, but GnuTLS does not care and we will anyway try to send the same content. It is way easier for us to not call with NULL, we just have to ensure to try to re-send the same content.

The only problem this has: GnuTLS might change since we are relying on non-documented, implementation defined behaviour. :-(

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
701 [LDMud 3.5] Efuns minor have not tried 2009-11-04 04:39 2018-01-30 04:59
Reporter: Gnomi Platform: i686  
Assigned To: zesstra OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: sizeof(mapping) is expensive
Description: When a mapping is given to sizeof() all its keys get checked for references to destructed objects. This is needed to give an exact answer but it makes sizeof() O(n) instead of O(1), which is quite unexpected.

So it would be nice to optimize that. Suggestions:
a) Have a flag that indicates whether this mapping has any keys referencing objects (objects, closures).
b) Have some kind of a time stamp of the last check. The global time stamp must then be incremented on each destructed object.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0001599)
zesstra   
2009-11-04 06:00   
Ugly thought: If we add a signed integer to mappings as timestamp, we may combine them both by using the sign bit to indicate keys referencing objects.

I just saw, that C99 changed time_t and only states that time_t must a numerical type, so that one would not work in this case. (I guess, we may see quite a lot of bugs in all sorts of programs soon. *g*)
(0001600)
Gnomi   
2009-11-04 06:10   
I didn't mean some time() like time stamp, but more something like a counter that is incremented on each object destruction (because otherwise it's hard to distinguish when destruction and mapping check happened in the same second).
(0001601)
zesstra   
2009-11-04 07:20   
Yes, right, time_t was a first reaction upon time stamp. ;-)
Something like p_int is anyway more suitable (although I think, a int32_t would be completely sufficient, we don't need 8 bytes on x86_64). Then we could just set it to -1 in mappings without keys referencing objects and the counter otherwise...

BTW: Maybe we should add a note about the O(n) in the manpage?
(0001724)
zesstra   
2010-02-13 17:08   
I will have a look into this and implement Gnomis suggestion first.

I am not sure if we should use the part of my suggestion to track if a mapping references objects by using a bit from the counter (e.g. negative value in the mapping -> no objects referenced). This would save some more time, but then we have to check the destructed-object-counter for overflow each time we increment it. And we have to keep the marker in the mapping uptodate all the time (all places which enter or delete values). Do you think it is worth it?

On the other hand: this optimization would probably be done in check_map_for_destr(), which means we save time not only in sizeof(), but a lot places more: copy(), deep_copy(), +, -, [], resize_mapping(), compact_mapping(), m_indices(), m_values(), walk_mapping(), filter_mapping(), m_reallocate(), unmkmapping(), save_mapping().
(0001725)
zesstra   
2010-02-13 19:29   
For a 'this mapping references objects' marker in general we have to take object the values into account as well, not only keys.
In addition to checking all keys upon addition (which is IMHO not to complicated), we have to check all assignments to mapping values. I am reluctant to do that. Besides the work it seems very easy to miss one place and that would probably introduce nasty crashes, because suddenly we have destructed objects somewhere in mappings.
(0001726)
Gnomi   
2010-02-14 07:10   
I think the functionality of check_map_for_destr should be splitted. In most cases we only need to check the keys. I think only cleanup_vector() needs also to check the values. So it may be better two have one fast function for the keys and the slow function for the cleanup routines.
(0001729)
zesstra   
2010-02-14 17:37   
Good idea.
I committed a series of experimental patches in r2861-r2864:
1)
introduce the 'timestamp' Gnomi suggested (BTW: Because currently the overhead is 4 Bytes per Mapping, we might think about using a uint16_t instead of uint32_t, if we are confident that the risk of destroying exactly 65536 objects between two calls to check_map_for_destr_keys() for a specific mapping is low enough. But I am unsure about this.)
2)
split check_map_for_destr() into check_map_for_destr_keys() and check_map_for_destr_values() with the timestampf from 1) being in check_map_for_destr_keys().
3)
changed some check_map_for_destr() to check_map_for_destr_keys() which are IMHO riskless, including in sizeof().

I still have to check other users of check_map_for_destr() in more detail later.

BTW: If you like to comment on the changes in a specific commit or specific file in a commit: You might do so at http://github.com/zesstra/ldmud-mirror/commits/master as I today found out... Quite fascinating.
(0001891)
zesstra   
2010-07-22 04:04   
I don't like to introduce this changes in 3.3.x, so I am moving all this to 3.5.x only if nobody objects. Then I will only attach a note about the O(n) behaviour in then sizeof() manpage in 3.3.x.
(0002085)
zesstra   
2011-11-22 23:28   
I believe, this is done for now.
I hope, I did not introduce new bugs in the process... ;-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
641 [LDMud 3.5] Implementation minor always 2009-05-26 05:03 2018-01-30 04:59
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: save_object() should never write NaN or INF into savefiles.
Description: If a float is actually too large to be represented and it is saved in save_object()/save_value(), a restore with restore_object()/restore_value() will fail (not only for the float, but for the complete savefile). A similar issue is "NaN".
restore_svalue() expects numbers to start with [0-9,-], but sprintf("%.12e") with my libc will print infinity as 'inf' (and NaN probably as 'nan'/'NaN').
C99 specifies that sprintf uses "[-]inf" or "[-]infinity" for infinity and a string starting with "nan" for NaN when printing floating point numbers.

One idea is, to define a new savefile format:
a) with a special first character as a tag for floats. The downside is, that the savefiles gets a little bit bigger and as less readable for humans.
b) never write the native float representation ("%.12e") into the savefile, only use separate mantissa+exponent. The downside is, the savefiles get even less readable for humans as well. Additionally I am not completely sure, what implications this has for portability. Right now we have only on floating point implementation, but maybe that changes in the future and creating yet another savefile format then is not something I look forward to...
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0001163)
fufu   
2009-05-26 12:03   
Thanks for separating this issue out from 0000627.

I was wondering how NaNs and infs would end up in the save file in the first place, ignoring 0000627 -- the driver seems to be careful to not create such values and turns them into errors instead.
(0001167)
zesstra   
2009-05-27 05:32   
Mhmm. Very good point. And preventing overflows/underflows in LPC is a good idea. I guess you are right, we might just define any case of a float being inf or NaN a bug somewhere else.
The only downside of that is, that savefiles may be written, which can't be restored. We could check that in save_svalue() and raise an error in that case to prevent writing illegal savefiles...
(0001567)
zesstra   
2009-10-28 06:15   
I think, I concur with Fuchur, that 'infinity' and 'NaN' should not be in savefiles in the first place, if they are, there is a problem somewhere else.
So I suggest to close this. Any more opinions?

(0001573)
Bardioc   
2009-10-30 04:00   
I think its a good idea to not serialize the values for NaN and Infinity as they are somewhat special. so is NaN always != NaN ... I wonder how this is handled after restoring the objects value.

From my opinion, making it an error is correct, as it obviously is one. I cannot think of somebody really taking advantage of saving NaN or Inf.
(0001574)
zesstra   
2009-10-30 05:11   
> I wonder how this is handled after restoring the objects value.
Well, it is not handled, because we can't restore savefiles with such values. ;-) You just get an error about the savefile having an illegal format (or such).

As Fuchur writes, the driver usually does not create those values in the first place (0000627 was special because due to architecture issues a float was mis-interpreted during save_svalue()). But currently, we don't have an active check in save_svalue() for these.
(0001799)
zesstra   
2010-03-14 17:43   
Do we need such a check (for NaN, infinity) in save_svalue() at the time we write the savefile?
(0002036)
Coogan   
2011-02-24 01:46   
I say: Yes, we need such a check, and the try to save Inf or NaN values should result in an error.

In a mud, I can't imagine a use case where it is needed to write Inf or NaN into a savefile. I even think that a mudlib's need to store such a value in a savefile does more seem to be a design error.
(0002175)
zesstra   
2012-12-09 02:59   
(Last edited: 2012-12-09 02:59)
I agree concerning the need of these values Coogan, but the argument is: there should be no situation the driver writes NaN or infinity into an svalue. Therefore no check in save_svalue() is necessary. If the driver creates such an svalue, that itself is an error that has to be fixed.
The only argument is: we want the check because we are paranoid. ;-)

(0002230)
zesstra   
2014-02-23 23:05   
I will add an assert in save_svalue() checking that the double written are finite. That will prevent invalid savefiles even if the driver has an error somewhere else. That should make all of us paranoid people happy. ;-)
(0002231)
ldmud-bugs   
2014-02-23 23:15   
Fix committed in revision e8ad384d5c9f26f2675ff7bd2c1fee66772a201f to master branch (see changeset 937 for details). Thank you for reporting!
(0002314)
zesstra   
2018-01-29 19:59   
Fix committed in revision e8ad384d5c9f26f2675ff7bd2c1fee66772a201f to master branch (see changeset 1437 for details). Thank you for reporting!
(0002365)
zesstra   
2018-01-29 22:57   
Fix committed in revision e8ad384d5c9f26f2675ff7bd2c1fee66772a201f to master branch (see changeset 2765 for details). Thank you for reporting!
(0002416)
zesstra   
2018-01-30 04:59   
Fix committed in revision e8ad384d5c9f26f2675ff7bd2c1fee66772a201f to master branch (see changeset 3850 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
565 [LDMud 3.5] Implementation minor N/A 2008-09-09 09:25 2018-01-30 04:59
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: low OS Version: 10.5.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Hash in store_prog_string() assumes 32 bit pointers
Description: The hash calculation in store_prog_string() and delete_prog_string() assumes pointers which fit into 32 bits. On LP64 platforms the distribution of the hashes will be impaired once strings are stored above 4GB (which is always the case on MacOS X, because the process address space contains a zero-page from 0 to 4GB).
Although it only reduces effiency in compilation, the hash calculation should be changed.
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0000785)
zesstra   
2008-09-16 16:48   
(Last edited: 2012-06-07 17:57)
The hash calculation in ptrtable.c as well:
    /* TODO: This code assumes that a pointer is 32 Bits long */
    hash = key ^ key >> 16;
    hash ^= hash >> 8;
    hash &= (PTABLE_SIZE-1);
    mask = 1 << (hash & (CHAR_BIT-1));
    /* TODO: this statement assumes CHAR_BIT == 8 */
    usage_p = ptable->hash_usage + (hash >> 2 & 0000001:0000001);

(The assumption that CHAR_BIT is always 8 is also done in bytecode.h, right now the driver does anyway not work on platforms where CHAR_BIT != 8.)

Edit: this issue was separated into 0000804


View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
427 [LDMud 3.5] Networking minor always 2005-12-16 12:26 2018-01-30 04:59
Reporter: lynx Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: wrong use of EMFILE for MAX_OUTCONN
Description: probably comes from junky's original code. there is no distinguish
the temporary overflow of the outgoing connections queue from the
real case of an exhaustion of descriptors. in the first case it
would be ok to simply resubmit the net_connect request 2 seconds
later, in the latter case it is correct to either queue the operation
for better times, or bail out. so we need a different return code here
that helps us distinguish these two error states. too bad posix doesn't
have any to borrow us i'm afraid. can you make one up, please? :-)

the code in question is in comm.c and looks like this:

        if (!stored)
        {
            rc = EMFILE;
            break;
        }

as you see it manually creates an EMFILE error although it isn't
a real case of EMFILE. this was okay in the days when we only had
an irc robot and occasional gopher requests going out of the mud.
yeah, talking about 1992. but today we have jabber, psyc, http and
irc connections going in all directions..

an other possible solution would be to allocate the queue dynamically,
but do we really need to do so much work? having an extra error code
is the simpler & immediate solution.
Tags:
Steps To Reproduce:
Additional Information: also, MAX_OUTCONN should really be configurable in the settings
file because for our needs 5 is way below mental sanity. just think
of a user logging into psyced with plenty of psyc and jabber friends
everywhere. one user alone may need a queue of dozens.

and thanks for making ldmud rock :)
Attached Files:
Notes
(0000823)
zesstra   
2008-12-15 12:45   
What about using ENOBUFS instead? It seems to me a similar cause (though in the kernel) and most probably a transient error as well.
BTW: Does anyone know, if there is any value range, which can never be used in errno?
(0001129)
lynx   
2009-05-22 03:48   
Since we no longer have MAX_OUTCONN limited to 5, this problem usually doesn't appear.. but still the code is there to handle EMFILE the "wrong" way.

I'd rather use a value unlikely to ever appear in errno, like -37337 ;)
But since I've never encountered a ENOBUFS it may as well be ENOBUFS.
Both solutions are fine with me.
(0001135)
zesstra   
2009-05-22 05:41   
The problem is, that the implementation of errno is not specified. (It may not even be a real variable.) The standard defines only 3 (symbolic) values, all other may be implementation-defined. It is very difficult to find one, which is guaranteed not to be used by someone else. Even if we assume, that all 'official' values are positive and use negatives ourself, this may go awfully wrong, if errno is implemented as 'unsigned'.
One possibility would be to abandon the idea of returning errno at all and define all error values ourselves, independent of errno.
(0001136)
lynx   
2009-05-22 05:48   
If our errno is signed and it only assigns some meaning to -37337, then it is quite unlikely that official values of errno will ever get there. But if you don't like that, take ENOBUFS please. Let's be pragmatic, we don't need an error code revolution here. In fact, if my OS introduces some new errnos, I prefer having them relayed into my LPC. For a while I even used to have an errno() efun, in order to be able to provide more precise error messages after file read/write ops etc. That was useful!
(0001139)
zesstra   
2009-05-22 06:37   
It is not so easy. Suppose, we choose
#define ENOSOCKET x
and return that in case we can't store the connection attempt.
Now the OS (future version) invents
#define ESOMESOCKETERROR x
Now you can't distinguish between these two error conditions any more.

On the second thought: returning errno, without supplying the OS version of errno.h and/or provide access to strerror() is completely nonsense. Why? Because the actual numbers are implementation defined. Example: EPROTONOSUPPORT on my system is 43. On MorgenGrauen it is 93.
If we want to follow this route, we have to create a /sys/errno.h on-the-fly upon driver startup. Which is not so easy, because the actual definition of the numbers may be in /usr/include/errno.h, /usr/include/sys/errno.h, /usr/include/asm-generic/errno-base.h, /usr/include/asm-generic/errno.h and probably other locations as well...
(0001145)
lynx   
2009-05-22 07:39   
I left it to the admin to create an errno.h for his system, if he likes to use the errno() efun.
(0001155)
Gnomi   
2009-05-25 17:09   
I don't think that LPC should return an errno code, otherwise we will have to start allowing system includes. That's too low-level for LPC in my opinion, there should be a level of abstraction from the system functions. So we should either implement our own error codes (just like file_size() does), or throw textual representation (strerror(errno)) as a runtime error.
(0002177)
zesstra   
2012-12-09 15:24   
I agree. And I think, changing the meaning of the return values (and/or adding of additional RTEs) is better done in 3.5.x, so I will move this issue.
(0002207)
zesstra   
2013-08-21 00:02   
You probably won't believe it, but: I pushed some changes into master, which should solve this problem. net_connect() now uses our own symbolic return values defined in comm.h and should enable to distinguish between some transient and non-transient errors.
(0002318)
zesstra   
2018-01-29 19:59   
Fix committed in revision ba9f4da6a3be62c9268f1a505436fc9e6d358236 to master branch (see changeset 1488 for details). Thank you for reporting!
(0002369)
zesstra   
2018-01-29 22:57   
Fix committed in revision ba9f4da6a3be62c9268f1a505436fc9e6d358236 to master branch (see changeset 2817 for details). Thank you for reporting!
(0002420)
zesstra   
2018-01-30 04:59   
Fix committed in revision ba9f4da6a3be62c9268f1a505436fc9e6d358236 to master branch (see changeset 3901 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
233 [LDMud 3.5] Implementation feature N/A 2004-11-26 23:39 2018-01-30 04:59
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.8 and before  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: Programs, Blueprints, Virtual Inheritance
Description: Short: Separate Programs from Blueprints
Date: Thu, 2 Nov 2000 10:12:23 +0100 (MET)
From: Fini Jastrow <mud@hurrikap.rz.uni-leipzig.de>

--- A way to prevent this scenario would be to keep a list of all programs.
But that would mean that blueprints and programs are no longer identical.

Hallo Mateese!

Nein, ich bin noch nichtmal dazu gekommen auch nur in den Regexp-Code zu
schauen.

Zum Thema: Wenn eine nomask Funktion mehrfach virtuell ererbt wird, wirft
das ja (seit neuem) keinen Fehler mehr. Das klappt auch ganz wunderbar.
Ein Problem entsteht nur, wenn die Vererbung nicht ganz direkt ist, und
diese nomask Funktion 'in der Zwischenzeit' neu geladen wurde - also im
Driver auf eine andere Funktion zeigt, obwohl der 'vollspezifizierte' Name
derselbe ist.

Beispiel:

'Normalzustand' 'Fehlerzustand'

       A A
      / \ / \
     / \ / \
    B C B C
     \ / | |
      \ / | |
       D D1 D2


Den Fehlerzustand kann man zB erreichen durch: C laden (laed D implizit),
D zerstoeren, B laden (laed D implizit). Nun gibt es zwei eigentlich
gleiche Funktionen, die aber verschiedenen Funktionszeiger haben:

in C nomask D::fun() --- aber eigentlich nomask D2:fun()
in B nomask D::fun() --- aber eigentlich nomask D1:fun()


Auf jeden Fall wirft es dann 'ploetzlich' irgenwann im Betrieb einen
Fehler (nomask zweimal inheritet). Ich weiss nicht, ob man das so aendern
kann, dass es trotzdem geht, ansonsten sollte das in der Docu erwaehnt
werden denke ich - und eigentlich ist die Faehigkeit dann mehr oder
weniger sinnlos, weil nicht wirklich sicher benutzbar.


Hmm, was mir gerade einfaellt... ich weiss gar nicht, ob 'virtual'
ueberhaupt in diesem Zustand geht, also ob D1 und D2 nur einen
Variablenraum, haben. Ich werde das gleich mal nachsehen (wenn ich Zeit
finde), wenn du willst schicke ich dir die Ergebnisse, sonst will ich dich
nicht mit einer weiteren Mail stoeren.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000745)
Gnomi   
2008-07-17 08:33   
This is a problem in UNItopia as well.

Currently the variable sets of two virtual inherited programs of the same name are merged to one iff these programs are equal (i.e. have the same address in memory). I'd rather compare their signature (the names and types of all public and protected functions, variables and structs). For this to work virtual inherited functions should be called using the current object's program's inherit list (instead of the current program's inherit list), where the compiler should have prepared a translation between function indices.

On a second thought in most of our virtual inheritances the virtual is mandatory, meaning that something will break if these programs are not merged. So why not always merge them and risk some dangling functions calls?

Anyway this is to experimental for 3.3, so I move it to 3.5.
(0000746)
Sorcerer   
2008-07-17 13:03   
I agree with Gnomi that virtual inherits should always be merged. Virutal inherits probably cause more errors the way they are now.
(0001985)
zesstra   
2011-02-14 17:35   
(Last edited: 2011-02-14 17:36)
You are probably right, although the merge dependent of the signature looks nice. On the other hand it would be at least good to know if a merge was 'risky', because the programs might not have been identical so you could think if reloading the inhertitance tree is needed instead.

(0002218)
Gnomi   
2014-02-11 00:53   
(Last edited: 2014-02-11 01:03)
My plan is the following: Always merge virtual inherited programs that have the same name. If they not only have the same name but are the same program then everything works as it does today. If not then choose the newer program.

The older program is replaced with a trampoline entry in the inherit list. For functions this might be done (hopefully) pretty easily by cross-defining their entries in the function table to the new inherit. For variables there need to be a translation table that maps each variable index of the old inherit to an index in the new inherit.

If a function in the old inherit is missing in the new inherit replace it by an undefined entry (so it gives the error message "Undefined function" when called). This is the most incompatible change of this proposal, but I think this behavior is more tolerable then nomask errors when merging fails. If a variable in the old inherit is missing in the new inherit add it as a regular inherited virtual variable.

Both (function cross-definition and variable index mapping) is done by comparing the name for publicly visible definitions (i.e. declared public or protected). Private functions or variables are ignored as they have no impact on the inheriting program.

The trampoline entry shall not have a counted reference to the old program (the old program itself is not needed anymore, so we would like to free its memory), therefore we remember only the program's id number to recognize it when it's inherited again.

(0002219)
Gnomi   
2014-02-11 09:21   
If a function in the old inherit is missing or has an incompatible signature, or a variable has an incompatible type then the compiler should issue a warning.
(0002297)
zesstra   
2018-01-28 22:31   
Fix committed in revision e380a9b4f62161bfbc45fc8cce027a7bc481a0a4 to master branch (see changeset 1184 for details). Thank you for reporting!
(0002304)
Gnomi   
2018-01-29 19:59   
Fix committed in revision e380a9b4f62161bfbc45fc8cce027a7bc481a0a4 to master branch (see changeset 1248 for details). Thank you for reporting!
(0002355)
Gnomi   
2018-01-29 22:57   
Fix committed in revision e380a9b4f62161bfbc45fc8cce027a7bc481a0a4 to master branch (see changeset 2572 for details). Thank you for reporting!
(0002406)
Gnomi   
2018-01-30 04:59   
Fix committed in revision e380a9b4f62161bfbc45fc8cce027a7bc481a0a4 to master branch (see changeset 2465 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
847 [LDMud 3.5] Networking minor N/A 2016-01-14 13:38 2018-01-30 04:59
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: Prevent the usage of weak ciphers/algorithms in TLS
Description: Weak ciphers like RC4, MD5, 3DES, especially export ciphers and SSLv3 should be rejected by the driver, even if the underlying openssl/gnutls still supports them, because they are too old. Maybe even SHA1 as well.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002269)
zesstra   
2016-01-14 17:22   
Unfortunately, setting priorities on my system (gnutls-3.3.20) causes sporadic segfaults during handshakes in gnutls/nettle/libgmp on my system.
Has to investigated later on.
(0002272)
zesstra   
2016-01-20 17:01   
Fixed in 0000849

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
845 [LDMud 3.5] Networking minor N/A 2016-01-14 13:34 2018-01-30 04:59
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.5.0  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Increase default prime length of DHE to 2048
Description: Using 1024 bits for the Diffie-Hellman Keyexchange should be considered unsafe nowadays. (See: https://weakdh.org/)
We should increase our defaults to 2048. Since it takes a long time to generate the parameters, we will have to ship a default set of parameters.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
596 [LDMud 3.5] Efuns feature N/A 2009-01-15 17:47 2018-01-30 04:59
Reporter: fufu Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: new efuns for configuring objects and the driver
Description: (This is a summary of an email exchange between Gnomi, Zesstra and me. The proposal is not yet complete, and open for discussion.)

The driver has numerous efuns for setting various options on objects and the driver, for example enable_commands(), set_buffer_size() or set_limits(). The idea of this proposal is to replace this increasing number of efuns by a generic interface for configuring objects and the driver:

  void configure_object(object ob, int what, mixed data)
  void configure_interactive(object ob, int what, mixed data)
  void configure_driver(int what, mixed data)

'what' would be an identifier for the setting - I'd suggest OC_*, IC_* or DC_*, for each of the respective respectively.

'ob' would be the object to configure. If we want to support changing the defaults, ob = 0 can be used for that.

Changing some settings will cause a privilege violation. Changing defaults should always cause a privilege violation.

If we find a good use for it, the return value can be changed to int for returning error codes. (Zesstra wants this. Gnomi and I currently don't.)

In addition, there should also be functions for querying the settings:

  mixed object_info(object ob, int what[, int index])
      (the extra argument comes from the existing object_info())
  mixed interactive_info(object ob, int what)
  mixed driver_info(int what[, mixed arg1[, mixed arg2]])
      (the extra arguments come from debug_info())

Candidates for replacement are as follows:

objects:
  enable_commands / disable_commands (set, query)
  set_heart_beat (set, query)
  set_modify_commands (set, query)
  query_actions (query only)
  object_info (reuse OINFO_*, I guess. query only)
  query_shadowing (query only)
  query_once_interactive (query only)

interactives:
  set_prompt (set, query)
  enable_telnet (set, query)
  start_mccp_compress / end_mccp_compress / query_mccp (set, query)
  set_buffer_size (set, query)
  set_combine_charset (set, query)
  set_connection_charset (set, query)
  set_max_commands (set, query)
  query_editing (query only)
  query_idle (query only)
  query_input_pending (query only)
  query_ip_name (query only)
  query_ip_number (query only)
  query_mccp_stats (query only)
  query_snoop (query only)

driver:
  set_driver_hook (reuse H_*, I guess. set, possibly query)
  set_limits / query_limits (reuse LIMIT_*, I guess. set, query)
  set_extra_wizinfo_size (set, query)
  mixed debug_info(int what[, mixed arg1[, mixed arg2]]) (query only)
  query_load_average (query only)
  query_mud_port (query only)
  query_udp_port (query only)

unsure:
  set_light, set_is_wizard if we want to support compat mode
  snoop
  query_command
  query_notify_fail
  query_verb
  set_extra_wizinfo
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000896)
_xtian_   
2009-01-16 05:43   
Even if this is targeted for 3.5, please don't remove the old functions. Mark them as deprecated but leave them. Changing that much mudlib code (and surely all MUDs will be affected) just to make the interface more elegant is ... well I could invest that time into more productive things.
You should also consider making the switch to 3.5 as easy as possible for your users.
Overall, we arent that many implementers any more.
(0000897)
_xtian_   
2009-01-16 05:51   
Also, you are changing object_info() semantically. This means the conversion to the suggested new interface would become non-trivial. Those who remember the switching over from filter_array() to filter() a few years back know how much work that is over our huge mudlibs. And this change was simpler.

(It's not intellectually complicated - it just means many hours of grepping/editing and testing).
(0000898)
Gnomi   
2009-01-16 05:52   
Would it be okay, if the old efuns were removed and we published reference implementations as simul_efuns to replace them?
(0000899)
zesstra   
2009-01-16 06:07   
Just to add, why I like having <int> as return type:
Using runtime errors to signal all kinds of errors limits the possibility for handling errors in the mudlib very drastically.
e.g. if setting the buffer length fails, because the host system doesn't support that buffer size at the moment it is IMHO bad to throw a runtime error. In that case signaling the error by return code enables to mudlib to fall back to a different size.
Of course it depends on the type of error. Using wrong types of arguments should certainly cause a runtime error. ;-)
(0000900)
Gnomi   
2009-01-16 06:07   
What do you mean with object_info? In the proposal it has the same signature as it has now to keep the old interface working.
(0000902)
Sorcerer   
2009-01-16 08:06   
First of all: I like the idea and I also support Zesstras move for returning error codes. As stated by himself above this will allow a more subtle handling of errors.
For most of the efuns I agree that providing them as simul_efuns should be sufficient. But at least those that are heavily used by wizards not directly involved in the base-lib of a MUD (e.g. query_idle(), query_editing(), query_once_interactive(), perhaps enable_/disable_commands()) should be provided as (deprecated) "real" efuns in 3.5.
So if a MUD wants to migrate they can do it in two steps: first, die base-lib maintainers update the base-lib (and get rid of the then dispensable simul_efuns), but the mayority of the code (domains, guilds etc.) will keep running using those "real" efuns and can be changed over time - as _xtian_ pointed out the number of implementers is not that high any more...
(0000903)
_xtian_   
2009-01-16 10:51   
Simply put: Anything where I can upgrade and don't need to change the mudlib is the better choice for me (representatively speaking).
I can understand the motivation completely - the urge to provide cleaner interfaces. But the timecost-benefit ratio doesn't have any merit here on the ldmud-user side.
If a 3.3-compatability-mode is good for you it is good for me.

Gnomi: I must have mis-read the signature of object_info() this morning. Please ignore that last comment.
(0000904)
Gnomi   
2009-01-16 11:43   
I think returning error codes does only make sense for errors that you can't prevent and do happen quite regularly.

Errors you can prevent are programming errors (e.g. giving a false type as a parameter, using unknown <what>s) and they should be thrown (how can you do error handling correctly if you can't call the function properly?). For errors that aren't expected to come up regularly you often are tempted to ignore these codes and that's worse then throwing an error. (Error handling has its cost, instead of one code line you have a lot more of them.)

file_size is a nice example for reasonable error codes. But e.g. out of memory exceptions should always be thrown because they're so rare that handling them explicitly is to expensive.
(0000917)
Bardioc   
2009-01-17 10:58   
I must say I like this very much as it really cleans the interface and as this only reflects certain driver functions or more internal lib dependend functions, it should not be too diffcult to change.

So 2 cents from me for this ;-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
722 [LDMud 3.5] Efuns minor always 2010-02-10 15:16 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: ed: 's' without any arguments will substitute with trash
Description: In ed() doing 's/a/bb/g' first and then (on another line) entering just 's' will replace "a" with "/bb/g".
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0001714)
Gnomi   
2010-02-10 15:19   
Fix for 3.5 committed as r2846.
Fix for 3.3 after review.
(0001955)
Gnomi   
2011-01-25 15:50   
Committed as r2846 for 3.3 as well.
(0001963)
Gnomi   
2011-01-26 00:17   
Fix committed in revision 5f44b1313f3d84192eb7f952731f0f33d08cd421 to master-3.3 branch (see changeset 757 for details). Thank you for reporting!
(0002343)
Gnomi   
2018-01-29 19:59   
Fix committed in revision 5f44b1313f3d84192eb7f952731f0f33d08cd421 to master-3.3 branch (see changeset 2243 for details). Thank you for reporting!
(0002394)
Gnomi   
2018-01-29 22:57   
Fix committed in revision 5f44b1313f3d84192eb7f952731f0f33d08cd421 to master-3.3 branch (see changeset 3588 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
711 [LDMud] LPC Compiler/Preprocessor minor always 2010-01-16 07:18 2018-01-29 22:57
Reporter: _xtian_ Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: 3.5.0 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: inline closures: context variables maybe overriding other var-types
Description: I encountered the following strange behaviour:


struct a {
  int blubb;
};

closure test()
{
  return function void(string s)
                   : float val; // context variable
                  {
                    struct a test= (<a>);

                    test->(s)= 9; // this will yield a compilation error
                  };
}

The interpreter yields the compile error:

line 13 before ' 9;': Illegal type for struct member name: "float"

It thinks the 's' in "text->(s)" is a float. This error goes away if I change the type of 'val' (!) from float to mixed.

My best guess is that the context variable messes up the type of the parameter variable.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001686)
Gnomi   
2010-01-18 17:22   
I can confirm it and will have a look into it.
(0001711)
Gnomi   
2010-02-08 08:28   
Committed a fix for 3.5 as r2844. I will commit it for 3.3 after review/testing.
(0001956)
Gnomi   
2011-01-25 15:59   
Committed as r2973 for 3.3 as well.
(0001962)
Gnomi   
2011-01-26 00:17   
Fix committed in revision 6397631cca0dc05ab17a944e2036cbd5b6e801b6 to master-3.3 branch (see changeset 756 for details). Thank you for reporting!
(0002342)
Gnomi   
2018-01-29 19:59   
Fix committed in revision 6397631cca0dc05ab17a944e2036cbd5b6e801b6 to master-3.3 branch (see changeset 2242 for details). Thank you for reporting!
(0002393)
Gnomi   
2018-01-29 22:57   
Fix committed in revision 6397631cca0dc05ab17a944e2036cbd5b6e801b6 to master-3.3 branch (see changeset 3586 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
627 [LDMud 3.3] Portability block always 2009-04-17 08:15 2018-01-29 22:57
Reporter: wedsall Platform: x86_64  
Assigned To: zesstra OS:  
Priority: urgent OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Floating point numbers on 64bit platforms may be saved incorrectly
Description: Hello!
 Just wanted to report this, I'm not sure if its a bug or not.

I just moved from 32 to 64 bit.

Our players have an attacks_pending floating integer in their save files.

An example of:
 attacks_pending 3.499965555966e-01=ffff:59995fd0

Gets turned into the following after logging in then logging back out (saving):
 attacks_pending inf=ffff:7ffffff8

And this format is non-restorable.
 Error: Illegal format (value string) when restoring bin/player/_finger from
blab/bla/bla.o line 26..

Tags:
Steps To Reproduce:
Additional Information:
Attached Files: 0001-Fix-for-float-corruption-in-restore_svalue.patch (1,927 bytes) 2009-04-17 18:11
http://ldmud.eu/file_download.php?file_id=221&type=bug
0002-Changed-Defines-for-FLOAT_FORMAT_0-to-functions.patch (2,112 bytes) 2009-04-19 14:04
http://ldmud.eu/file_download.php?file_id=222&type=bug
0003-Use-LOAD_-macros-in-F_FLOAT.patch (2,101 bytes) 2009-04-19 14:04
http://ldmud.eu/file_download.php?file_id=223&type=bug
0005-Changed-restore_svalue-to-recognize-inf-and-nan.patch (2,343 bytes) 2009-05-07 03:38
http://ldmud.eu/file_download.php?file_id=231&type=bug
Notes
(0001051)
zesstra   
2009-04-17 08:43   
I will have a look this evening. Given the nature of the floating number implementation in the driver, this sounds possible.
(0001052)
zesstra   
2009-04-17 15:37   
Ok, I can confirm this issue with this number on my machine. The floating point number 3.499965555966e-01 seems to be regarded as 'infinity' when converted into our floating point format and back again:
Floatvar before restore: 0.349997
Floatvar after restore: inf.0
If that value is written to the savefile, it can't be restored. This is because 'numbers' (including floats) in restore_svalue() have to begin with a digit or -. The string 'inf=ffff:7ffffff8' the doesn't match any case in the switch and if regarded as illegal.

One issue here is: restore_object() should be able to restore 'infinity', if save_object() can write that.
The other, why 3.499965555966e-01 is mis-interpreted in the first place.

Currently we split a floating point number into mantissa and exponent, the mantissa being a p_int and the exponent a ph_int. On 32 bit platforms that is a 32bit value and a 16bit value. On 64 bit systems these are 64bit and 32bit wide.
save_svalue() stores only the lower 16 bits of the exponent (0xFFFF). The exponent for the number given above is -1 (0xFFFFFFFF), which is truncated to 0xFFFF in save_svalue(). Upon restore, the exponent is 65535 (0xFFFF) and so the resulting floating point number is 'infinity'.

Big warning: Until we solve this bug, assume the driver will scramble all floating point numbers with negative exponents! Don't use on production systems!
(0001053)
zesstra   
2009-04-17 16:24   
Ok, so several things...

1) I think, we need a test case for this (negative exponents). Any other suggestions, which the testcase should include?

2) Solution:
The quickest would be to correct save_svalue(). As Quick-Fix ok, but I think, this is an incomplete solution, because we don't know if other places make assumptions about the size of exponent and mantissa and because on LP64 systems, the FPN are suddenly 96 bit, not 48 without any benefit.
The most portable thing would be to use fixed-width integer like uint32_t and uint16_t for mantissa and exponent. (Which we can only do this if we check all users of floats in the code and are sure, that changes in svalue_s are acceptable.)
In addition, we might want to take 0000496 into account, if we anyway change the svalue type and add a further optional floating point format, using basically double and split only in save_svalue().
(0001055)
zesstra   
2009-04-17 18:27   
I added a quick fix for the immediate issue, which fixes restore_svalue() to interpret the value for the exponent as 16bit wide integer (int16_t). Additionally, the mantissa is also explicitly read as 32bit wide integer (int32_t) and also save_svalue() explicitly writes int16_t and int32_t.

This solves the first part of the problem (data corruption). The second part (the unability to restore 'infinity') is not solved, but the data corruption is anyway the more severe.
(0001056)
wedsall   
2009-04-17 19:56   
thanks once again for the quick response Zesstra.
(0001058)
zesstra   
2009-04-19 14:04   
I prepared two other patches for the floating point implementation. They don't deal with the issue here, but for the sake of simplicity I will attach them here for discussion:
The first one changes the READ_DOUBLE, SPLIT_DOUBLE, STORE_DOUBLE defines in svalue.h to static functions.
The second one changes interpret.c in F_FLOAT to use LOAD_INT32 and LOAD_SHORT (an old TODO), which removes any conditional compilation from that place.

Comment: the compiler uses ins_long() to store the mantissa which sounds like a waste of 4 byte on LP64 platforms. But despite its name ins_long() stores a 32bit wide integer with PUT_INT32, so that is OK. The downside is: there is no possibility to store a 64 bit value (p_int on LP64) in the bytecode... This may be something we need to repair very soon - I planned to do that during some bytecode cleanup I started for 3.5.x, but it may be needed in 3.3.x as well.
(0001076)
zesstra   
2009-05-04 15:04   
I applied the patch and a testcase in r2558.

Note:
There is one issue left here. If a float is actually too large to be represented and it is saved in save_object()/save_value(), a restore with restore_object()/restore_value() will fail (not only for the float, but for the complete savefile). A similar issue may be "NaN".
I think, we have to address this as well, although it is not really urgent.
restore_svalue() expects numbers to start with [0-9,-], but sprintf("%.12e") with my libc will print infinity as 'inf' (and NaN probably as 'nan'/'NaN'). Does anybody know, if the exact format is standardized in C89 or C99?
(0001087)
zesstra   
2009-05-07 03:42   
C99 specifies that sprintf uses "[-]inf" or "[-]infinity" for infinity and a string starting with "nan" for NaN when printing floating point numbers.
I attached a small patch making restore_svalue() to restore such numbers by using the the separately stored mantissa and exponent regardless of CURRENT_HOST. But I am not sure if there is a better strategy. Comments are welcome. ;-)
(0001102)
zesstra   
2009-05-11 16:31   
Just noticed, that my patch misses to take quoted floats into account.
BTW: Would be easier, if we use a new savefile format with a special first character as a tag for floats. The downside is, that the savefiles gets a little bit bigger as less readable for humans.
(0001159)
zesstra   
2009-05-26 05:10   
I split the part of restoring infinity and NaN into bug 0000640 for handling in 3.3.720, so that this only deals with the incorrect storing of the floats. And this part is fixed. :-)
(0001911)
zesstra   
2010-11-16 10:42   
Fix committed to master branch.
(0002341)
zesstra   
2018-01-29 19:59   
Fix committed in revision 6b46c043298f9a4e5bcd1040e0bbd4d58084be9f to master branch (see changeset 1893 for details). Thank you for reporting!
(0002392)
zesstra   
2018-01-29 22:57   
Fix committed in revision 6b46c043298f9a4e5bcd1040e0bbd4d58084be9f to master branch (see changeset 3230 for details). Thank you for reporting!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
604 [LDMud 3.2] Implementation minor always 2009-01-29 18:38 2018-01-29 22:57
Reporter: willem Platform:  
Assigned To: fufu OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.15  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: erq_args is built incorrectly
Description: This is actually for driver 3.2.15, but mantis doesn't have that version as an option. I believe the bug is also present on 3.3.

eval_arg() in main.c doesn't correctly build erq_args.

Reproduction:
./ldmud --erq "/home/mud/bin/erq --execdir /home/mud/libexec"
The ERQ daemon will not run.

An strace reveals:

execve("/home/mud/bin/erq", ["erq", "--forked", "--execdir", "/home/mud/libexec", "\7", 0x2000000d, 0x6d6f682f, 0x756d2f65, 0x622f3264, 0x652f6e69, 0x2d007172, 0x6578652d, 0x72696463, 0x6f682f00, 0x6d2f656d, 0x2f326475, ...], [/* 28 vars */]) = -1 EFAULT (Bad address)
Tags:
Steps To Reproduce:
Additional Information: My fix was to change:

/* Ensure termination */
*cp++ = '\0';

To:

/* Ensure termination */
if (*cp != '\0') *cp++ = '\0';
Attached Files: test.patch (3,626 bytes) 2009-01-30 10:08
http://ldmud.eu/file_download.php?file_id=196&type=bug
Notes
(0000940)
zesstra   
2009-01-30 02:58   
I can't reproduce this on my machine and the code in eval_args actually looks good.
I wonder if your erq_args was corrupted afterwards or if your compiler did some curious things?
Your patch should IMHO not change anything in the resulting erq_args as the only difference is, that the current code may replace a \0 by \0.
(0000941)
fufu   
2009-01-30 08:16   
The bug is valid, and so is the fix - the effect of the change is that the 'cp' pointer does not get incremented beyond the final \0 of the command line argument anymore. I'll take this one.
(0000942)
fufu   
2009-01-30 09:10   
Fixed in rev 2515. I'm still thinking about whether and how best to add a test for this.
(0000943)
fufu   
2009-01-30 10:09   
I've refactored the 'run.sh' script to allow running shell scripts, and created a test that segfaults for me due to this bug.

Gnomi, do those changes look good to you?
(0000944)
Gnomi   
2009-01-30 17:38   
I think 'continue' isn't a POSIX shell command, so the case statement should be put in a else block. And t-0000640.sh should output a line or two about that it is run. Despite that it looks fine to me.
(0000945)
fufu   
2009-01-30 18:06   
Thanks. More annoyingly, ${FOO/a/b} is not available in the POSIX shell either, according to http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
(0000946)
fufu   
2009-01-31 13:03   
Test added in rev. 2517
The fix will be in 3.3.719

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
553 [LDMud 3.2] Implementation major always 2008-07-10 09:31 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version: 3.2.15  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.2.16  
    Target Version:  
Summary: Backports of 3.3 fixes for 3.2.16
Description: This is a bug for collecting suggestions and patches of 3.3 fixes that should be backported to 3.2.16.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files: bug537.diff (6,325 bytes) 2008-07-10 09:33
http://ldmud.eu/file_download.php?file_id=141&type=bug
restore_value_alloca.diff (2,721 bytes) 2008-07-16 16:26
http://ldmud.eu/file_download.php?file_id=147&type=bug
addmessage_buff.diff (1,459 bytes) 2008-09-22 03:12
http://ldmud.eu/file_download.php?file_id=155&type=bug
Notes
(0000717)
Gnomi   
2008-07-10 09:34   
I uploaded a straightforward backport for 0000537 (missing F_CLEAR_LOCALs) and I also intend to port 0000532 (alloca in restore_value).
(0000731)
Gnomi   
2008-07-16 16:30   
I added a patch for 0000532. I did it similar to restore_object without an error handler. It's not foolproof (see my comment 666 in 0000532), but then again this is oldstable. Should I add error handlers to restore_object and restore_value, nevertheless?
(0000732)
zesstra   
2008-07-16 16:48   
I don't think, that will be necessary to invest more work than strictly necessary. An error should be rare and it will be caught eventually by the garbage collector. That should be acceptable for oldstable.
(0000790)
Gnomi   
2008-09-22 03:13   
I'd like to backport the add_message buffer overflow (r2422), too.
(Patch attached.)
(0001230)
Gnomi   
2009-06-23 14:05   
Bug 0000575 is not applicable as 3.2 doesn't have a filter(string).
Backport of 0000577 was committed as r2689.
(0001231)
Gnomi   
2009-06-23 17:23   
All remaining backports committed in r2693.
(0001625)
Gnomi   
2009-11-16 05:48   
3.2.16 was released a few months ago.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
495 [LDMud] Runtime crash sometimes 2006-12-12 08:20 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: lars OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3.713  
Product Build: 3.3.714 Build 2307 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.716  
    Target Version:  
External Data (URL):
Summary: Errors during setup_new_frame may crash the driver
Description: The following program crashes the driver:

void fun(varargs mixed* arg) {}

void create()
{
    int x;
    
    funcall(#'fun, &x);
}

Program received signal SIGSEGV, Segmentation fault.
0x08060be7 in closure_location (l=0x8b3b287) at closure.c:5653
(tgdb) bt
#0 0x08060be7 in closure_location (l=0x8b3b287) at closure.c:5653
0000001 0x080b08d5 in get_line_number_if_any (name=0xbfb9a5dc) at interpret.c:18552
0000002 0x0810914c in errorf (fmt=0xbfb99ddc "Varargs argument passed by reference.\n") at simulate.c:896
0000003 0x08092cd7 in setup_new_frame2 (funstart=0x92adb6c "\201", sp=0x81743b8, allowRefs=0, is_lambda=0) at interpret.c:7162
0000004 0x080929f0 in setup_new_frame (fx=0, inhProg=0x0) at interpret.c:7301
0000005 0x080af4f5 in int_call_lambda (lsvp=0x81743b0, num_arg=1, allowRefs=0) at interpret.c:17765
0000006 0x080b3e8a in v_funcall (sp=0x81743b8, num_arg=2) at interpret.c:20261
0000007 0x080953cd in eval_instruction (first_instruction=0x92adb7e "`", initial_sp=0x81743a0) at interpret.c:8173
0000008 0x080adc6d in apply_low (fun=0x8b23978, ob=0x92eadf0, num_arg=0, b_ign_prot=0, allowRefs=0) at interpret.c:16811
0000009 0x080ade64 in int_apply (fun=0x8b23978, ob=0x92eadf0, num_arg=0, b_ign_prot=0, b_use_default=1) at interpret.c:16889
0000010 0x080a8e2a in eval_instruction (first_instruction=0x8b1efbb "a\036", initial_sp=0x8174380) at interpret.c:16159
0000011 0x080af893 in int_call_lambda (lsvp=0x823e348, num_arg=1, allowRefs=0) at interpret.c:17893
0000012 0x080d00f9 in reset_object (ob=0x92eadf0, arg=5) at object.c:868
0000013 0x0810ba94 in load_object (lname=0x81f98e0 "w/gnomi/snf", create_super=0, depth=0, isMasterObj=0, chain=0x0) at simulate.c:2132
#14 0x0810c372 in lookfor_object (str=0x9217fd4, bLoad=1) at simulate.c:2397
#15 0x0810fc8b in f_load_object (sp=0x8174370) at simulate.c:4466
#16 0x08094222 in eval_instruction (first_instruction=0x8b4abd6 "\036\001\003P\036", initial_sp=0x8174368) at interpret.c:7974
#17 0x080af547 in int_call_lambda (lsvp=0x8174358, num_arg=2, allowRefs=0) at interpret.c:17772
#18 0x080b3e8a in v_funcall (sp=0x8174368, num_arg=3) at interpret.c:20261
#19 0x080953cd in eval_instruction (first_instruction=0x8b4abee "`\002\005\036", initial_sp=0x8174348) at interpret.c:8173
#20 0x080a622e in eval_instruction (first_instruction=0x92bc18e "a\017\003@\036", initial_sp=0x8174308) at interpret.c:14664
#21 0x080adc6d in apply_low (fun=0x9259f60, ob=0x929872c, num_arg=1, b_ign_prot=0, allowRefs=0) at interpret.c:16811
#22 0x080ade64 in int_apply (fun=0x9259f60, ob=0x929872c, num_arg=1, b_ign_prot=0, b_use_default=1) at interpret.c:16889
#23 0x080ae2ce in sapply_int (fun=0x9259f60, ob=0x929872c, num_arg=1, b_find_static=0, b_use_default=1) at interpret.c:17050
#24 0x0804c9ce in parse_command (buff=0xbfb9e2c0 "lade snf", from_efun=0) at actions.c:1094
#25 0x0804cf41 in execute_command (str=0xbfb9e2c0 "lade snf", ob=0x920e1b4) at actions.c:1258
#26 0x08054999 in backend () at backend.c:671
#27 0x080c02c9 in main (argc=20, argv=0xbfb9fc74) at main.c:615

The reason is that the current csp is not yet fully initialized (especially csp->funstart is missing). That's why int_call_lambda does a CLEAN_CSP before an error, but setup_new_frame, setup_new_frame2 and other functions like stack_overflow or allocate_array, which are called from within int_call_lambda, do not.

In the above example the call to #'fun raises the error 'Varargs argument passed by reference.', so errorf() wants to get the current line number and inspects csp->funstart, but as this may be some arbitrary value further inspection results in a segfault.

Greetings,
Gnomi.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0000569)
lars   
2007-10-14 02:04   
Cleaining the CSP in setup_new_frame() would mean that funcall(#'fun, &x) and fun(&x) would deliver differing stack traces.

The solution I chose was to update the csp->funstart inside of setup_new_frame(), just before setup_new_frame2() is called. Putting that into setup_new_frame() is more convenient for the callers anyway.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
492 [LDMud 3.2] Runtime crash always 2006-11-13 23:20 2018-01-29 22:57
Reporter: zippo Platform:  
Assigned To: lars OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.13  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.2.16  
    Target Version:  
Summary: crash with snoop + --check-refcounts
Description: This is for version 3.2.14.

This is probably just a bad cut & paste. Crasher when current_object = 0, but I don't think current_object is even meant to be used here. Here's a patch that should work:

Index: comm.c
===================================================================
RCS file: /home/mud/cvsroot/driver/src/comm.c,v
retrieving revision 1.1.1.14
diff -u -r1.1.1.14 comm.c
--- comm.c 12 Nov 2006 20:15:04 -0000 1.1.1.14
+++ comm.c 14 Nov 2006 04:19:56 -0000
@@ -6873,7 +6873,7 @@
         if ( NULL != (ob = all_players[i]->snoop_by) ) {
             interactive_t *ip;

- if (!(O_SET_INTERACTIVE(ip, current_object)))
+ if (!(O_SET_INTERACTIVE(ip, ob)))
             {
                 /* snooping monster */
                 ob->extra_ref++;
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000548)
lars   
2007-10-06 20:49   
Indeed, that resolves the problem

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
490 [LDMud 3.2] Portability minor always 2006-11-12 22:15 2018-01-29 22:57
Reporter: zippo Platform:  
Assigned To: lars OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.13  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.2.16  
    Target Version:  
Summary: x86_64 sprintf.c problem
Description: This is actually for 3.2.14, but it's not listed in Mantis.

sprintf.c: In function `string_print_formatted':
sprintf.c:1681: warning: comparison is always false due to limited range of data type
sprintf.c:1682: warning: large integer implicitly truncated to unsigned type
Tags:
Steps To Reproduce:
Additional Information: Either the "fs" variable should be unsigned long (instead of unsigned int), or we should be using INT_MAX and INT_MIN instead of PINT_MAX and PINT_MIN here.

On my system, SIZEOF_LONG and SIZEOF_CHAR_P are both == 8, and PINT_MAX then = LONG_MAX (and PINT_MIN = LONG_MIN). But the "fs" variable is unsigned int.
Attached Files:
Notes
(0000519)
zippo   
2006-11-12 22:28   
Actually, looking a bit further, it doesn't seem to make sense that fs is unsigned:

if (fs == WHATEVER_MINIMUM) { fs = WHATEVER_MAXIMUM } else { fs = -fs }

I was going to say that since it's unsigned int, we should have if (fs == 0) { fs = UINT_MAX } ... but then I read the 'else' clause, and it doesn't make much sense to me.

I guess I'm just confused, and you'll probably know the answer before I finish typing this. Either way, something is amiss.
(0000551)
lars   
2007-10-06 21:19   
I believe to resolve this problem it is sufficient to define fs as type p_uint (which is the unsigned variant of p_int). I don't have a x86-64 at my hands, so you'll have to check the correction.

fs is unsigned as it is supposed to handle the always-positive field size. The code in question however reads the fieldsize from the given NUMBER svalue, where a negative value indicates a left-aligned field (default is right-aligned): in that case, the negative value needs to be converted safely into its corresponding positive one.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
683 [LDMud 3.3] Runtime crash random 2009-09-27 17:16 2018-01-29 22:57
Reporter: favoretti Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: 2 crashes on 3.3.719 x64
Description: Hi there,

Been running x64 version for about a week now, so far had 2 crashes that I can't really explain. Any thoughts? Backtraces follow:

(gdb) bt
#0 fatal (fmt=0x4cf720 "(free_svalue) Illegal svalue %p type %d\n") at simulate.c:593
0000001 0x000000000043d564 in int_free_svalue (v=0x7f961cf0bad0) at interpret.c:1136
0000002 0x000000000044a504 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>)
    at interpret.c:8865
0000003 0x00000000004579e7 in apply_low (fun=0x7f961cf0baf0, ob=0x7f9643ebe488, num_arg=0, b_ign_prot=false,
    allowRefs=false, b_ign_shadows=false) at interpret.c:17442
0000004 0x0000000000447584 in int_apply (fun=0x8, ob=0x0, num_arg=1, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
0000005 0x000000000044d623 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>)
    at interpret.c:16645
0000006 0x00000000004579e7 in apply_low (fun=0x7f961d039ba8, ob=0x7f9643ebe488, num_arg=0, b_ign_prot=false,
    allowRefs=false, b_ign_shadows=false) at interpret.c:17442
0000007 0x0000000000447584 in int_apply (fun=0x8, ob=0x0, num_arg=1, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
0000008 0x000000000044d623 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>)
    at interpret.c:16645
0000009 0x0000000000458a0b in int_call_lambda (lsvp=<value optimized out>, num_arg=1, allowRefs=false, external=true)
    at interpret.c:18447
0000010 0x0000000000458bc3 in v_funcall (sp=0x713100, num_arg=2) at interpret.c:21003
0000011 0x000000000044b621 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>)
    at interpret.c:8475
0000012 0x000000000045871c in int_call_lambda (lsvp=0x7e40e0, num_arg=<value optimized out>, allowRefs=false,
    external=true) at interpret.c:18589
0000013 0x000000000047aa12 in reset_object (ob=0x7f9643ebe488, arg=96) at object.c:875
#14 0x00000000004ae1d5 in clone_object (str1=<value optimized out>) at simulate.c:2356
#15 0x00000000004ae421 in f_clone_object (sp=0x7130c0) at simulate.c:4376
#16 0x000000000044ee88 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>)
    at interpret.c:8276
#17 0x00000000004ad373 in catch_instruction (flags=0, offset=<value optimized out>, i_sp=0x7e3d50,
    i_pc=0x7f961d4d1a4b "e\b\002\037\001??g?4", i_fp=<value optimized out>, reserve_cost=150000, i_context=0x0)
    at simulate.c:455
#18 0x000000000044a9a2 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>)
    at interpret.c:9730
#19 0x00000000004579e7 in apply_low (fun=0x7f961d041110, ob=0x10680, num_arg=1, b_ign_prot=false, allowRefs=false,
    b_ign_shadows=false) at interpret.c:17442
#20 0x0000000000447584 in int_apply (fun=0x8, ob=0x0, num_arg=1, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
#21 0x000000000044d623 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>)
    at interpret.c:16645
#22 0x00000000004579e7 in apply_low (fun=0x7f961d039ba8, ob=0x2f280, num_arg=0, b_ign_prot=false, allowRefs=false,
    b_ign_shadows=false) at interpret.c:17442
#23 0x0000000000447584 in int_apply (fun=0x8, ob=0x0, num_arg=1, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
#24 0x000000000044d623 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>)
#25 0x0000000000458a0b in int_call_lambda (lsvp=<value optimized out>, num_arg=1, allowRefs=false, external=true)
    at interpret.c:18447
#26 0x0000000000458bc3 in v_funcall (sp=0x712fb0, num_arg=2) at interpret.c:21003
#27 0x000000000044b621 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>)
    at interpret.c:8475
#28 0x000000000045871c in int_call_lambda (lsvp=0x7e40d0, num_arg=<value optimized out>, allowRefs=false,
    external=true) at interpret.c:18589
#29 0x000000000047aa12 in reset_object (ob=0x7f95fbc490e0, arg=80) at object.c:875
#30 0x00000000004aa17d in load_object (lname=<value optimized out>, create_super=false, depth=0, isMasterObj=false,
    chain=0x0) at simulate.c:2144
#31 0x00000000004aa454 in lookfor_object (str=<value optimized out>, bLoad=true) at simulate.c:2412
#32 0x0000000000452cb0 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>)
    at interpret.c:16618
#33 0x00000000004ad373 in catch_instruction (flags=0, offset=<value optimized out>, i_sp=0x7e3d50,
    i_pc=0x7f961d4e442c "e\037\006\n\"?f\003t\200\002*?f)\002\037\002n\020\n#\b\025\037\001??,\n$,\003~\020\030\037\006\003u\200\006+e?\n-eg?5", i_fp=<value optimized out>, reserve_cost=150000, i_context=0x0) at simulate.c:455
#34 0x000000000044a9a2 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>)
    at interpret.c:9730
#35 0x00000000004579e7 in apply_low (fun=0x7f961cf2d358, ob=0x7f963a9e06e0, num_arg=1, b_ign_prot=false,
    allowRefs=false, b_ign_shadows=false) at interpret.c:17442
0000036 0x0000000000447584 in int_apply (fun=0x8, ob=0x0, num_arg=1, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
0000037 0x000000000044d623 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>)
    at interpret.c:16645
0000038 0x00000000004579e7 in apply_low (fun=0x7f961cf91fb8, ob=0x7f9622f967e0, num_arg=0, b_ign_prot=false,
    allowRefs=false, b_ign_shadows=false) at interpret.c:17442
0000039 0x0000000000447584 in int_apply (fun=0x8, ob=0x0, num_arg=1, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
0000040 0x00000000004480cb in sapply_int (fun=0x7f961cf91fb8, ob=0x7f9622f967e0, num_arg=0, b_find_static=120,
    b_use_default=true) at interpret.c:17707
0000041 0x000000000040718c in parse_command (buff=0x7fff4ef350c0 "west", from_efun=false) at actions.c:1162
0000042 0x0000000000408711 in execute_command (str=0x7fff4ef350c0 "west", ob=0x7f9622f967e0) at actions.c:1333
0000043 0x000000000040f2bf in backend () at backend.c:696
0000044 0x0000000000464f36 in main (argc=<value optimized out>, argv=<value optimized out>) at main.c:688





Second one:


(gdb) bt
#0 0x000000000041d8e6 in add_message (fmt=0x0) at comm.c:2118
0000001 0x00000000004a74d6 in print_svalue (arg=0xb7) at simulate.c:4328
0000002 0x00000000004a7652 in f_write (sp=0x713030) at simulate.c:4961
0000003 0x000000000044ee88 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:8276
0000004 0x00000000004579e7 in apply_low (fun=0x7fa1687b89c8, ob=0x7fa112564180, num_arg=0, b_ign_prot=false, allowRefs=false, b_ign_shadows=false)
    at interpret.c:17442
0000005 0x0000000000447584 in int_apply (fun=0x0, ob=0xb7, num_arg=183, b_ign_prot=<value optimized out>, b_use_default=true, b_ign_shadows=<value optimized out>)
    at interpret.c:17546
0000006 0x000000000044d623 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:16645
0000007 0x00000000004579e7 in apply_low (fun=0x7fa1687b9060, ob=0x7fa1125640b8, num_arg=2, b_ign_prot=false, allowRefs=false, b_ign_shadows=false)
    at interpret.c:17442
0000008 0x0000000000447584 in int_apply (fun=0x0, ob=0xb7, num_arg=183, b_ign_prot=<value optimized out>, b_use_default=true, b_ign_shadows=<value optimized out>)
    at interpret.c:17546
0000009 0x000000000044d623 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:16645
0000010 0x00000000004579e7 in apply_low (fun=0x7fa1687ba320, ob=0x7fa112564398, num_arg=1, b_ign_prot=false, allowRefs=false, b_ign_shadows=false)
    at interpret.c:17442
0000011 0x0000000000447584 in int_apply (fun=0x0, ob=0xb7, num_arg=183, b_ign_prot=<value optimized out>, b_use_default=true, b_ign_shadows=<value optimized out>)
    at interpret.c:17546
0000012 0x00000000004480cb in sapply_int (fun=0x7fa1687ba320, ob=0x7fa112564398, num_arg=1, b_find_static=128, b_use_default=true) at interpret.c:17707
0000013 0x00000000004a9a4c in execute_callback (cb=0x70b7c8, nargs=1, keep=false, toplevel=true) at simulate.c:4081
#14 0x000000000041cb9d in call_input_to (i=<value optimized out>, str=0x7fffaffe4670 "drop all corpse", it=0x7fa11e87b6c8) at comm.c:4127
#15 0x00000000004202ae in call_function_interactive (i=0x7fa119dd2148, str=0x7fffaffe4670 "drop all corpse") at comm.c:4212
#16 0x000000000040ee13 in backend () at backend.c:693
#17 0x0000000000464f36 in main (argc=<value optimized out>, argv=<value optimized out>) at main.c:688


Any ideas would be appreciated.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: ldmud-crash-20090923.tar.gz (41,412 bytes) 2009-09-29 15:45
http://ldmud.eu/file_download.php?file_id=250&type=bug
ldmud-crash-20090927.tar.gz (14,005 bytes) 2009-09-29 15:46
http://ldmud.eu/file_download.php?file_id=251&type=bug
bat.custom.diff (144,337 bytes) 2009-10-03 06:28
http://ldmud.eu/file_download.php?file_id=252&type=bug
bug683.diff (6,958 bytes) 2009-10-21 05:32
http://ldmud.eu/file_download.php?file_id=260&type=bug
Notes
(0001318)
zesstra   
2009-09-27 18:36   
Just some first comments:
- output on stdout/stderr and maybe the debug.log might help as well.
- additional information about your platform and environment and configuration might help.
- the two backtraces are very different. But it may well be that there is a common memory corruption as root cause. For example, the address give to print_svalue() in the second crash (0xb7) nearly certainly wrong and maybe already the one given to f_write() - but where did it come from? But I guess, we won't find it by stacktraces alone, so...
- please consider disabling the optimization for some time, because it severely limits debugging and think about adding -ggdb3 to your compiler options if you use gcc/gdb.
- If not already active, please enable the following configuration options in your driver and recompile: --enable-malloc-check, --enable-malloc-trace, --enable-malloc-lpc-trace, --enable-trace-code, --enable-debug.
- please enable core files on your system and archive the _exact_ executable that produced the core along with it.
- if the crashes occur regularly: do you recognize any common thing prior to the crashes? Reproducing the issue would of course be best. ;-)
(0001347)
favoretti   
2009-09-29 14:48   
I have core + executable for you, for the rest I'll need to recompile the driver and then wait for it to crash again (which can take a week or so).

Cores are about 2G, where do you want them upped?
(0001348)
favoretti   
2009-09-29 15:48   
Attached stderr, stdout logs.

Platform: debian lenny 64-bit, 6G RAM.
Configuration is the same as you've seen in that XML bug I've reported earlier. But just in case, in your trunk under settings/bat.

Pasteing here as well:

#!/bin/sh
#
# Settings for the BatMUD
#
# configure will strip this part from the script.

exec ./configure --prefix=/bat --with-setting=bat $*

exit 1

# --- The actual settings ---

#
# mudlib compatibility etc options
#

with_portno=1234
with_max_players=1000

with_master_name=secure/master
with_input_escape="@"

enable_erq=erq
enable_use_mysql=1
enable_malloc_sbrk=no

enable_use_parse_command=yes
enable_compat_mode=no
enable_strict_euids=no
enable_use_deprecated=yes
enable_use_alists=yes
enable_use_pcre=yes
enable_use_xml=xml2
with_time_to_reset=3600
with_time_to_clean_up=7200

enable_use_structs=yes
enable_use_tls=no

with_alarm_time=1
with_heart_beat_interval=3

#
# debug
#
enable_malloc_trace=0
enable_malloc_lpc_trace=0
enable_trace_code=no
enable_debug=no
enable_debug_telnet=no
# /debug

enable_malloc_check=no
with_malloc=smalloc

#
# performance options
#

with_optimize=med
enable_use_pthreads=yes

#no swapping
with_time_to_swap=0
with_time_to_swap_variables=0

# 1/5 of distinct strings
with_htable_size=274566

with_itable_size=16384
# 1/4 of objects
with_otable_size=32768

with_evaluator_stack_size=3000
with_compiler_stack_size=600
with_max_user_trace=120
with_max_trace=125
with_hard_malloc_limit=0

with_max_cost=25000000
with_catch_reserved_cost=150000

with_max_array_size=50000
with_max_mapping_keys=100000
with_max_mapping_size=150000
with_max_bits=20000
with_read_file_max_size=100000

# preallocation
with_min_malloced=671088640
with_min_small_malloced=536870912
(0001349)
favoretti   
2009-09-29 15:49   
So far, in both cases executables were linked against:
batmud64:/bat/mudlib/crash-20090923-231937# ldd ldmud
        linux-vdso.so.1 => (0x00007fff3dbff000)
        libnsl.so.1 => /lib/libnsl.so.1 (0x00007f1735710000)
        libm.so.6 => /lib/libm.so.6 (0x00007f173548d000)
        libcrypt.so.1 => /lib/libcrypt.so.1 (0x00007f1735255000)
        libgcrypt.so.11 => /usr/lib/libgcrypt.so.11 (0x00007f1734fee000)
        libmysqlclient.so.15 => /usr/lib/libmysqlclient.so.15 (0x00007f1734be3000)
        libxml2.so.2 => /usr/lib/libxml2.so.2 (0x00007f1734887000)
        libc.so.6 => /lib/libc.so.6 (0x00007f1734534000)
        libgpg-error.so.0 => /usr/lib/libgpg-error.so.0 (0x00007f1735a36000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x00007f1734318000)
        libz.so.1 => /usr/lib/libz.so.1 (0x00007f1734101000)
        libdl.so.2 => /lib/libdl.so.2 (0x00007f1733efd000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f1735928000)
(0001356)
zesstra   
2009-09-30 15:52   
2 GB? Mhmm, I'm afraid, I don't know where to upload that.
With enabled optimization I am also sceptical, that it will be worth the effort to upload such big cores as long as there are other possibilities.
Is all that memory actually in use? Until now all muds I know with such a memory consumption had a memory leak somewhere. ;-)

Did that crashes started after switching to the x86_64 architecture or after switching to 3.3.719? Or both?

BTW: a non-related comment to your configuration: a string hash table size >65535 is not different than 65535, it just consumes more memory. This has been changed until now only in 3.5.x. Maybe that work will someday be backported, but for now it still has to tested somewhat more.
(0001369)
favoretti   
2009-09-30 17:06   
Well, I suppose I could arrange you an account directly on the box to dig in it with GDB if you want.

Yes, that memory is in use, we are quite some HUGE(tm) MUD out there.
Crashes tarted occuring after both switching to 64 bit and to 3.3.719, it was all in one go, since previous attempts to switch to earlier driver versions were pathetic crash festshows :) This one seems to be stable, apart from these intermittent crashes.

Withregards to leaking memory, I'm not sure we do, it stays stable around 2.2g for most of the day after all objects have been loaded and most players have visited the game.

Thanks for the info about the hashtable size param, will adjust.
What I will do tomorrow is recompile the driver with full debugging options and will run on that hoping that it will crash again. Until that I can provide you access to those cores right on the machine where it runs.
(0001423)
favoretti   
2009-10-02 10:10   
Crashed again this morning, unfortunately I haven't recompiled driver with all the debugging yet. But this one is similar to one of the pervious crashes, might give you an idea on where to look.

(gdb) bt
#0 fatal (fmt=0x4cf720 "(free_svalue) Illegal svalue %p type %d\n") at simulate.c:593
0000001 0x000000000043d564 in int_free_svalue (v=0x7f0e6d9dbb30) at interpret.c:1136
0000002 0x000000000044a504 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:8865
0000003 0x00000000004579e7 in apply_low (fun=0x7f0e6d9dbb50, ob=0x7f0e3648b9f0, num_arg=0, b_ign_prot=false, allowRefs=false,
    b_ign_shadows=false) at interpret.c:17442
0000004 0x0000000000447584 in int_apply (fun=0x8, ob=0x0, num_arg=1, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
0000005 0x000000000044d623 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:16645
0000006 0x00000000004579e7 in apply_low (fun=0x7f0e6db09ba8, ob=0x7f0e3648b9f0, num_arg=0, b_ign_prot=false, allowRefs=false,
    b_ign_shadows=false) at interpret.c:17442
0000007 0x0000000000447584 in int_apply (fun=0x8, ob=0x0, num_arg=1, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
0000008 0x000000000044d623 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:16645
0000009 0x0000000000458a0b in int_call_lambda (lsvp=<value optimized out>, num_arg=1, allowRefs=false, external=true) at interpret.c:18447
0000010 0x0000000000458bc3 in v_funcall (sp=0x713100, num_arg=2) at interpret.c:21003
0000011 0x000000000044b621 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:8475
0000012 0x000000000045871c in int_call_lambda (lsvp=0x7e40e0, num_arg=<value optimized out>, allowRefs=false, external=true) at interpret.c:18589
0000013 0x000000000047aa12 in reset_object (ob=0x7f0e3648b9f0, arg=96) at object.c:875
#14 0x00000000004ae1d5 in clone_object (str1=<value optimized out>) at simulate.c:2356
#15 0x00000000004ae421 in f_clone_object (sp=0x7130c0) at simulate.c:4376
#16 0x000000000044ee88 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:8276
#17 0x00000000004ad373 in catch_instruction (flags=0, offset=<value optimized out>, i_sp=0x7e3d50,
    i_pc=0x7f0e6dfa9373 "e\b\002\037\001??g?4", i_fp=<value optimized out>, reserve_cost=150000, i_context=0x0) at simulate.c:455
#18 0x000000000044a9a2 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:9730
#19 0x00000000004579e7 in apply_low (fun=0x7f0e6db11110, ob=0x1c860, num_arg=1, b_ign_prot=false, allowRefs=false, b_ign_shadows=false)
    at interpret.c:17442#20 0x0000000000447584 in int_apply (fun=0x8, ob=0x0, num_arg=1, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
#21 0x000000000044d623 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:16645
#22 0x00000000004579e7 in apply_low (fun=0x7f0e6db09ba8, ob=0x9660, num_arg=0, b_ign_prot=false, allowRefs=false, b_ign_shadows=false)
    at interpret.c:17442
#23 0x0000000000447584 in int_apply (fun=0x8, ob=0x0, num_arg=1, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
#24 0x000000000044d623 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:16645
#25 0x0000000000458a0b in int_call_lambda (lsvp=<value optimized out>, num_arg=1, allowRefs=false, external=true) at interpret.c:18447
#26 0x0000000000458bc3 in v_funcall (sp=0x712fb0, num_arg=2) at interpret.c:21003
#27 0x000000000044b621 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:8475
#28 0x000000000045871c in int_call_lambda (lsvp=0x7e40d0, num_arg=<value optimized out>, allowRefs=false, external=true) at interpret.c:18589
#29 0x000000000047aa12 in reset_object (ob=0x7f0e27dcdc90, arg=80) at object.c:875
#30 0x00000000004aa17d in load_object (lname=<value optimized out>, create_super=false, depth=0, isMasterObj=false, chain=0x0)
    at simulate.c:2144
#31 0x00000000004aa454 in lookfor_object (str=<value optimized out>, bLoad=true) at simulate.c:2412
#32 0x0000000000452cb0 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:16618
#33 0x00000000004ad373 in catch_instruction (flags=0, offset=<value optimized out>, i_sp=0x7e3d50,
    i_pc=0x7f0e6dfb3bec "e\037\006\n\"?f\003t\200\002*?f)\002\037\002n\020\n#\b\025\037\001??,\n$,\003~\020\030\037\006\003u\200\006+e?\n-eg?5", i_fp=<value optimized out>, reserve_cost=150000, i_context=0x0) at simulate.c:455
#34 0x000000000044a9a2 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:9730
#35 0x00000000004579e7 in apply_low (fun=0x7f0e6d9fd3b8, ob=0x1b960, num_arg=1, b_ign_prot=false, allowRefs=false, b_ign_shadows=false)
    at interpret.c:17442
0000036 0x0000000000447584 in int_apply (fun=0x8, ob=0x0, num_arg=1, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
0000037 0x000000000044d623 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:16645
0000038 0x00000000004579e7 in apply_low (fun=0x7f0e6da62098, ob=0x7f0e4714efe8, num_arg=0, b_ign_prot=false, allowRefs=false,
    b_ign_shadows=false) at interpret.c:17442
0000039 0x0000000000447584 in int_apply (fun=0x8, ob=0x0, num_arg=1, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
0000040 0x00000000004480cb in sapply_int (fun=0x7f0e6da62098, ob=0x7f0e4714efe8, num_arg=0, b_find_static=72, b_use_default=true)
    at interpret.c:17707
0000041 0x000000000040718c in parse_command (buff=0x7fff9fa06b91 "west", from_efun=false) at actions.c:1162
0000042 0x0000000000408711 in execute_command (str=0x7fff9fa06b91 "west", ob=0x7f0e4714efe8) at actions.c:1333
0000043 0x000000000040f339 in backend () at backend.c:690
0000044 0x0000000000464f36 in main (argc=<value optimized out>, argv=<value optimized out>) at main.c:688


Recompiling driver with debugs now...
(0001424)
favoretti   
2009-10-02 10:18   
(Last edited: 2009-10-02 10:19)
Starting from boot tomorrow will run debugging driver.
When it crashes will let you know :)

In the meantime, if you have even a slightest idea why it crashes based on the traces we have so far (or if you want core access, let me know) - please let me know. We have 500+ players suffering daily :)

(0001425)
zesstra   
2009-10-02 11:34   
Phew, the stacks are basically identical. Thats good for a start.
Debugging a memory corruption issue is very hard, therefore we will need access to the cores, yes. (BTW: That should Gnomi as well as me, he has more experience in this and might be needed.) The problem is (as you see), that certain values have been optimized away from the compiler and that makes it harder to analyze the core. Additionally, the debug options from the driver itself which annotate memory blocks with their origin makes life usually again easier. Therefore I am the opinion that you will probably have to suffer at least one more of these crashes.
It would help to know, if this only occurs with 3.3.719 (then it has to be one of the changes there) or if it does only occur on x86_64 architectures. But I see, that this information is not available right now, so there remains only the cores. ;-)
The first and the second backtrace both involve someone going west in some object. During that at least one new object is loaded (probably a room) and some other object is cloned. The crash occurs during the initialization of this clone (create() or whatever you call it). It would help to find out, if that objects were the same in both cases (that means, the same room, where somebody went west). Then we could look at the code and check for unusual thing or try to create a test case.
I don't know if it promises any success, but maybe some of your players remembers going west directly before the crash?
(0001426)
favoretti   
2009-10-02 11:38   
Yeah, went in that way of thinking myself already, will try to dig out if someone remembers that.

Withregards to the cores access, let me quickly clear that out with the rest of game administration and I'll get back to you with login details. Would help if you could tell me how to reach you aside of bugtracker, not feeling very happy about leaving login details here :)
(0001427)
favoretti   
2009-10-02 12:18   
Aha.

We dug in a bit more. On the LPC side, it seems twice the same stuff triggered the crash:

Last crash:

2009.09.27 15:31:14 Command giver: 'players/malar/areas/outpost/mons/guard_capt#169325'
Last command: 'west'
(free_svalue) Illegal svalue 0xffffffff type 1189027840
Command giver: 'players/malar/areas/outpost/mons/guard_capt#169325'
Last command: 'west'
2009.09.27 15:31:14 Current object was players/malar/areas/outpost/mons/guard_capt#169325
Command giver: 'players/malar/areas/outpost/mons/guard_capt#169325'
Last command: 'west'
2009.09.27 15:31:14 Dump of the call chain:
Command giver: 'players/malar/areas/outpost/mons/guard_capt#169325'
Last command: 'west'
' command_hook' in ' obj/player.c' ('obj/race/p/ent-azgaroth') line 1952
' parser' in ' nroom/room.c' ('players/malar/areas/outpost/1floor/kentry') line 346
' CATCH' in ('players/malar/areas/outpost/1floor/kentry')
<lambda 0x7f961d036729> in 'players/malar/areas/outpost/1floor/kentry.c' ('players/malar/areas/outpost/1floor/kentry') offset 7
'_create_object_hook' in ' secure/master.c' (' secure/master') line 2319
' create' in ' nroom/room.c' ('players/malar/areas/outpost/1floor/kwest') line 85
' reset' in ' nroom/room.c' ('players/malar/areas/outpost/1floor/kwest') line 920
' reset_items' in ' nroom/items.c' ('players/malar/areas/outpost/1floor/kwest') line 462
' CATCH' in ('players/malar/areas/outpost/1floor/kwest')
<lambda 0x7f961d036699> in 'players/malar/areas/outpost/1floor/kwest.c' ('players/malar/areas/outpost/1floor/kwest') offset 7
'_create_object_hook' in ' secure/master.c' (' secure/master') line 2319
' create' in ' obj/monster.c' ('players/malar/areas/outpost/mons/guard_capt#169325') line 240
' extra_create' in 'players/malar/areas/outpost/mons/guard_capt.c' ('players/malar/areas/outpost/mons/guard_capt#169325') line 38
Command giver: 'players/malar/areas/outpost/mons/guard_capt#169325'
Last command: 'west'


Previous crash:
2009.10.02 04:00:27 Command giver: 'players/malar/areas/outpost/mons/guard_capt#527582'
Last command: 'west'
(free_svalue) Illegal svalue 0xffffffff type -1752428544
Command giver: 'players/malar/areas/outpost/mons/guard_capt#527582'
Last command: 'west'
2009.10.02 04:00:27 Current object was players/malar/areas/outpost/mons/guard_capt#527582
Command giver: 'players/malar/areas/outpost/mons/guard_capt#527582'
Last command: 'west'
2009.10.02 04:00:27 Dump of the call chain:
Command giver: 'players/malar/areas/outpost/mons/guard_capt#527582'
Last command: 'west'
' command_hook' in ' obj/player.c' ('obj/race/p/barsoomian-kheldor') line 1952
' parser' in ' nroom/room.c' ('players/malar/areas/outpost/1floor/kentry') line 346
' CATCH' in ('players/malar/areas/outpost/1floor/kentry')
<lambda 0x7f0e6db06729> in 'players/malar/areas/outpost/1floor/kentry.c' ('players/malar/areas/outpost/1floor/kentry') offset 7
'_create_object_hook' in ' secure/master.c' (' secure/master') line 2319
' create' in ' nroom/room.c' ('players/malar/areas/outpost/1floor/kwest') line 85
' reset' in ' nroom/room.c' ('players/malar/areas/outpost/1floor/kwest') line 920
' reset_items' in ' nroom/items.c' ('players/malar/areas/outpost/1floor/kwest') line 462
' CATCH' in ('players/malar/areas/outpost/1floor/kwest')
<lambda 0x7f0e6db06699> in 'players/malar/areas/outpost/1floor/kwest.c' ('players/malar/areas/outpost/1floor/kwest') offset 7
'_create_object_hook' in ' secure/master.c' (' secure/master') line 2319
' create' in ' obj/monster.c' ('players/malar/areas/outpost/mons/guard_capt#527582') line 240
' extra_create' in 'players/malar/areas/outpost/mons/guard_capt.c' ('players/malar/areas/outpost/mons/guard_capt#527582') line 38
Command giver: 'players/malar/areas/outpost/mons/guard_capt#527582'
Last command: 'west'
(0001428)
favoretti   
2009-10-02 12:40   
In both cases it crashes in eval_instruction in interpret.c in the piece where it processes default return:

CASE(F_RETURN):

...

        /* The caller might have a yet-unterminated SAVE_ARG_FRAME in
         * effect (this can happen in lambda closures, when the subclosure
         * to compute an efun argument executes a #'return) - undo them.
         */

        while (ap && ap > efp)
        {
            while (sp > ap)
                free_svalue(--sp); <-- this is where we crash
            sp = ap-1;
            ap = sp->u.lvalue;
        }

Crash occurs on attempting to load that guard_capt.c evaluating extra_create() as can be seen from the ldmud.log call trace and on processing the closing bracer, a.k.a. return statement.
(0001429)
fufu   
2009-10-02 14:33   
The line numbers look odd to me for 3.3.719 - do you have any custom patches in your driver?
(0001432)
favoretti   
2009-10-02 15:51   
Yeah, there is a small number, but nothing that would actually break this. If there will be suspicion that it's one of our patches I can disable some of those. Can't disable all of the, however, since it will break the game heavily :)
(0001433)
favoretti   
2009-10-02 15:54   
On a sidenote, tried to load that room this boot again.. No crash, so it could be that it's just a coincidence that it crashed twice there, although in a world with 16000+ inside rooms and hardly countable outside rooms it sounds a bit odd.
(0001434)
zesstra   
2009-10-03 05:14   
Ok... But even if you think, your patches are completely unrelated, please put them in an archive and upload them here, so we speak about the same source and the same line numbers.
Concerning login details: yes, I can understand that. ;-) You can reach us at our our developer address ldmud-dev@UNItopia.rus.Uni-Stuttgart.DE or contact me at zesstra@zesstra.de.
The place where it crashes (that free_svalue()) is not the place of the root cause. Somehow a malformed svalue was pushed onto the stack (or corrupted while already being there is even more probable). Finding that is the challenge here. A test case whould ease that enormously. Knowing the involved code could help us finding one.
It may be a coincidence, but maybe there is something in there (e.g. a rarely used feature/efun) which can cause problems when certain circumstances are met. On the other hand, your second crash was somewhere else. But it looks also like a corrupted svalue on the stack. Here, the debugging feature you enabled now are useful, because then we get the last 4096 instructions before the crash (well, if that is a call to fatal() at least).
(0001435)
favoretti   
2009-10-03 06:27   
(Last edited: 2009-10-03 06:38)
Yesterday just to be sure, except adding debug to the driver I hacked the patching out of interpret.c and simulate.c.

We used to have our own code profiler built into the driver. However, it wasn't enabled during crashes, so from what I could see, the code was never evaluated. But just to be sure I disabled it.

Now there's not that much hacking left :) Attached.

EDIT: The line numbers after this patch won't match the crashes 1:1, cuz I hacked profiler code out for the debugging version. So in case it crashes again any time soon, we'll have the perfect match between trace and line numbers.

(0001439)
favoretti   
2009-10-03 13:20   
Ok, I think I figured a relation to crashes.

Every time we crashed someone fiddled with XML functions (I had xml2 package compiled it). Now I fiddled with those myself and we crashed almost immediately with the following stack trace:

(gdb) bt
#0 0x00000000004ee262 in UNLINK_SMALL_FREE (block=0x7f26f221e158) at smalloc.c:1137
0000001 0x00000000004ee77a in mem_alloc (size=32) at smalloc.c:1545
0000002 0x00000000004f17f1 in xalloc_traced (size=24) at xalloc.c:565
0000003 0x000000000049672a in f_restore_object (sp=0x745bf0) at object.c:8977
0000004 0x0000000000451b3a in eval_instruction (
    first_instruction=0x7f271e875b2b "\037\002\003V\200\003*?f)\003\037\003>n\001\031\b", initial_sp=0x745bd0)
    at interpret.c:8219
0000005 0x00000000004cdae4 in catch_instruction (flags=0, offset=8, i_sp=0x816360,
    i_pc=0x7f271e875b2b "\037\002\003V\200\003*?f)\003\037\003>n\001\031\b", i_fp=0x745b90, reserve_cost=150000, i_context=0x0)
    at simulate.c:453
0000006 0x00000000004541c6 in eval_instruction (first_instruction=0x7f271e875aba "d\001\003?>)\026e?g?", initial_sp=0x745bc0)
    at interpret.c:9652
0000007 0x0000000000467455 in apply_low (fun=0x7f27051119b0, ob=0x7f26d58bf4a0, num_arg=1, b_ign_prot=false, allowRefs=false,
    b_ign_shadows=false) at interpret.c:17207
0000008 0x00000000004675ca in int_apply (fun=0x7f27051119b0, ob=0x7f26d58bf4a0, num_arg=1, b_ign_prot=false, b_use_default=true,
    b_ign_shadows=false) at interpret.c:17285
0000009 0x00000000004634f4 in eval_instruction (first_instruction=0x7f271e8792fa "d\001\002e\037", initial_sp=0x745af0)
    at interpret.c:16528
0000010 0x0000000000467455 in apply_low (fun=0x7f27051173d8, ob=0x7f271e5a3300, num_arg=1, b_ign_prot=false, allowRefs=false,
    b_ign_shadows=false) at interpret.c:17207
0000011 0x00000000004675ca in int_apply (fun=0x7f27051173d8, ob=0x7f271e5a3300, num_arg=1, b_ign_prot=false, b_use_default=true,
    b_ign_shadows=false) at interpret.c:17285
0000012 0x00000000004634f4 in eval_instruction (first_instruction=0x7f271f26aa2a "d\002\n\037", initial_sp=0x745a90)
    at interpret.c:16528
0000013 0x0000000000467455 in apply_low (fun=0x7f270c2cd200, ob=0x7f271f2628e8, num_arg=2, b_ign_prot=false, allowRefs=false,
    b_ign_shadows=false) at interpret.c:17207
#14 0x00000000004675ca in int_apply (fun=0x7f270c2cd200, ob=0x7f271f2628e8, num_arg=2, b_ign_prot=false, b_use_default=true,
    b_ign_shadows=false) at interpret.c:17285
#15 0x00000000004634f4 in eval_instruction (first_instruction=0x7f271c4ac199 "e\n\026\037", initial_sp=0x7459a0)
    at interpret.c:16528
#16 0x00000000004cdae4 in catch_instruction (flags=0, offset=21, i_sp=0x816360, i_pc=0x7f271c4ac199 "e\n\026\037",
    i_fp=0x745970, reserve_cost=150000, i_context=0x0) at simulate.c:453
#17 0x00000000004541c6 in eval_instruction (first_instruction=0x7f271c4abf8a "e\037", initial_sp=0x745810) at interpret.c:9652
#18 0x0000000000468c69 in int_call_lambda (lsvp=0x7cd840, num_arg=3, allowRefs=false, external=true) at interpret.c:18186
#19 0x00000000004696dc in secure_call_lambda (closure=0x7cd840, num_arg=3, external=true) at interpret.c:18560
#20 0x00000000004dd558 in socket_process_events (sock=0x7cd800, events=5) at sockets.c:1128
#21 0x00000000004dce88 in socket_poll () at sockets.c:986
#22 0x000000000040f695 in backend () at backend.c:755
#23 0x00000000004775f6 in main (argc=8, argv=0x7fff4b6dc048) at main.c:688


I recompiled the driver using libiksemel for now... Still running debugging mode in case it's unrelated.
(0001440)
favoretti   
2009-10-03 13:38   
Last call on mudside was:
2009.10.03 19:03:32 Caught error: Bad arg 1 to xml_generate(): tag is not an array with 3 elements.
Command giver: 'obj/race/p/coder-favorit'
Environment: 'city/main/boardroom'
Last command: 'call ./guilds_server_xml update_guild_object find_object("nguild/d/mage")'
' command_hook' in ' obj/player.c' ('obj/race/p/coder-favorit') line 1904
' do_command' in ' cmds/cmd_inherit.c' (' cmds/wiz/call') line 37
' CATCH' in (' cmds/wiz/call')
' command' in ' cmds/wiz/call.c' (' cmds/wiz/call') line 99
' CATCH' in (' cmds/wiz/call')
' call_lpc' in 'players/favorit/TMP.c' (' players/favorit/TMP') line 1
'update_guild_object' in 'lib/gameinfo/guilds_server_xml.c' ('lib/gameinfo/guilds_server_xml') line 61
'update_guild_info' in 'lib/gameinfo/guilds_server_xml.c' ('lib/gameinfo/guilds_server_xml') line 116
Command giver: 'obj/race/p/coder-favorit'
Environment: 'city/main/boardroom'
Last command: 'call ./guilds_server_xml update_guild_object find_object("nguild/d/mage")'
2009.10.03 19:03:32 ... execution continues.
Command giver: 'obj/race/p/coder-favorit'
Environment: 'city/main/boardroom'
Last command: 'call ./guilds_server_xml update_guild_object find_object("nguild/d/mage")'

What I did, I fed a 3-d array to xml_generate, which wasn't formed correctly.
(0001458)
zesstra   
2009-10-05 10:14   
Mhmm, I had a look at your diff. I wouldn't call 144k "not much", even if you deactivated some of it. That differs substantially from the source we have.

May I ask, what exactly you fed into xml_generate() and what the others did?

BTW: I noticed two things you should check in your diff, while having a short glance (although I may have overlooked something, I had only a few minutes to spare):
- the efun random_integer() won't return [INT_MIN .. INT_MAX] on x86_64 platforms, because your random_integer() returns uint32, but an LPC int has 64 bits on x86_64.
- f_recompile_object(). You seem to replace the blueprint of the object, while keeping the variable block. If the new program differs in variables or sequence of variables, this will cause problems, especially if the new program uses more variables, because it will read garbage beyond the variable block or overwrite stuff there.
(0001462)
favoretti   
2009-10-05 11:38   
Basically I fed a huge mapping containing multi-dimensional arrays, while being curious what kinda output it will produce.

What others did - was pretty much twiddling around, generating XML about guild information, etc. I could probably paste some code here, but I don't think it will be largely relevant. There was nothing out of ordinary which, for instance, some code typo won't produce.

([ /* 0000001 */
  0: ({ /* 0000002, size: 1 */
   ({ /* 0000003, size: 2 */
     "background",
     ({ /* 0000004, size: 1 */
       "magical"
     })
   })
 }),
  2: ({ /* 0000005, size: 7 */
   ({ /* 0000006, size: 3 */
     "skill_min",
     "cast_generic",
     6
   }),
   ({ /* 0000007, size: 3 */
     "skill_min",
     "cast_protection",
     12
   }),
   ({ /* 0000008, size: 3 */
     "skill_min",
     "consider",
     15
   }),

...

This will go on for another page or five :)

Thanks for the notices on the diff, I'll have a look. That diff has also been a long-term hacking effort of a gazillion of people so maybe now would be the time to look at it closely again.
(0001463)
favoretti   
2009-10-05 11:39   
Oh yeah, and as to 144k, if you notice, there's mostly efuns that are added.
The only hacking into the driver self would be adding ability to bypass shadows, which is rather straightforward and otherwise harmless.

The biggest part of the diff is sockets implementation.
(0001465)
zesstra   
2009-10-05 12:25   
It doesn't really matter, if it is only efuns or not. Any efun may corrupt memory (.e.g. your mentioned xml_generate()), they are not separated from the rest of the driver. I wrote some efuns which wrote somewhere they shouldn't the first time I tested them... ;-) But sometimes a memory corruption in an efun takes a long time to be noticed.
Any piece of code changing data may be the root cause of an avalanche of small or big changes leading in the end to a crash.

Concerning your last crash: if you believe, that it is caused by some call to xml_generate(), please try to reproduce it. If that does work, create a minimal test case (just enough code to trigger the problem). Otherwise, we will never make progress finding the real problem. I can't just try random arguments to xml_generate() until I find some problem (especially, because the crash by be platform/architecture-specific). ;-)
(0001518)
favoretti   
2009-10-12 07:40   
Just crashed again:

#0 0x0000000000422bf0 in add_flush_entry (ip=0x7fbc722ad0a8) at comm.c:2118
0000001 0x0000000000422b74 in add_message (fmt=0x421e27 "UH\211?H\201??\r") at comm.c:2060
0000002 0x00000000004d48b7 in print_svalue (arg=0x7453d0) at simulate.c:4322
0000003 0x00000000004d5913 in f_write (sp=0x7453d0) at simulate.c:4955
0000004 0x00000000004517ea in eval_instruction (
    first_instruction=0x7fbcb4181aba "d\001\004\n\017\003T_e\n\017\022\005\022<.\a\b\017f_\037", initial_sp=0x7453c0)
    at interpret.c:8219
0000005 0x0000000000466d3e in apply_low (fun=0x7fbc9e3bd0e8, ob=0x7fbc7226db08, num_arg=0, b_ign_prot=false,
    allowRefs=false, b_ign_shadows=false) at interpret.c:17093
0000006 0x000000000046727a in int_apply (fun=0x7fbc9e3bd0e8, ob=0x7fbc7226db08, num_arg=0, b_ign_prot=false,
    b_use_default=true, b_ign_shadows=false) at interpret.c:17285
0000007 0x00000000004631a4 in eval_instruction (first_instruction=0x7fbcb4a7bb92 "\037\001{$+\037\001o\016eeg?",
    initial_sp=0x7452e0) at interpret.c:16528
0000008 0x0000000000466d3e in apply_low (fun=0x7fbc9a559590, ob=0x7fbc72c27210, num_arg=2, b_ign_prot=false,
    allowRefs=false, b_ign_shadows=false) at interpret.c:17093
0000009 0x000000000046727a in int_apply (fun=0x7fbc9a559590, ob=0x7fbc72c27210, num_arg=2, b_ign_prot=false,
    b_use_default=true, b_ign_shadows=false) at interpret.c:17285
0000010 0x00000000004631a4 in eval_instruction (first_instruction=0x7fbcb4181e12 "d\001\005\037", initial_sp=0x745220)
    at interpret.c:16528
0000011 0x0000000000466d3e in apply_low (fun=0x7fbc9a5564f8, ob=0x7fbc72c26b60, num_arg=1, b_ign_prot=false,
    allowRefs=false, b_ign_shadows=false) at interpret.c:17093
0000012 0x000000000046727a in int_apply (fun=0x7fbc9a5564f8, ob=0x7fbc72c26b60, num_arg=1, b_ign_prot=false,
    b_use_default=true, b_ign_shadows=false) at interpret.c:17285
0000013 0x0000000000467673 in sapply_int (fun=0x7fbc9a5564f8, ob=0x7fbc72c26b60, num_arg=1, b_find_static=false,
    b_use_default=true) at interpret.c:17446
#14 0x00000000004d43cf in execute_callback (cb=0x73d948, nargs=1, keep=false, toplevel=true) at simulate.c:4075
#15 0x000000000042638f in call_input_to (i=0x7fbc722ad0a8, str=0x7fffe1266540 "use ref at mahogany in dw",
    it=0x7fbcc2db05a8) at comm.c:4127
#16 0x000000000042652d in call_function_interactive (i=0x7fbc722ad0a8, str=0x7fffe1266540 "use ref at mahogany in dw")
    at comm.c:4212
#17 0x000000000040f1fe in backend () at backend.c:679
#18 0x00000000004772a6 in main (argc=8, argv=0x7fffe1267f58) at main.c:688
(0001524)
zesstra   
2009-10-16 04:35   
The stack traces alone give not enough information, so we need access to core + binary + source. If you still consider giving us access to your machine for that purpose, the easiest would be to give you Gnomis and my public ssh key which you temporarily add to your authorized_keys.
Otherwise, you need to pack the stuff and put it somewhere for download. Although then we might have problems having the right gdb for your platform+architecture.
(0001525)
zesstra   
2009-10-16 05:20   
BTW: You might want to have a look at your garbage collector. You added some socket stuff. During the early phase of the GC run you call clear_socket_refs() to clear the refcounters, but later you don't call count_socket_refs(), but clear_socket_refs() again. That will lead to uncounted references and later to memory that might be used twice (because the GC will mark memory as free which is not referenced). So, if you ever have a GC run while having socket callbacks, your system will be unstable.
(0001528)
Gnomi   
2009-10-18 09:52   
We found a possible cause in the xml2 functions. I committed a fix in 3.3/trunk as r2770. Maybe you could try it out?
(0001529)
favoretti   
2009-10-18 10:42   
Will do. Although last 2 crashes occured with libiksemel, since I was trying to exclude the possible reason of crashing.
(0001530)
favoretti   
2009-10-18 10:49   
@Zesstra: that's a brilliant find! Thanks. That sounds like something I overlooked/mistyped while manually transferring some failed hunks...

Could might as well be responsible for those crashes of late..

We're gonna try to run test version of mud under valgrind.. Maybe that will give us some pointers.

Withregards to access to cores and source... There's some commotion about accessing internal net here, Would it be enough if I give you some VM off-site where no mudlib will be present, but just those cores, source and logs?
(0001531)
zesstra   
2009-10-18 10:55   
Yes, that will be sufficient. But don't forget the correct binary as well and gdb. ;-)
(0001532)
favoretti   
2009-10-18 12:03   
BTW, something unrelated, but maybe nice to fix just in case.
While waiting on startup of ldmud under valgrind, this popped out:
==19441== Conditional jump or move depends on uninitialised value(s)
==19441== at 0x43BA54: e_sscanf (efuns.c:4134)
==19441== by 0x4539E1: eval_instruction (interpret.c:9516)
==19441== by 0x467104: apply_low (interpret.c:17207)
==19441== by 0x467279: int_apply (interpret.c:17285)
==19441== by 0x4631A3: eval_instruction (interpret.c:16528)
==19441== by 0x467104: apply_low (interpret.c:17207)
==19441== by 0x467279: int_apply (interpret.c:17285)
==19441== by 0x4631A3: eval_instruction (interpret.c:16528)
==19441== by 0x468918: int_call_lambda (interpret.c:18186)
==19441== by 0x46B9ED: v_funcall (interpret.c:20742)
==19441== by 0x451F74: eval_instruction (interpret.c:8418)
==19441== by 0x468CEF: int_call_lambda (interpret.c:18328)

He's generally right, checking for value initialization is a Good Thing(tm) ;-)

I'll set up the VM for you in a few hours and will place those crashcollections there. Our crashchecker autocopies the current binary next to core, so you'll have precise binaries with each crashdump.
(0001535)
favoretti   
2009-10-18 17:59   
Ok, if you could send me your ssh keys, I'll add them to the machine with all you need to have for analyzing crashdumps.

Details of the machine: 89.105.199.206, user bat.
You'll have full sudo rights, that VM is totally yours, feel free to install any tools you might find missing.

It's identical to the machine we're using s/w-wise.

Source is in /home/bat/ldmud-src.

Thanks for looking into it!
(0001537)
Gnomi   
2009-10-20 06:07   
The last two crashes (in add_flush_entry) are unrelated to the previous ones and result from inconsistencies in the list of dirty players.
(0001538)
favoretti   
2009-10-21 02:53   
Yeah, that I got as well, question is, how come it got dirty...
(0001539)
Gnomi   
2009-10-21 03:05   
Players get dirty all the time. And normally when add_message(message_flush); is called they get clean again. And exec() is counting on that. But this time too many messages were sent to a particular player (a login object), so that its socket buffer got full and messages had to be discarded. This interactive object won't get clean until the master object was notified. And that was something exec() didn't expect and so it left some non-interactive object (the former interactive object) in the list of dirty players which lead to the crash.

It can be fixed quite easily and I'll have a fix for that shortly.
(0001540)
Gnomi   
2009-10-21 05:33   
I attached a patch for 3.3 and committed a patch for 3.5 as r2771.
(0001541)
favoretti   
2009-10-21 08:45   
Thanks! Will patch it up right away.
Any thoughts on the previous crashes though?
(0001542)
Gnomi   
2009-10-21 10:03   
(Last edited: 2009-10-21 10:03)
The first one (20090927-153151) has the same cause as the last two ones (exec() on dirty players).

The next two crashes (20090927-153151 and 20091002-040121) I don't know. They're hard to debug (optimized and no TRACE_CODE). They both occurred when 'players/malar/areas/outpost/mons/guard_capt' was loaded and the driver was returning from the function extra_create and cleaned up the stack. So somebody put an illegal value on the stack but who or how I cannot see in the core.

The fourth one (20091003-190417) had probably something to do with libxml2 processing, which we already fixed. It shows memory corruption and has the following call trace:
    lib/finger/finger_ob#266918->load_character
    lib/finger/server->query_web_player_data
    lib/webgw/modules/xmlfinger->request
So this one is fixed.

(0001543)
favoretti   
2009-10-21 11:00   
Thanks! I'd say we mark this as resolved, and wait if something else occures. If so, we keep running in debug mode, so that we can produce usable cores and I'll just log a new one.

Guys, I can't express my thanks for bearing with me and helping us solving it. You made a ton of players very happy :)
(0001572)
favoretti   
2009-10-29 15:53   
Aaaand, we have a winner:

Core was generated by `/bat/bin/ldmud -m /bat/mudlib --pidfile /bat/mudlib/ldmud.pid --debug-file /bat'.
Program terminated with signal 8, Arithmetic exception.
[New process 23645]
#0 0x00000000004cdd27 in dump_core () at simulate.c:591
591 *((char*)0) = 0/a;
(gdb) bt
#0 0x00000000004cdd27 in dump_core () at simulate.c:591
0000001 0x00000000004cdc5e in fatal (fmt=0x4fe1e8 "'illegal' instruction encountered.\n") at simulate.c:653
0000002 0x00000000004513e0 in eval_instruction (first_instruction=0x7f828ab2fef2 "", initial_sp=0x745a40)
    at interpret.c:8103
0000003 0x00000000004670d1 in apply_low (fun=0x7f82d7763338, ob=0x7f828ab3fa70, num_arg=0, b_ign_prot=false,
    allowRefs=false, b_ign_shadows=false) at interpret.c:17207
0000004 0x0000000000467246 in int_apply (fun=0x7f82d7763338, ob=0x7f828ab3fa70, num_arg=0, b_ign_prot=false,
    b_use_default=true, b_ign_shadows=false) at interpret.c:17285
0000005 0x0000000000463170 in eval_instruction (
    first_instruction=0x7f82d7bef608 "e?\n??fn\006\020\200\032*m\004\017\200\032*?f>\200\033+\037\032(\002\037\033n\a\017{i+\037", initial_sp=0x745880) at interpret.c:16528
0000006 0x00000000004cd6c8 in catch_instruction (flags=0, offset=19, i_sp=0x815d60,
    i_pc=0x7f82d7bef608 "e?\n??fn\006\020\200\032*m\004\017\200\032*?f>\200\033+\037\032(\002\037\033n\a\017{i+\037",
    i_fp=0x745680, reserve_cost=150000, i_context=0x0) at simulate.c:453
0000007 0x0000000000453e42 in eval_instruction (first_instruction=0x7f82d7c58a12 "d\004\002e\037", initial_sp=0x745660)
    at interpret.c:9652
0000008 0x0000000000466d0a in apply_low (fun=0x7f82d7787898, ob=0x7f828ab3fa70, num_arg=2, b_ign_prot=false,
    allowRefs=false, b_ign_shadows=false) at interpret.c:17093
0000009 0x0000000000467246 in int_apply (fun=0x7f82d7787898, ob=0x7f828ab3fa70, num_arg=2, b_ign_prot=false,
    b_use_default=true, b_ign_shadows=false) at interpret.c:17285
0000010 0x0000000000463170 in eval_instruction (first_instruction=0x7f82df49a7f2 "d", initial_sp=0x745200)
    at interpret.c:16528
0000011 0x0000000000469562 in call_function (progp=0x7f82df49a310, fx=18) at interpret.c:18650
0000012 0x000000000044a660 in call_heart_beat () at heartbeat.c:289
0000013 0x000000000040f2f5 in backend () at backend.c:732
#14 0x0000000000477272 in main (argc=8, argv=0x7fff09864498) at main.c:688


Uploading cores to the same vm again.

This time it's again that Malar's area. All it does it puts some objects into arrays and then removes arrays with

array -= ({ 0 });

Seems it somehow screws something up. If need be I'll upload LPC code of the relevant pieces.

Appreciate a lot if you could have a glance.

Thanks!!
(0001594)
favoretti   
2009-11-03 17:44   
Guys, any luck? Did you have a chance to have a look yet? Thanks!
(0001595)
favoretti   
2009-11-03 17:51   
Actually to elaborate a bit more on what the LPC code does.
That array contains object references. On certain occasions LPC code fires
array -= ({ 0 }) to remove object references to objects that have been destructed.

It also happens in second_life() of monsters, so somewhere just before object gets destructed.

We tried to reproduce it under valgrind, but couldn't find anything even remotely useful. But we thought that maybe explaining this to you will light the bulb somewhere :)
(0001598)
Gnomi   
2009-11-04 04:51   
I had a first look and didn't found anything that could be the cause. But I hadn't enough time to look deeper so far. In the next few days I shall have enough time to do that.
(0001605)
Gnomi   
2009-11-05 04:31   
I had another look yesterday. I'm I right that second_life() in /players/malar/areas/outpost/mons/veteran_guard1.c just contains a return; (or nothing at all)?

It seems to me that 2 bytes of the function were overwritten or wrongly written (the first four bytes consist of 00 19 00 80, but should have been 00 00 19 <whatever>). But at this time I have no idea how this could have happened.

Which LPC code did you refer to in comment 0000683:0001595 (about removing destructed objects from an array)? Could we have a look at the LPC code from Malar's area?
(0001606)
favoretti   
2009-11-05 04:37   
Second life from the mob:
second_life()
{
        MSERV->remove(this_object());
}

MSERV:

FILE /players/malar/areas/outpost/monster_server.c 548 bytes, 42 lines.
---------------------------------------------------------------------------
// Monster server for outpost
// Malar

object *guards = ({ });

add(object mons)
{
  guards+= ({ mons });
}

get()
{
  update();
  if (sizeof(guards))
    {
      object mons = guards[0];
      guards= guards[1..];
      mons->set_aggressive(1);
      return mons;
    }
  else return 0;
}

remove(object ob)
{
  if(member_array(ob, guards) != -1) guards -= ({ ob });
  update();
  return 1;
}

query_mons()
{
  update();
  write(guards);
  return guards;
}

update()
{
  guards-=({ 0 });
  return 1;
}
EOF
(0001607)
Gnomi   
2009-11-05 06:01   
Then there's something badly wrong with the program structure. As I read the bytecode, second_life() is the last function in veteran_guard1.c. And there are only 8 bytes left in the bytecode block (afterwards comes the function lookup table, which seems fine), such an call_other needs 12 bytes.
(0001608)
favoretti   
2009-11-05 06:24   
Right... Any ideas on the cause?
(0001614)
Gnomi   
2009-11-06 09:06   
None whatsoever.

The whole program structure is consistent (malloc size, program size, pointers to the several tables of the program) in this regard, that there are only 8 bytes left for this particular function. So if there really should have been a call_other, then either the LPC compiler aborted the compilation at that function (and returned the compiled program nevertheless) or removed some bytes from the program at the end of the compilation. The first possibility I cannot image. And for the second one: The compiler does remove some opcodes during the compilation, but I went over these places and haven't found anything wrong with them. And it should be fairly reproducible. Did you try to call second_life on it again?

Could I have a look on veteran_guard1.c?
(0001615)
favoretti   
2009-11-07 10:11   
FILE /players/malar/areas/outpost/mons/veteran_guard1.c 1246 bytes, 37 lines.
---------------------------------------------------------------------------
#define MSERV "/players/malar/areas/outpost/monster_server"
inherit "obj/monster";
inherit "/players/shardik/monster/renaming_limbs";
extra_create ()
{
  set_name ("veteran guard");
  set_short ("an old veteran guard");
  set_long (line_wrap("This old elf is a typical elven soldier. Proud of"+
                      " his art and sure in his swordsmanship he stands tall"+
                      " and secure. You are certain this man knows how to"+
                      " fight. At least he looks like he knows. He has a fist"+
                      " insignia on his breastplate."));
  set_id (({"elf","guard","elite guard","guard with insignia",
                "elven guard","an elven guard",
                "guard with a flaming fist insignia"}));
  set_hunt_range(5);
  set_al(500);
  set_defender(1);
  set_level(21);
  set_wimpy(0);
  set_aggressive(0);
  set_gender(1);
  set_race("elf");
  set_skill("cleave",80,"attacker","while_fighting");

  set_skill_chance("dodge",70);
  set_skill_chance("negate offhand penalty",80);
  rename_limbs( ({"right hand", 1, "fist", "left hand", 1, "fist",
                      "right foot", 0, "kick"}) );
  add_random_weapon("random_katana");
  if(file_name() != base_name()) MSERV->add(this_object());
}

second_life()
{
        MSERV->remove(this_object());
}
(0001618)
Gnomi   
2009-11-10 15:37   
The patch against crashes because of dirty users was committed to 3.3 as r2806.
(0001619)
favoretti   
2009-11-10 15:39   
Cool. Any ideas on the last crash, though? :-P Sorry if I become annoying :)
(0001621)
Gnomi   
2009-11-11 05:20   
I can confirm that the compiler did compile the second_life() function (because there is a string for "remove" in the program's string table). I have searched for the missing bytecodes and found veteran_guard3.c seems to be identical to veteran_guard1.c. Can you confirm that both files are the same?
(0001622)
favoretti   
2009-11-11 05:32   
Pretty much, yeah.

favorit@batmud64:/bat/mudlib/players/malar/areas/outpost/mons$ cat veteran_guard3.c
#define MSERV "/players/malar/areas/outpost/monster_server"
inherit "obj/monster";
inherit "/players/shardik/monster/renaming_limbs";
extra_create ()
{
  set_name ("veteran guard");
  set_short ("a tall elven guard with a fist insignia");
  set_long (line_wrap("This tall guard has seen many battles. He is one of"+
              " the veteran guards in the outpost."+
              " He is vigilant and alert. He wears a thin armour of"+
              " elven chain and a green tunica on top of that with"+
              " a fist insignia."));
  set_id (({"elf","guard","elite guard","guard with insignia",
        "elven guard","an elven guard","guard with a flaming fist"+
        " insignia"}));
  set_hunt_range(5);
    set_al(500);
    set_defender(1);
    set_level(21);
    set_wimpy(0);
    set_aggressive(0);
    set_gender(1);
    set_race("elf");
  set_skill("cleave",80,"attacker","while_fighting");
  
  set_skill_chance("dodge",70);
  set_skill_chance("negate offhand penalty",80);
    rename_limbs( ({"right hand", 1, "fist", "left hand", 1, "fist", "right foot", 0, "kick"}) );
    add_random_weapon("random_katana");
    if(file_name() != base_name()) MSERV->add(this_object());
}

second_life()
{
    MSERV->remove(this_object());
}
(0001623)
Gnomi   
2009-11-11 07:46   
I'm still out of ideas. We have two nearly identical files which give identical programs with identical bytecodes (except the string content which doesn't matter because it's stored in the global string table, not in the program). But one of them is missing 10 bytes before the final and automatic 'return' bytecode in second_life(), while the other is fine.
(0001624)
favoretti   
2009-11-11 07:54   
Heh, indeed. Why that happens is beyond my comprehension. So far it's been 10 days stable, if it will ever crash again I hope a new crash dump will give more ideas.
(0001666)
Gnomi   
2009-12-22 10:22   
And we've found the cause for the last one. Wildcat could reproduce this bug in 0000709, so we finally tracked that one down. The bugfix was committed as r2809. So I'm now closing this bug.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
577 [LDMud 3.3] Implementation crash always 2008-09-28 15:30 2018-01-29 22:57
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: high OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: Potential crashes in send_erq() and send_udp() due to stack overflow
Description: f_send_erq() and f_send_udp() allocate temporary buffers for their messages respectively the destination hostname. Using large strings as hostnames or large arrays (if the array size is not suitably limited) may crash the driver.
I will attach a patch for this issue.
Tags:
Steps To Reproduce: send_udp("a"*8000000, 4242, "bla");
Additional Information:
Attached Files: send_erq_send_udp.diff (5,117 bytes) 2008-09-28 15:45
http://ldmud.eu/file_download.php?file_id=160&type=bug
Notes
(0000799)
zesstra   
2008-10-04 12:55   
Should be fixed in r2436.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
576 [LDMud 3.3] Implementation crash always 2008-09-24 17:21 2018-01-29 22:57
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: high OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: save_object() and restore_object() may crash with large argument strings
Description: save_object() and restore_object() allocate a temporary buffer on the stack which has the size of the given string. Because stack memory is usually a very limited ressource and alloca() has no error handling (does not return NULL if the stack limit would be exceeded) but just moves the stack pointer, after the allocation either system libs or the heap might be overwritten or in the best case non-allocated memory areas are accessed, which will terminate the driver.
Tags:
Steps To Reproduce: save_object("a"*8000000);

and

mixed m;
void test() {restore_object("a"*8000000);}
Additional Information:
Attached Files: save_restore__object.diff (10,909 bytes) 2008-09-24 17:23
http://ldmud.eu/file_download.php?file_id=159&type=bug
Notes
(0000793)
zesstra   
2008-09-24 17:31   
Patch is attached. It depends on the errorhandler.diff attached to bug 0000575.
In restore_object() the error handling is slightly changed. Instead of keeping track of allocated ressources on every errorf() the error handler is pushed much earlier on the stack and ressources are referenced in the cleanup structure as soon as they are allocated. It is slightly less efficient but I think the code is more robust.
(0000798)
zesstra   
2008-10-04 12:48   
Should be fixed by r2435.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
575 [LDMud 3.3] Implementation crash always 2008-09-23 03:27 2018-01-29 22:57
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: high OS Version: 10.5.x  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: filter(<string>,...) may crash with large strings
Description: filter() allocates a temporary buffer on the stack which has the size of the given string. Because stack memory is usually a limited ressource and alloca() has no error handling (does not return NULL if the stack limit would be exceeded) but just moves the stack pointer, after the allocation either non-allocated memory areas or system libs or the heap might be overwritten.
Tags:
Steps To Reproduce: Assuming the standard 8MB stack:
filter("a")*8000000,#'intp);
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files: errorhandler.diff (4,692 bytes) 2008-09-24 15:03
http://ldmud.eu/file_download.php?file_id=157&type=bug
filterV2.diff (4,454 bytes) 2008-09-24 15:04
http://ldmud.eu/file_download.php?file_id=158&type=bug
Notes
(0000791)
zesstra   
2008-09-23 06:49   
First draft of a patch is attached. It introduces an error handler and cleanup structure and unfortunately involves a transfer of the error handler on the stack, because the arguments are partially removed from the stack in the meantime. If someone devises a simpler strategy... ;-)
Ah, and as a note: the patch uses free_svalue to free the error handler and in that process the cleanup is done. It can be done manually without free_svalue (see patch), but I think, it is cleaner in this way.
(0000792)
zesstra   
2008-09-24 15:08   
Gnomi suggested to introduce a general error handler and a function for allocating memory from the heap and pushing an error handler for freeing that memory at the same time.
One suggestion for this is attached as errorhandler.diff.
filterV2.diff is an updated patch which makes use of this.
Additionally the patch fixes a bug in filter() if there is is not enough memory for the result string. In this case filter() used to push 0 as string onto the value stack. Now the proper runtime error is raised.
(0000794)
zesstra   
2008-09-26 18:06   
Should be fixed in r2434.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
550 [LDMud 3.3] Compilation, Installation major always 2008-07-08 14:09 2018-01-29 22:57
Reporter: zortek Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: xptmalloc compilation failure
Description: In file included from xptmalloc.c:20,
                 from xalloc.c:307:
ptmalloc/malloc.h:72:1: warning: "__THROW" redefined
In file included from /usr/include/features.h:329,
                 from /usr/include/sys/types.h:27,
                 from port.h:72,
                 from driver.h:18,
                 from xalloc.c:14:
/usr/include/sys/cdefs.h:47:1: warning: this is the location of the previous definition
In file included from xalloc.c:307:
xptmalloc.c: In function ptmalloc_ref_unused:
xptmalloc.c:252: error: clib_alloc_stat undeclared (first use in this function)
xptmalloc.c:252: error: (Each undeclared identifier is reported only once
xptmalloc.c:252: error: for each function it appears in.)
make: *** [xalloc.o] Error 1
Tags:
Steps To Reproduce: # ./configure --with-malloc=ptmalloc
# make
Additional Information:
Attached Files: driver.h.diff (608 bytes) 2008-07-09 02:26
http://ldmud.eu/file_download.php?file_id=137&type=bug
ptmalloc.diff (1,899 bytes) 2008-07-09 14:33
http://ldmud.eu/file_download.php?file_id=140&type=bug
Notes
(0000678)
zesstra   
2008-07-08 15:58   
I can reproduce the undeclared 'clib_alloc_stat' on MacOS 10.5.3, though I don't have any warning about the redefinition of __THROW.
(0000681)
zesstra   
2008-07-08 16:19   
Looks to me that count_up(clib_alloc_stat, 0); in ptmalloc_ref_unused() in xptmalloc.c should be enclosed in a #if defined(SBRK_OK) ... #endif?
(0000682)
zortek   
2008-07-08 16:33   
I've been walking the revs...(currently up through 2368) compiles.
I'm supposing that:
       59 /* PTHREADS need a normal malloc() */
       60 #if defined(SBRK_OK) && defined(USE_PTHREADS)
       61 # undef SBRK_OK
       62 #endif
is the culprit. I'll try wrapping the ptmalloc_ref_unused as suggested.
(0000683)
zesstra   
2008-07-08 16:42   
Attached suggested mini patch xptmalloc.diff.
(0000685)
zortek   
2008-07-08 16:57   
I updated to rev 2375 and added the wrapper and it fixed the failure for me.

xptmalloc.c
245 #if defined(SBRK_OK)
246 /* Reference a couple of unused variables and functions to avoid
247 * unnecessary warning.
248 */
249 void ptmalloc_ref_unused(void)
250 {
251 in_malloc = 0;
252 print_block(0, 0);
253 count_up(clib_alloc_stat, 0);
254 }
255 #endif

The remaining warnings from xalloc don't make my spleen quiver to overly much. :)

In file included from xptmalloc.c:20,
                 from xalloc.c:307:
ptmalloc/malloc.h:72:1: warning: "__THROW" redefined
In file included from /usr/include/features.h:329,
                 from /usr/include/sys/types.h:27,
                 from port.h:72,
                 from driver.h:18,
                 from xalloc.c:14:
/usr/include/sys/cdefs.h:47:1: warning: this is the location of the previous definition
xalloc.c:115: warning: in_mallocâ defined but not used
xalloc.c:915: warning: print_block defined but not used
(0000689)
zortek   
2008-07-08 18:06   
Well, while it compiles, I'm not able to get a parser that doesn't immediately segfault using ptmalloc since rev 2368. (pthreads && ptmalloc)
(0000690)
zesstra   
2008-07-08 18:07   
Mhmm, ok, that works as well.
I would not remove the whole function without SBRK_OK, but only the count_up() call, then you won't get the warnings about unused in_malloc and print_block() which is the anyway the whole purpose of ptmalloc_ref_unused().
(0000692)
zesstra   
2008-07-08 18:22   
Mhmm, I do not get a segfault, but a working driver (--with-malloc=ptmalloc --enable-use-pthreads).
Your segfault may not be related to this issue. Could you post a stacktrace? (Either by running driver in gdb and issuing a 'bt full' after the segfault or examining a core dump with gdb.)
(0000693)
zortek   
2008-07-09 01:16   
GNU gdb Red Hat Linux (6.5-16.el5rh)
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) start
Breakpoint 1 at 0x80b5c27: file main.c, line 251.
Starting program: /mud/trunk/src/ldmud
[Thread debugging using libthread_db enabled]
[New Thread -1208072512 (LWP 18135)]
[Switching to Thread -1208072512 (LWP 18135)]
main (argc=1, argv=0xbf8ffc74) at main.c:251
251 {
(gdb) continue
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x47faeb57 in _int_free () from /lib/libc.so.6
(gdb) bt full
#0 0x47faeb57 in _int_free () from /lib/libc.so.6
No symbol table info available.
0000001 0x47fb25b0 in free () from /lib/libc.so.6
No symbol table info available.
0000002 0x47f69e52 in _nl_load_locale_from_archive () from /lib/libc.so.6
No symbol table info available.
0000003 0x47f68bd3 in _nl_find_locale () from /lib/libc.so.6
No symbol table info available.
0000004 0x47f686d6 in setlocale () from /lib/libc.so.6
No symbol table info available.
0000005 0x080b5c8e in main (argc=Cannot access memory at address 0x1
) at main.c:269
        i = <value optimized out>
        set = {__val = {8192, 0 <repeats 31 times>}}
        rc = 0

Odd... dumping on:
main.c:269 setlocale(LC_CTYPE, ""); /* Use the locale defined in the LANG env var */

I appologise, I'm still a bit wet behind the ears on this level of exploration. I don't know if I should start a new bug issue or how to document this dialog at this point. I'll try to discover what has changed since rev 2368 that might cause it to fumble at this odd point. Any hints?
(0000694)
zortek   
2008-07-09 02:31   
(Last edited: 2008-07-09 02:34)
Well, I don't know why yet, but the relocation of port.h upward in driver.h is the break. I returned it to its original location and no more segfaults.

/* Include the portability headers */
#include "port.h"

I supplied a diff and suppose that the original bug report is resolved.

Any hints what might be offending the sequencing? Does this discovery resolve another bug or create a new problem? Was the relocation of the include needed to address a challenge?

(0000697)
Gnomi   
2008-07-09 03:14   
If you move machine.h back down you may get SBRK_OK defined (it's defined in machine.h which is included in port.h), which is not good if pthreads are used.
(0000698)
Gnomi   
2008-07-09 03:23   
I can reproduce the segfault and will look into it.
(0000708)
zesstra   
2008-07-09 14:37   
Gnomi found out, that the root cause for the crash are name clashes between our implementation of ptmalloc and the one in glibc. In that sense, it is a different bug than this one.
However, this problem occurs only, if it is not possible to replace the system malloc (glibcs ptmalloc) by our own ptmalloc.
The recent changes had the side effect to undefine SBRK_OK unnecessarily in some cases (use of pthreads) and thus prevent to replace malloc.
The attached patch enforces SBRK_OK in driver.h, if ptmalloc is used as memory allocator, so that the driver always uses its built-in ptalloc. While we should discuss how to deal with the bigger problem of name clashes in our code and the glibc, this should be a work-around for most users.
Additionally, clib_alloc_stat in xptmalloc.c is only used if REPLACE_MALLOC is defined.
Could you please check ptmalloc.diff?
(0000710)
zortek   
2008-07-09 15:12   
Rev. 2377 and applied ptmalloc.diff. Works for me. Thanks for the help and learning opportunity.
(0000734)
zesstra   
2008-07-16 17:36   
I applied the patch in r2390 which should resolve this bug.
Of course, the underlying problem with the name collisions of our ptmalloc and glibc ptmalloc (0000552) remain, that has to be solved later on.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
542 [LDMud 3.3] Compilation, Installation minor always 2008-05-09 15:45 2018-01-29 22:57
Reporter: fufu Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.713  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: creating configure from configure.in fails
Description: to reproduce: cd src; autoconf autoconf/configure.in > configure.test
with autoconf 2.61, this results in a few warnings and a final line saying

autom4te-2.61: /usr/bin/m4 failed with exit status: 1
Tags:
Steps To Reproduce:
Additional Information: The AC_FORM_HELP macro sometimes generates a %0s format string which m4 doesn't like.

I'll attach a patch that appears to fix the problem -- it uses %.0s instead of %0s and appears to work.
Attached Files: fix-configure-in.patch (1,383 bytes) 2008-05-09 15:45
http://ldmud.eu/file_download.php?file_id=123&type=bug
Notes
(0000620)
fufu   
2008-05-09 16:03   
This is a duplicate of 0000541, sorry.
(0000636)
zesstra   
2008-06-30 18:45   
Patch applied in r2367 / 3.3.717.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
541 [LDMud 3.3] Compilation, Installation minor always 2008-05-09 15:02 2018-01-29 22:57
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version: 3.3  
Product Build: r2364 Resolution: duplicate  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: Errors in autoconf/configure.in
Description: Apparantly, recent autoconf releases can't process our autoconf/configure.in into to configure. Reported errors are:
/sw/bin/m4:autoconf/configure.in:129: Warning: unrecognized specifier in `%0s'
/sw/bin/m4:autoconf/configure.in:168: Warning: unrecognized specifier in `%0s'
/sw/bin/m4:autoconf/configure.in:180: Warning: unrecognized specifier in `%0s'
/sw/bin/m4:autoconf/configure.in:183: Warning: unrecognized specifier in `%0s'
/sw/bin/m4:autoconf/configure.in:215: Warning: unrecognized specifier in `%0s'
autom4te-2.62: /sw/bin/m4 failed with exit status: 1

I have only access to autoconf-2.62 on my system here, Fuchur reports the errors also with 2.61.
Unfortunately, my knowledge of autoconf is too shallow to fix that errors.
(BTW: Wouldn't it be a good idea to move the implementation of the checks to acinclude.m4?)
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0000635)
zesstra   
2008-06-30 18:38   
Duplicate of 0000542

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
537 [LDMud 3.3] LPC Compiler/Preprocessor minor always 2008-05-04 11:56 2018-01-29 22:57
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version: 3.3  
Product Build: 3.3.714 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: Missing initialization of local variables in some cases
Description: There seems to be an issue with the initialization of local variables.
Assume the following code:

void test() {
  mapping m=(["bla": 100]);
  printf("Anfang: %O\n",m);
  object key;
  foreach (key, int val: &m) {
    val--;
  }
  printf("Nach FE: %O\n", m);
  int tmp=-1;
  printf("Ende: %O\n", m);
}

It produces the following output:
Anfang: ([ /* 0000001 */
  "bla": 100
])
Nach FE: ([ /* 0000001 */
  "bla": 99
])
Ende: ([ /* 0000001 */
  "bla": -1
])

The driver allocates the same space to variables val and tmp, because val does
not exist after the foreach() block. Unfortunately the svalue for the new tmp
is obviously not properly initialized. It is still of type T_LVALUE and the pointer u.lvalue in it still points to the svalue in the mapping which was assigned in the previous code block.
It does not happen if the declaration of the new variable is in another code
block, upon entering a code block the local variables are zeroed, because of
exactly this problem (prolang.<, line 6854.
Luckily, the bug only shows up in rare circumstances (at least in our lib), but it can be quite nasty to track.
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files: prolang.clearlocals.diff (7,820 bytes) 2008-05-07 14:41
http://ldmud.eu/file_download.php?file_id=121&type=bug
fix-clear-locals.patch (8,459 bytes) 2008-05-09 15:34
http://ldmud.eu/file_download.php?file_id=122&type=bug
Notes
(0000616)
Gnomi   
2008-05-07 14:46   
I uploaded a patch from Fuchur@Wunderland for this bug. It keeps track of these local variables that have to be initialized again and inserts additional F_CLEAR_LOCAL commands where appropriate.
(0000618)
Coogan   
2008-05-08 09:10   
This issue also affects driver version 3.2.15.
(0000619)
fufu   
2008-05-09 15:36   
(Last edited: 2008-05-09 15:37)
I've just uploaded my patch for this problem with Gnomi's changes included.
(The patch Gnomi uploaded applied on top of my initial patch.)

(0000715)
Gnomi   
2008-07-10 05:04   
Fixed in 3.3.717 (r2379).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
536 [LDMud 3.3] Efuns minor always 2008-04-07 06:23 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version: 3.3.713  
Product Build: 3.3.716-2363 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: strstr("", "") does not return 0.
Description: strstr("", "") yields -1, because of the following code in mstring_mstr_n_str:

    if (start >= mstrsize(pStr))
        return NULL;

if ptxt is "" and start <= mstrsize(pStr) then it should return pStr instead.

Greetings,
Gnomi.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0000718)
Gnomi   
2008-07-10 10:18   
Fixed in r2381 (same as r2358/Bug 0000509 now for strstr).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
534 [LDMud 3.3] Runtime minor always 2008-03-05 10:38 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3.713  
Product Build: 3.3.716-2363.U017 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: set_noecho calls the driver hooks with external==TRUE
Description: set_noecho calls the driver hooks with secure_callback_lambda, which is meant for reactions to external events. But set_noecho is sometimes also called from within an LPC program (with input_to or remove_input_to). So if that's the case and there is an error within the driver hook the eval_cost will get cleared (due to external==TRUE) and the calling program gets all its eval ticks back. But if there is a catch(), the eval count can even get below zero, which effectively aborts this thread (no catch holds, no error handling can happen).

Greetings,
Gnomi.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files: external_noecho.diff (8,231 bytes) 2008-07-11 05:21
http://ldmud.eu/file_download.php?file_id=142&type=bug
Notes
(0000723)
Gnomi   
2008-07-11 05:23   
I added a patch that adds an external flag to set_noecho and also to secure_apply (renaming it to secure_apply_ob and making an alias secure_apply without that parameter), so that the later is consistent to apply_master(_ob).
(0000741)
Gnomi   
2008-07-17 03:01   
Committed as r2391.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
532 [LDMud 3.3] Efuns crash always 2008-02-19 08:24 2018-01-29 22:57
Reporter: chaos Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.716  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: restore_value() segfaults on large inputs on 64-bit Debian; alloca() related
Description: Product version is actually 3.3.716 (Mantis only knows about 3.3.715).

On my amd64 Debian system, restore_value() will segfault if fed a sufficiently large input; attached file (uncompress first) will trigger the behavior. Error is:

0x00000000004a7dbf in f_restore_value (sp=0x67ef20) at object.c:9058
9058 memcpy(buff, get_txt(sp->u.str), len);
(gdb) print buff
$1 = 0x7fffd0904d40 <Address 0x7fffd0904d40 out of bounds>

This appears to be a failure of alloca() on this architecture; as a workaround I modified f_restore_value() to manage 'buff' using xalloc() and xfree() instead of alloca(), and this alleviated the problem.
Tags:
Steps To Reproduce:
Additional Information: Seems likely that other uses of alloca() may fail on large sizes.
Attached Files: alloca_test.c (320 bytes) 2008-02-19 12:35
http://ldmud.eu/file_download.php?file_id=115&type=bug
restore_value-2.diff (2,639 bytes) 2008-07-03 05:27
http://ldmud.eu/file_download.php?file_id=132&type=bug
restore_value-2a.diff (1,447 bytes) 2008-07-03 06:08
http://ldmud.eu/file_download.php?file_id=133&type=bug
Notes
(0000596)
chaos   
2008-02-19 08:28   
Please disregard in favor of next ticket; the file upload attempted with this one failed.
(0000597)
zesstra   
2008-02-19 12:26   
You may just attach your file to this ticket, no need to open a new one.

Yes, alloca() allocates memory on the stack and that is often limited to 8 MB by default, so its relatively "easy" to hit that limit.

Note that the check after the alloca() doesn't work on my machine as well. alloca() seems to happily allocate memory exceeding the stack limit for the process (without returning NULL) and upon accessing it or calling a function (which implicitly accesses the out-of-bounds stack now) the driver crashes.
According to the manpage its behaviour is machine and compiler dependent. (You can try the behaviour on your system with the very simple test program I will attach.)

One problems is: It is not very straight-forward to determine the already used stack size as there is no libc function for it, otherwise you could check beforehand if there is enough space on the stack + a safety margin. Therefore it is probably indeed a good idea to replace other alloca() as well or introduce a (rather low) limit for all alloca() (which may impair legitimate uses) and will not work if you heavily recursed and use already quite a lot of the available stack space.

Note: For MG we use a stack size limit of 128MB at the moment, because of such potential problems and the PCRE crash reported in 0000524, but that doesn't solve the basic problem.
(0000598)
zesstra   
2008-02-19 12:47   
Hmpf, I forgot: My system here is 32 bit based, it is definitely not a 64 bit issue. A quick search suggests that it is quite common for alloca() implementations not to return NULL upon out-of-stack-memory. From a BSD man page: "if the allocated block is beyond the current stack limit, the resulting behavior is undefined." I assume that on most systems this crash s reproducible.
(BTW: the man page on MacOS is just wrong. :-( )
(0000599)
chaos   
2008-02-19 14:11   
Additional data: I had suspected a 64-bit issue because the same data being processed by 3.2.15 restore_value() (also uses alloca()) on intel32 FreeBSD 5.4 works fine.

So, yeah, glibc's fault.
(0000600)
zesstra   
2008-02-19 14:25   
How large was that string and stack size limit you used there? alloca() on FreeBSD 5.4 may well behave the same behaviour, maybe the stack size limit was just bigger and you didn't hit the limit. At least FreeBSD 6.2 has the same behaviour according to its manpage. It says:
"The allocation made may exceed the bounds of the stack, or even go further into other objects in memory, and alloca() cannot determine such an error."

So I would check if either the stack limit was higher on your FreeBSD or if the process just didn't get killed and potentially overwrote stuff after/below the stack (on Linux that would be system/shared lib code, but I don't know how FreeBSD organizes the process' address space.
(The latter behaviour would be especially interesting as it may allow to inject code into the drivers process.)
(0000601)
zesstra   
2008-02-19 18:11   
I thought a little bit about my last note and tested the alloca() on 2 systems (MacOS 10.5 and Debian etch). Basically on both systems alloca() gave me any address in the virtual address space of the process I wanted to have. So you can write arbitrary data to arbitrary memory addresses in the driver's address space.
Of course, in practice you are limited by the possible size of the string to restore_value() (AFAIK LPC strings are only limited by the amount of memory available).
If you know the process image layout and where the systems shared libs are mapped and which memory areas are not write-protected, you may really be able to inject code remotely if you know what you do (I don't, that said.).
(simplified and quick example: in a small test program I expanded the stack into an address range allocated by the heap. That area is not write-protected so you can overwrite the data there or continue program execution (calling functions is possible because the system simply expands the stack happily further into the heap). Although simply overwriting the heap should be detected by the driver's memory allocator later, resulting in calling fatal().)

BTW, there are 69 calls to alloca(), some of them in efuns, probably one has to have a closer look at them, if they may be a problem. They contain checks for NULL pointers, but... *sigh*
(0000604)
chaos   
2008-02-20 14:09   
Re: your question about my FreeBSD environment, I don't know how to find out what stack size gcc sets up (I'm thinking that's the relevant stack size, rather than the LPC interpreter's stack). Google shows me articles which speak of the stack size being "unlimited" unless changed with ulimit, but we seem to be seeing that alloca() interacts with it in a way that doesn't cause it to expand when needed.

http://www.irccrew.org/~cras/security/howto/dynamic.html has commentary on alloca() that pretty much says that it's completely unsafe to use on any arbitrary or user-provided data, and portability-negative too.
(0000605)
zesstra   
2008-02-20 15:43   
I would say, the people on irccrew.org are right with that opinion.

And yes, I did not mean the LPC stack. ;-) It is, how much memory space your system wants to permit the process to use (obviously it does only weakly enforce it). You can find that out by executing 'ulimit -a' in your shell, there should be an entry "stack size", that is the maximum amount of memory the process started in that shell should use for the stack. (You can also change it with ulimit.)

Example:
On my system the memory of the process looks like this (system-dependent!):
-----<stack><stackguard>--------<syslibs>---------<heap><executable>
(all --- may be used for the heap, it grows from right to left here)
The <stackguard> is read and write protected, so any access there gets the process killed, if you extend the stack into to the <stackguard> area. If you manage to "jump" over it at get from alloca() an address where you can write, your process doesn't get killed.
Linux AFAIK even doesn't have this stackguard area, there stack and heap are next to each other, if that neighbouring heap area is allocated by your process, you may not even notice it for some time, if the stack grows into the heap.
(0000606)
chaos   
2008-02-20 15:51   
Okay. ulimit -a shows a stack size of 8192K on the Debian system and 65536K on the FreeBSD system, so that's consistent with observed behavior.
(0000611)
zesstra   
2008-05-06 14:22   
Yesterday Gnomi and me had a discussion about the use of alloca() in the driver.
Basically there seem to be 3 possibilities:
1) use alloca() only for small allocations (<200 byte) and only if it is guaranteed to be not more. Consequently change all other alloca() to xalloc().
2) There is a alloc.c in the driver source, using mempools to allocate memory and it reclaims storage allocated deeper in the stack. We might use this palloca() instead of alloca(). But I am not sure if it is finished yet.
3) continue to use alloca() but always check before if there is enough stack space left. This can be determined by using the initial stack pointer upon start-up, the current stack pointer, the direction in which the stack grows and RLIMIT_STACK from getrlimit().

2) and 3) have the advantage of not having to free the memory manually.
With 3) a function may still use a lot of stack space and potentially crash upon calling other functions.
1) may increase fragmentation of the heap and we have to keep in mind all return paths out of the function for freeing the memory.

Any favorites?
(0000661)
chaos   
2008-07-02 10:17   
(Last edited: 2008-07-02 10:17)
3) doesn't seem like a good idea; what will it do when there isn't enough memory on the stack, error out? Then lib code will error at random based on stack conditions, and a new unanticipated failure condition has been introduced into all the functions using alloca; seems very unfriendly. The only alternative I see to erroring out is switching to using xalloc, and then really you may as well have just used xalloc in the first place.

I can't really evaluate 2); if it's not clear that the function is finished, it sounds like it's going to be flaky.

So 1), the painful one, kinda sounds the best.

(0000665)
zesstra   
2008-07-02 19:11   
I still think, palloca() has some potential, but to have a fix ready for this one I just changed f_restore_value() to use xalloc/xfree for the buffer. I noticed 6 return paths in the function, if somebody reads the diff, please double-check that I did not miss one. ;-)
(0000666)
Gnomi   
2008-07-03 03:46   
restore_svalue might throw errors that abort through a longjmp. Mostly out of memory errors, but also on illegal array sizes (e.g. restore_value("0000001:0\n({" + "0,"*100000 + "})\n")). So I would recommend using the already existing error handler (restore_value_cleanup) to catch these.
(0000667)
fufu   
2008-07-03 05:30   
How about this?

We could cheat and use a global variable, but I'd rather eliminate those than introduce new ones.
(0000668)
Gnomi   
2008-07-03 05:40   
A global variable is not an option, because restore_value/object calls can be quite recursive (e.g. "#e:efun" can raise a privilege violation and the master can then call restore_value/object again).
(0000669)
zesstra   
2008-07-03 05:54   
Ok, had the same in mind after Gnomis comment, but had no time during the day.
I think using the restore_cleanup_t for transfering the address of buff is just fine.
There is IMHO one problem left, which I also missed in my first patch: buff is changed in line 9070: buff = p+1; We have to account for this and use the original address of the allocated memory for xfree and the cleanup structure.
(0000670)
fufu   
2008-07-03 06:09   
good point. I think the easiest solution is to check whether a version is there after setting up the error handler, see latest patch. (restore_value-2a.diff applies on top of restore_value-2.diff)
(0000671)
zesstra   
2008-07-03 07:04   
Looks good for me.
I wrote a small test yesterday, once the testsuite is available in SVN I could commit the test (although it heavily depends on the available stack memory, so it just feeds some 50MB of zeroes into restore_value()...).
(0000672)
Gnomi   
2008-07-04 07:47   
(Last edited: 2008-07-04 07:47)
Looks good for me too.

(0000684)
zesstra   
2008-07-08 16:53   
Fuchur, do you want to apply your patches yourself?
(0000701)
fufu   
2008-07-09 09:19   
(Zesstra) Fuchur, do you want to apply your patches yourself?
Done now, see SVN revision 2377.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
528 [LDMud 3.3] Portability minor always 2008-01-27 17:04 2018-01-29 22:57
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: sprintf() fails to print int values larger than 2^32 - 1 correctly
Description: sprintf() assumes that LPC ints (T_NUMBER) are 32-bit ints and wraps at 2^31 to negative values and then again after 2^32 and so on and therefore truncates all values to the range of -2147483647 and 2147483647.
Tags:
Steps To Reproduce: printf("%d\n", __INT_MAX__) on 64-bit platforms.
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files: sprintf_64bit-V2.diff (1,957 bytes) 2008-05-02 17:38
http://ldmud.eu/file_download.php?file_id=118&type=bug
Notes
(0000610)
zesstra   
2008-05-02 16:44   
sprintf.c uses for T_FLOAT und T_NUMBER in most cases the system sprintf. Unfortunately, that needs a length modifier for long int ('l') and long long int ('ll'). I added some precompiler logic in string_print_formatted() around line 2314 to add 'l' or 'll' depending on the size of p_int (u.number in svalue).
That works, but has to 2 issues:
First it introduces stuff from port.h to sprintf.c, it would be nicer to keep that portability defines in port.h. Though I not sure, if it is practicable.
Second and more important, the format_char can be 'c' as well and '%lc' signifies a wide char wint_t. It would be needed to change that part of string_print_formatted() to use the 'l' and 'll' length mods only for integral conversions (d, i, o, u, x, or X). I still have to do that and it is sadly an additional runtime decision.
(0000613)
zesstra   
2008-05-06 15:32   
sprintf_64bit-V2.diff should fix the 2 obvious issues with sprintf() concerning 64-bit Ints and %d, %i, %x and %O.
1) change num_add(..., int num) to num_add(..., p_int num)
2) add 'l' or 'll' to %d, %i, %x (but not %c) before passing them on to the system lib.

There are still a lot of warnings "implicit conversion shortens 64-bit value into a 32-bit value" in sprintf.c left and some of them might well be a bug. But they have to wait for another patch.
(0000762)
zesstra   
2008-09-06 18:19   
Fixed in r2413.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
524 [LDMud 3.3] Implementation crash always 2008-01-21 04:09 2018-01-29 22:57
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: Crash in PCRE-RegExp efuns due to excessive recursion
Description: The function match() in the PCRE package is highly recursive. Depending on the string and the regular expression it can recurse thousands of times.

Something like
regmatch("aaa bbb ccc"*1000,"a{1,2}(\n|.)+cc",RE_PCRE|RE_MULTILINE|RE_MATCH_SUBS,0)
causes the driver to crash with a segmentation fault (EXC_BAD_ACCESS).
I had a quick look at the core dump, there were some 18k frames on the stack. Basically, match() recursed until it reached the stack size limit (8 MB at that time) of the OS and the process was killed.
Raising the limit to 16MB solved the problem for this regmatch call, but it doesn't solve the general problem. Using the maximum stack size of 64MB on my machine required just a longer string, until the stack was filled with 144k frames ;-)
There should definitely be some safeguards (other than eval costs) for preventing to crash the driver in this way, you never know when someone puts a whole file in a RegExp-Efun or even tries to deliberately crash the driver.

I briefly thought about solutions:
1. configure the PCRE code with NO_RECURSE not to use recursions but a
   private stack on the heap, but it is noticeably slower then and we would
   have to set 2 function pointers for using the driver memory allocation
   handler instead of standard malloc. Additionally, allocating an indefinite
   amount of memory on the heap for match() only reduces the problem.
2. limit the size of the strings to match. This is probably a sane thing, but
   may be difficult as the amount of recursions also depend on the pattern
   and one would have to set the limit suitable to the given stack size
   limit.
3. change the PCRE code to keep track of the stack size and abort the
   process with a PCRE_ERROR_xxx if it approaches the stack size limit. The
   calling RegExp efuns could then throw an error. Don't know if there is
   a library/system call for finding the current stack size...
   On could calculate it from the current stack pointer and the stack base
   adress, but... *sigh*
4. check for updates of PCRE with improved recursion behaviour.
5. ... ?
Tags:
Steps To Reproduce: regmatch("aaa bbb ccc"*1000,"a{1,2}(\n|.)+cc",RE_PCRE|RE_MULTILINE|RE_MATCH_SUBS,0)
Additional Information:
Attached Files: pcre_limit.diff (6,694 bytes) 2008-01-25 06:40
http://ldmud.eu/file_download.php?file_id=113&type=bug
pcre_limit_v2.diff (6,722 bytes) 2008-04-01 05:18
http://ldmud.eu/file_download.php?file_id=116&type=bug
Notes
(0000580)
zesstra   
2008-01-21 05:28   
Ok. There already is some way to limit the recursions in PCRE. ;-) And the driver even uses it, but...
The specific lines are 679 and 742 in mregex.c:
pHints->match_limit = max_eval_cost - eval_cost - 1;

This is far too much for the match limit, I think. We have 1.5MTicks as Eval cost limit in MorgenGrauen right now, but even 100k would be enough for the standard stack size limit of 8M.

I would suggest to limit 'match_limit' to a maximum defined either at compile time or some run-time defined value which takes the current stack size limit into account in some way. (Unfortunately, PCRE limits the number of recursions, but not the used stack size, so we have to assume some values for 'used size per recursion' here.)
(Of course, if there are less eval ticks available than this maximum amount of recursions, we should use the available ticks.)

Additionally there are cases (if pHint is not present), where there is no match_limit set. We should either change them or define some sane maximum in PCRE's config.h. In fact, the regmatch() call here doesn't have any match_limit set and defaults then to 10000000 from pcre/config.h.
(0000581)
Gnomi   
2008-01-21 05:53   
At home I have 1008 bytes per recursion, on the UNItopia machine it is 592 bytes per recursion (both are Debian packages of PCRE 7.4, but different Debian releases).
(0000582)
zesstra   
2008-01-21 06:10   
Mhmm. Interesting difference.
I just found a curious thing: as I said, in my regmatch() case there was no pHints present and therefore no specific match_limit. pHint is generated by pcre_study() in pcre/study.c but despite various RegExp I could not get a single case, where pcre_study() actually returned a non-zero pHints. I could be wrong, but at least here pHints->match_limit seems to be never set.
If we want to use that mechanism we have to set either the global maximum or make sure, there is an initialized pHints member in the RegExp struct.
(0000583)
zesstra   
2008-01-21 07:15   
BTW: My tests here at home were done with the built-in PCRE package, configure does not seem to use/find my system pcrelib. Anyway, it eases debugging. ;-)
I had a look at the newer PCRE versions. Most recent version is 7.5, the driver ships with 4.5. According to the changelog there were some improvements in saving stack space. Additionally, they have now a MATCH_LIMIT_RECURSION which limits the recursion depth of match() while MATCH_LIMIT limits the overall number of calls to match().
An update of the built-in PCRE would be nice, unfortunately, the changes to the PCRE package seem to be quite extensive.
I think, we should make sure each call to pcre_exec() has a sane match_limit or match_limit_recursion set instead of setting the global compile-time maximum, because that way only works while the built-in copy of PCRE is used.
(0000584)
zesstra   
2008-01-25 06:41   
I assembled a patch for limiting the recursions in match(), which introduces
the following changes:
* ensure a initialized pHints section after call to pcre_study() in
  rx_compile()
* set a limit for match in rc_exec() if PCRE_RECURSION_LIMIT is defined.
  If we use a newer libpcre with support for PCRE_EXTRA_MATCH_LIMIT_RECURSION
  we use that, otherwise PCRE_EXTRA_MATCH_LIMIT
* set RE_ERROR_BACKTRACK to PCRE_ERROR_RECURSIONLIMIT if defined or
  PCRE_ERROR_MATCHLIMIT otherwise
* I did not make PCRE_RECURSION_LIMIT changeable at run-time. Increasing it
  would anyway only make sense if you increase the stack size limit of the
  driver process.
* I removed the dependence of the recursion limit on the remaining
  eval_costs, sensible recursion limits on most systems would probably
  be in the range of 10k - 20k recursions.
* added PCRE_RECURSION_LIMIT to configure.in with a default of 7000.
* added PCRE_RECURSION_LIMIT to config.in with a describing comment

The default limit is a conservative guess, I think. Gnomi and me had for
several versions and compilations of the libpcre frame sizes between 466
and 1008 bytes and I assume a default 8M for the stack size limit.

Several things could still be improved, but I don't know if that is needed,
they are more or less complicated to do:
* make PCRE_RECURSION_LIMIT run-time configurable, a pre-defined LPC define
  or include it in query_limits()
* update the built-in pcre package (would be a good idea, but I don't have
  time for that at the moment)
* don't limit the number of recursions, but the amount of stack space used.
  That would require a patch for libpcre itself and is probably not
  feasible
* calculate the recursion limit dynamically in rx_exec(), depending on the
  stacke size limit (getrlimit()) and the already consumed stack space
  (not straight-forward, there is no libc function for that, one would
   have to calculate it from the top and bottom of the stack)
* PCRE_RECURSION_LIMIT has a small chance of provoking a name clash with
  the libpcre defines in the future. It may be reasonable to rename it to
  something like LD_PCRE_RECURSION_LIMIT

Comments, Complaints, Requests welcome. ;-)
(0000602)
Gnomi   
2008-02-20 08:21   
In the patch when allocating a new pcre_extra structure pHints->flags should be set to zero, otherwise pcre may crash later.
(0000603)
zesstra   
2008-02-20 09:27   
Hmpf. Right. I will update the patch soon, thank you.
I was probably thinking of calloc from ptmalloc which zeroes out allocated memory. or simply forgot it. *g*
But, I still don't like the patch very much, because it is completely static and doesn't take into account the current stack usage. Maybe it would really be better to check the stack size first (get_stack_direction() in xalloc.c in fact keeps track of (more or less) the beginning of the stack, don't know if it is worth to add some get_stack_size() function there?)
(0000607)
zesstra   
2008-04-01 06:01   
Of course I forget this issue again for some time. ;-) Remembered it this morning and added the initialisation of pHints->flags. New patch is pcre_limit_v2.diff.
(0000614)
zesstra   
2008-05-06 15:49   
As I wrote, my current patch has the disadvantage, that it is static. Therefore the driver can still crash if the recursion is already quite deep before executing the RegExp and a low limit may prevent legimate RegExps from being executed correctly.
I could add functions in xalloc.c (because there the stack direction is already known) to find out about the current stack usage und the remaining space. Then the Regexp package can limit to recursions dynamically (but with the assumption that one recursion takes about 1k of stack space).
Is there any interest for that approach?
(0000639)
Gnomi   
2008-07-01 04:50   
I can live with the static limit. The dynamic limit would be an approximation as well (because we can't determine the needed stack space per recursion), as LPC has a recursion limit (80 in UNItopia), which should never exceed half of the stack space, I can give PCRE the other half of the stack and that should suffice.
(0000673)
zesstra   
2008-07-07 05:39   
True enough. I will go for the static limit, if there are too many problems, we can still change it. Maybe I will expand the comment about the limit a little bit to clarify that users have to choose according to the available stack size and that they should choose suitable for worst conditions (max. LPC recursion, when executing a PCRE).
BTW: Testcase in SVN, r2374.
(0000674)
zesstra   
2008-07-07 17:37   
This should be fixed by r2375. In case of problems with the static limit (or something else), please re-open.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
523 [LDMud 3.3] Runtime feature always 2008-01-04 19:43 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3  
Product Build: 3.3.716-2363 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: The "object to closure was bound to has been destructed" errors shouldn't occur anymore
Description: As closures referencing destructed objects should be handled as zeroes there should be no "object to closure was bound to has been destructed" errors.

They still occur with ERQ callbacks and could be circumvented there with a check_object call. But why not remove this error entirely and let call_lambda just return a zero on the stack?

Greetings,
Gnomi.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0000713)
Gnomi   
2008-07-10 04:18   
Any objections to the entire removal of this error message?
(0000714)
zesstra   
2008-07-10 04:59   
No, I agree, that this condition should be treated consistently.

BTW: Could we change check_object from a define to a static inline function? There is no difference in the code modern compilers generate, but it is beneficial for debugging.
(0000742)
Gnomi   
2008-07-17 03:53   
Done as r2392.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
520 [LDMud 3.3] Runtime minor N/A 2007-10-12 15:25 2018-01-29 22:57
Reporter: zesstra Platform:  
Assigned To: lars OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.716  
    Target Version:  
Summary: Overflow of apply_cache_hit, apply_cache_miss causing wrong statistics
Description: 'status tables' gave me the following info about the apply cache:
Apply Cache:
------------
Calls to apply_low: 4042499944
Cache hits: 3902887001 (155.30%)

apply_cache_hit and apply_cache_miss in interpret.c|h are of type p_int and outputted as unsigned long in the 'status' command. Obviously, 'signed long' (p_int) overflowed.
For both variables only positive values are of interest, therefore I suggest to change their type to p_uint (s. attached patch).
Of course, this doesn't solve the overflow problem. ;-) A possibility may be to decay both values by a constant factor from time to time, e.g. in a function like wiz_decay() called by the backend. Any opinions on this?
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: apply_cache.diff (874 bytes) 2007-10-12 15:26
http://ldmud.eu/file_download.php?file_id=112&type=bug
Notes
(0000567)
lars   
2007-10-14 01:30   
Implemented the patch. If overflows continue to be a problem, we may want to move to a gigahit/hit counter approach (like we do with VM ticks).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
517 [LDMud 3.3] Runtime crash sometimes 2007-09-19 15:10 2018-01-29 22:57
Reporter: zesstra Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.716  
    Target Version:  
Summary: Crash in remove_mapping()
Description: Morgengrauen crashed this afternoon after a nice long uptime with 3.3.714. ;-)
The crash occured in remove_mapping() in mapping.c:1401 by calling fatal() ("Mapping entry didn't hash to the same spot.")
find_map_entry() found an entry in the hash part (searching the hash of the given map_index), but remove_mapping() itself wasn't able to find it using the hash of 'entry' (returned from find_map_entry).

LPC-Stacktrace was:
2007.09.19 15:54:20 Mapping entry didn't hash to the same spot.
2007.09.19 15:54:20 Current object was players/nibel/demon/master/dmaster
2007.09.19 15:54:20 Dump of the call chain:
' ParseLine' in ' obj/tools/MGtool.c' ('obj/tools/MGtool#5887724') line 1509
' CallFunc' in ' obj/tools/MGtool.c' ('obj/tools/MGtool#5887724') line 1617
' Xcall' in 'obj/tools/MGtool.c (/obj/tools/MGtool/toolcmd.c)' ('obj/tools/MGtool
#5887724') line 63
' CATCH' in ('obj/tools/MGtool#5887724')
' eval' in 'players/nibel/.tool.lpc.c' ('players/nibel/.tool.lpc') line 8
' StopPhase5' in 'players/nibel/demon/master/dmaster.c' ('players/nibel/demon/master/dmaster') line 315

StopPhase5() was this code snippet:
public int StopPhase5() {
  if(!Sec()) return -1;
  while(remove_call_out(#'TimerPhase5A) != -1);
  while(remove_call_out(#'TimerPhase5B) != -1);
  filter_objects(m_indices(npcs["worm"] - ([0])), "die");
  npcs["worm"] = ([]);
  return ShoutPlane("Der Strom neuer Wuermer versiegt.\n"),1;
}

Of course, this subtraction of ([0]) is in case of mappings not necessary to remove destructed object(key)s, but it should crash either.
I can reproduce that crash. remove_mapping() crashes sometimes, if you have a mapping with objects as Keys, destruct an object and subtract ([0]) from the mapping (see steps to reproduce).
I am not yet certain, what exactly happens, but hopefully I am able to look into the details soon.
Tags:
Steps To Reproduce: Create the following program and load it.
Call Stop() until it crashes, e.g. xdo 50#xcall test->Stop().
Repeat if necessary, in rare cases it does not crash in my homemud.

mapping m=([]);

void create() {
    seteuid(getuid());
    foreach(int i: 20) {
      object ob=clone_object("/obj/seil");
      ob->move("/room/void",M_NOCHECK);
      m+=([ob:"bla"]);
    }
}

public int Stop() {
  object *ind;
  ind=m_indices(m);
  destruct(ind[random(sizeof(ind))]);
  m = m - ([0]);
  return 1;
}
Additional Information: Stack trace:

#0 fatal (fmt=0x810cb58 "Mapping entry didn't hash to the same spot.\n") at simulate.c:586
0000001 0x080b3c54 in remove_mapping (m=0x207ccf34, map_index=<value optimized out>) at mapping.c:1401
0000002 0x080b28dd in walk_mapping (m=0x16e11bb0, func=0x80b3ca0 <sub_from_mapping_filter>, extra=0x207ccf34) at mapping.c:1971
0000003 0x080b3533 in subtract_mapping (minuend=0x207ccf34, subtrahend=0x16e11bb0) at mapping.c:3422
0000004 0x08095c5b in eval_instruction (first_instruction=0x208904b2 "an\002", initial_sp=0x813eec0) at interpret.c:10247
0000005 0x080a1ea1 in apply_low (fun=0x11e9723c, ob=0x1ac5c570, num_arg=0, b_ign_prot=0, allowRefs=0) at interpret.c:16811
0000006 0x080a280a in int_apply (fun=0x11e9723c, ob=0x1, num_arg=0, b_ign_prot=0, b_use_default=1) at interpret.c:16889
0000007 0x0808fe88 in eval_instruction (first_instruction=0x2242d66e "a\036", initial_sp=0x813eea8) at interpret.c:16159
0000008 0x080a1ea1 in apply_low (fun=0x967150c, ob=0xb5b26bc, num_arg=3, b_ign_prot=0, allowRefs=0) at interpret.c:16811
0000009 0x080a280a in int_apply (fun=0x967150c, ob=0x1, num_arg=0, b_ign_prot=0, b_use_default=1) at interpret.c:16889
0000010 0x0808fe88 in eval_instruction (first_instruction=0x28261e63 "a\036\001\n>\036\002\b\003a\b\003\a\020b»b{\f(´b{\a)\002\f{\n)\036\aj\017a\n=\036\a\020K*nx",
    initial_sp=0x813ee78) at interpret.c:16159
0000011 0x080e7350 in catch_instruction (flags=0, offset=21, i_sp=0x81b4c04,
    i_pc=0x28261e63 "a\036\001\n>\036\002\b\003a\b\003\a\020b»b{\f(´b{\a)\002\f{\n)\036\aj\017a\n=\036\a\020K*nx", i_fp=0x813ee10, reserve_cost=4000, i_context=0x0)
    at simulate.c:447
0000012 0x0808bf35 in eval_instruction (first_instruction=0x28261d3a "`\001\fanN", initial_sp=0x813ee70) at interpret.c:9381
0000013 0x080a1ea1 in apply_low (fun=0xa21bc70, ob=0x1350ed60, num_arg=1, b_ign_prot=0, allowRefs=0) at interpret.c:16811
#14 0x080a280a in int_apply (fun=0xa21bc70, ob=0x1, num_arg=0, b_ign_prot=0, b_use_default=1) at interpret.c:16889
#15 0x0808fe88 in eval_instruction (first_instruction=0x282676be "`\001\003a\ff\036", initial_sp=0x813edd0) at interpret.c:16159
#16 0x080a1ea1 in apply_low (fun=0xa20bc38, ob=0x1350ed60, num_arg=1, b_ign_prot=0, allowRefs=0) at interpret.c:16811
#17 0x080a280a in int_apply (fun=0xa20bc38, ob=0x1, num_arg=0, b_ign_prot=0, b_use_default=1) at interpret.c:16889
#18 0x080a4799 in sapply_int (fun=0xa20bc38, ob=0x1350ed60, num_arg=1, b_find_static=0, b_use_default=1) at interpret.c:17050
#19 0x0804bca9 in parse_command (buff=0xbf8cad66 "xcall dmaster->stopphase5()", from_efun=0) at actions.c:1098
#20 0x0804ddaf in execute_command (str=0xbf8cad66 "xcall dmaster->stopphase5()", ob=0xe79bb10) at actions.c:1258
#21 0x08054612 in backend () at backend.c:671
#22 0x080b2435 in main (argc=Cannot access memory at address 0x0
) at main.c:615

I will attach the full stacktrace. A core dump is available, but I had only time for a short glance yet.
Attached Files: stack (9,525 bytes) 2007-09-19 17:12
http://ldmud.eu/file_download.php?file_id=107&type=bug
destructedkeys.diff (3,310 bytes) 2007-09-19 20:21
http://ldmud.eu/file_download.php?file_id=108&type=bug
destructedkeys_v2.diff (4,169 bytes) 2007-09-19 20:46
http://ldmud.eu/file_download.php?file_id=109&type=bug
Notes
(0000543)
Gnomi   
2007-09-19 20:54   
m = m - ([0]) creates a shallow copy of the mapping (via copy_mapping as an alias for resize_mapping()). But resize_mapping() requires that check_map_for_destr() is called before, because otherwise assign_svalue_no_free would zero out destructed objects even if they are a key in the mapping. Two uses of copy_mapping() don't do this (inl_copy_svalue_no_free and subtract_mapping) and that's why the number 0 shows up in a hash chain where it doesn't belong.

I attached a patch to make resize_mapping aware of destructed object references as keys, alternatively you could just call check_map_for_destr() in inl_copy_svlaue_no_free and subtract_mapping.

Greetings,
Gnomi.
(0000546)
lars   
2007-10-01 02:14   
Resolved with Gnomi's v2 patch.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
514 [LDMud 3.3] Runtime minor always 2007-09-10 18:01 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: lars OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3.713  
Product Build: 3.3.714 Build 2307 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: remove_shadow_actions and remove_action don't handle shadow actions very well
Description: Hi,

remove_shadow_action assumes, that the shadow is the only shadow and that there are no shadows between it and the underlying object. But should go through the shadowing list till the underlying object just as add_action does.

remove_action doesn't work with actions by shadows at all, that means, only the underlying object can remove such an action, not the shadow itself. Because it searches for an action by the shadow, not by the underlying object.

I attached a patch, that should fix both issues. I left remove_action backward compatible in that manner, that the underlying object can still remove actions from its shadows (but shadows can only remove their actions).

Greetings,
Gnomi
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files: removeshadowaction.diff (1,767 bytes) 2007-09-10 18:01
http://ldmud.eu/file_download.php?file_id=104&type=bug
Notes
(0000575)
lars   
2007-11-11 18:24   
Added the patch - Thanks!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
513 [LDMud 3.3] Runtime minor always 2007-09-10 17:06 2018-01-29 22:57
Reporter: zesstra Platform:  
Assigned To: lars OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.716  
    Target Version:  
Summary: Errormessage from errorf() may be leaked
Description: Recently we had a garbage collector run, which revealed several memory leaks. I was able to associate one of these leaks to errorf(), which seems to leak the error message unter some very specific circumstances (see below for instructions).

2007.09.10 22:46:42 --- Garbage Collection ---
2007.09.10 22:46:43 GC pass 1: Freed 1 objects.
freeing small block 0x04092440 (user 0x04092448) simulate.c 801
  By object: secure/error
  By program: secure/error.c line:3
0409245c: 02 00 00 00 00 00 00 00 06 00 00 00 00 00 2a 65 ..............*e
0409246c: 67 61 6c 0a 00 0d 03 00 11 06 00 38 ab d8 58 ab gal........8..X.
0409247c: 74 d4 5a 05 15 00 00 t.Z....

freeing small block 0x03041ecc (user 0x03041ed4) simulate.c 801
  By object: players/zesstra/test
  By program: players/zesstra/test.c line:37
03041ee8: 02 00 00 00 00 00 00 00 0f 00 00 00 00 00 2a 77 ..............*w
03041ef8: 69 72 6b 6c 69 63 68 20 65 67 61 6c 0a 00 00 01 irklich egal....
03041f08: b2 08 00 38 08 3c 09 71 00 5a 2d 04 bd 05 00 ...8.<.q.Z-....

2 small blocks freed
2007.09.10 22:46:43 GC freed 0 destructed objects.

The leaked blocks were allocated by
  string_t * str = new_mstring(emsg_buf);

Tags:
Steps To Reproduce: Ok, please consider the following objects:
/players/zesstra/test.c:
mixed test() {
  catch(raise_error("wirklich egal\n");publish);
}

/secure/error.c:
mixed LogError() {
  raise_error("egal\n");
}

/secure/master.c:
protected void runtime_error(...) {
...
    catch(call_other("/secure/error","LogError",
      err,prg,curobj,line,culprit,caught);publish);
...
}

Now call /players/zesstra/test->test() and initiate the garbage collector run. The result in the garbage collector log should be something like the memory dump given above.
Please note, that the error during the catch() in runtime_error() is important, without it there is no leak.
Additional Information:
Attached Files: catchleak.diff (6,670 bytes) 2007-09-14 19:36
http://ldmud.eu/file_download.php?file_id=106&type=bug
Notes
(0000540)
zesstra   
2007-09-10 17:10   
Hngl. For anybody missing the instructions how to reproduce the leak, please switch to the advanced view of the bug report, without it the report ist pretty much useless. ;-)
(0000542)
Gnomi   
2007-09-14 19:44   
The problem is one global variable catch_value that is overwritten in the nested call to errorf(). In the example there are three writes to that variable (1x "*wirklich egal\n" and 2x "*egal\n", because LogError() invokes runtime_error twice), the innermost catch() reads the variable and sets it back to T_INVALID, both outer catch()es get then T_INVALID as their result. Two of these three strings are leaked by then.

I uploaded a patch that should fix this issue. I put this variable catch_value into the catch_context, so each catch() gets its own instance of it.

Greetings,
Gnomi.
(0000563)
lars   
2007-10-07 18:50   
I implemented the patch as given. Thanks!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
512 [LDMud 3.3] Efuns feature always 2007-09-01 21:12 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3.713  
Product Build: 3.3.714-2314 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: write_file with flag 1 should not complain if the file doesn't exist
Description: Hi,

when write_file is instructed to remove the file first an error "Could not remove filename: errno 2." is thrown if the file didn't exist. This makes this feature impractical, because then you have to check whether the file exist and shouldn't pass the flag if it doesn't. But then you could also do a rm() before, it doesn't complain about the non-existence of the file.

So I would suggest not to throw this error if errno == ENOENT.

Greetings,
Gnomi
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0000539)
zesstra   
2007-09-02 05:12   
Yes, I fully agree on that, it would be nice to change this behaviour.
(0000722)
Gnomi   
2008-07-11 02:35   
Done in 3.3.717 (r2383).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
511 [LDMud 3.3] LPC Compiler/Preprocessor minor always 2007-08-28 09:49 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: lars OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version:  
Product Build: 3.3.714-2314 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.716  
    Target Version:  
Summary: Lfuns implementing Inline closures should be 'private nomask'
Description: Hi,

when using new inlines the lfuns implementing them are public (unless overridden with a 'default' statement).

In 3.2.9-dev.332/3.3.97 in the old implementation they all got 'private nomask', because you should only call the function with the closure, not another way (especially not rely on the function name). 'nomask' was dropped in 3.2.9-dev.334/3.3.99, because the driver could not handle two inherited private nomask functions with the same name, but that's not true anymore for 3.3.

So in my opinion lfuns implementing old inlines should be nomask, too, and new inlines should become private and nomask (regardless of any 'default' statement).

Greetings,
Gnomi

PS: I attached a patch that we use in UNItopia, so it's for new inlines only, but the other case is just as trivial. :-)
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files: privinlines.diff (548 bytes) 2007-08-28 09:49
http://ldmud.eu/file_download.php?file_id=103&type=bug
Notes
(0000538)
Gnomi   
2007-08-28 09:57   
This bug report should have been for LDMud 3.3, not 3.2.
(0000553)
lars   
2007-10-06 21:46   
For 3.2 and the old inline closures in 3.3 this was actually no longer a problem - some earlier change
had already made them 'private nomask' again.

For the new kind, the patch went in with revision 2334 (in case we need to back it out again after all).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
510 [LDMud 3.3] LPC Compiler/Preprocessor minor always 2007-08-23 05:20 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: lars OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3  
Product Build: 3.3.714-2314 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: Wrong linenumber information after two inline closures in the same function
Description: When inserting pending inline closures it is assumed, that stored_line (the line where the line number information leads to) is at the current line in the file, so that some LI_BACK entries have to be inserted. Usually the store_line_number_info() call at the beginning of the loop in insert_pending_inline_closures takes care of that. But store_line_number_info updates stored_line only when some bytes were inserted into the program code. In 3/4 of the cases this happens because of the inserted bytes for alignment. For the remaining fourth wrong line number information will be generated.

So at the beginning of the loop it should be also checked whether forward steps are necessary. A attached a patch that fixes this.

Greetings,
Gnomi.
Tags:
Steps To Reproduce: Loading the following file shows the division by zero error at line 16 (at not 23).

string fun()
{
    map(({}),(: $1+0 :))
      
      
        ;

   foreach(mapping m:

        filter(({}),(: $1 :)))

   {

      1+1;

   }

}

void create()
{
   0/0;
}
Additional Information:
System Description
Attached Files: prolang.linecounting.diff (984 bytes) 2007-08-23 05:20
http://ldmud.eu/file_download.php?file_id=102&type=bug
Notes
(0000577)
lars   
2007-11-11 18:36   
Resolved - thanks for the patch.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
509 [LDMud 3.3] Efuns minor always 2007-08-11 09:31 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: lars OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3  
Product Build: 3.3.714-2314 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: strrstr doesn't find a pattern, when die string length is given as the start position
Description: strrstr("abcdef","b",6) returns -1, but should return 2. I think in mstring_mstr_rn_str there is such a leftover from mstring_mstr_n_str.

Greetings,
Gnomi.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0000576)
lars   
2007-11-11 18:32   
Yep, the check for the length had been copied unchanged from strstr().

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
508 [LDMud 3.3] LPC Compiler/Preprocessor minor always 2007-08-07 05:40 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: lars OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3  
Product Build: 3.3.714-2314 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: There is an off-by-one in the linenumbers in include files using auto-include-strings
Description: Hi,

consider the following files:

-- oneoff.c ---
#pragma BeginC
#include "oneoff.inc"
#pragma EndC


-- oneoff.inc ---
#pragma IncFile

And an auto-include hook return "#pragma AutoInc-IncFile\n" or "#pragma AutoInc-CFile\n" depending on whether it is the main file or an included file.
These pragmas are just for giving warnings with the current line number.
Compiling oneoff.c gives the following result:

Warning: w/gnomi/oneoff.c (auto include) line 1: Unknown #pragma 'AutoInc-CFile'
Warning: w/gnomi/oneoff.c line 1: Unknown #pragma 'BeginC'
Warning: w/gnomi/oneoff.inc (auto include) line 2: Unknown #pragma 'AutoInc-IncFile'
Warning: w/gnomi/oneoff.inc line 0: Unknown #pragma 'IncFile'
Warning: w/gnomi/oneoff.c line 3: Unknown #pragma 'EndC'

The linenumbers in oneoff.c and its auto include string are correct, but not these from oneoff.inc. The auto include string should start at line 1 not 2, and lineoff.inc should start at line 1 and not 0.

The linenumber within the auto include string is one too high because the #include statement (in handle_preprocessor_statement()) will increment the linenumber after having handled the include stuff, and add_auto_include is not aware of that.

The linenumber within the include file itself is one too low because the linenumbering for include files starts at zero (because the #include will increment it afterwards), for the main file it starts at one. add_auto_include() increments it, to make it correct for include files (because the #incude will now increment the linenumber of the auto include string and not of the include file itself), but the CHAR_EOF handling in yylex1 will decrement it to counteract the incrementation for the main file.

I attached a diff that fixes this. I removed the linenumber adjustment in the CHAR_EOF handling and let add_auto_include() increment the linenumber just once, either before or after starting the auto include string depending on whether we are in the main file or include file.

Greetings,
Gnomi.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files: incoffbyone.diff (1,698 bytes) 2007-08-07 05:40
http://ldmud.eu/file_download.php?file_id=101&type=bug
Notes
(0000578)
lars   
2007-11-11 18:39   
Thanks for the patch!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
505 [LDMud 3.3] Implementation minor always 2007-06-27 16:41 2018-01-29 22:57
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: 3.3.714 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: tell_room() does not send to 'room' itself, only the contained objects
Description: tell_room() sends the message only to objects contained in 'room', unlike say(), which sends the message also the environment itself, if suitable (interactive or living).
Some wizard build containers/rooms/environments which are marked as living and define catch_tell(). In that cases, it would be very nice, if tell_room() and say() would have the same behaviour.
Tags:
Steps To Reproduce: Define catch_tell() in /room/room1.c and call enable_commands() in its create() and call tell_room("/room/room1","bla").
Additional Information: In object.c:
e_say() adds the environment to the list of recipients, e_tell_room() does not. The attached patch for e_tell_room() adds 'room' to the list of recipients, if 'room' is interactive or marked as living.
Attached Files: tell_room.patch (1,676 bytes) 2007-06-27 16:41
http://ldmud.eu/file_download.php?file_id=100&type=bug
Notes
(0000641)
Gnomi   
2008-07-01 05:14   
ACK. (Except for the codestyle. ;-)
(0000729)
zesstra   
2008-07-16 15:56   
Changed codestyle ;-) and applied in r2389.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
504 [LDMud 3.3] Compilation, Installation major always 2007-05-04 18:06 2018-01-29 22:57
Reporter: lynx Platform:  
Assigned To: lars OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.716  
    Target Version:  
Summary: old macro breaks compilation on nexenta solaris
Description: The historically superceded PROT() macro is no longer provided, but
my-rusage.h and files.c still use it.

When compiling on Solaris, or whatever Nexenta is, the compilation
process breaks.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000559)
lars   
2007-10-07 00:25   
All these years, nobody had noticed these leftovers :-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
503 [LDMud 3.3] Runtime major always 2007-04-25 19:02 2018-01-29 22:57
Reporter: zesstra Platform:  
Assigned To: lars OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.713  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.716  
    Target Version:  
Summary: foreach() with negative integer expression causes "endless" loop
Description: foreach(int i: -1) printf("%O",i);
loops as long as there are evaluation ticks left:
"...6503186504186505186506186507186508186509186510186511186512186513186514186515186516186517186518186519186520186521186522186523186524186525186526186527186528186529186530186531186532186533186534186535186536186537186538186539186540186541Error: Too long evaluation. Execution aborted."
Tags:
Steps To Reproduce:
Additional Information: I will probably look into the source during the next days and try to write a suitable patch.
Attached Files: foreach.patch (446 bytes) 2007-04-29 17:36
http://ldmud.eu/file_download.php?file_id=98&type=bug
foreach2.patch (460 bytes) 2007-04-29 18:01
http://ldmud.eu/file_download.php?file_id=99&type=bug
Notes
(0000531)
zesstra   
2007-04-29 17:47   
Ok, this is a tiny patch for interpret.c which just checks 'count' in CASE(F_FOREACH) if the argument is of type T_NUMBER. If 'count' is negative, it throws an error via ERRORF().
One could argue that the original behaviour is not a bug and just a possibility to iterate over a larger integer range than 0 - MAX_INT. But I think, that isn't a very realistic scenario. Most often, a negative integer as range expression is just not intended and therefore I would prefer to not accept it.
BTW: Another possibility is to silently correct a negative 'count' to 0 and only issue a warning, but I would definitely prefer a real error as this situation anyway leads to a 'too long evalution' error.
(0000560)
lars   
2007-10-07 00:40   
Yup, makes sense.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
500 [LDMud 3.3] Runtime crash always 2007-01-30 15:45 2018-01-29 22:57
Reporter: zesstra Platform:  
Assigned To: lars OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.713  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.716  
    Target Version:  
Summary: load_object() may lead to a crash if given an empty string
Description: load_object() and lookfor_object() do not check, if the received string is an empty string. They won't find a corresponding object and eventually load it via load_object(). If there is a file /.c in the mudlib, the file will be found and compiled. (Because the driver implicitly adds .c to the name.) Then load_object() assigns the empty string to ob->name and tries to enter the object in the object hash table.
enter_object_hash looks up the object in the hash table first and will always find some because of the empty name. In debug mode that results in calling fatal("Duplicate object in objetct hash table").
load_object() should therefore check and refuse loading if the given name is empty.
I have a stacktrace and core file availabe if someone is interested to check personally.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: load_object.patch (1,059 bytes) 2007-02-25 10:42
http://ldmud.eu/file_download.php?file_id=96&type=bug
find_object.patch (3,136 bytes) 2007-02-25 10:45
http://ldmud.eu/file_download.php?file_id=97&type=bug
Notes
(0000528)
zesstra   
2007-02-25 10:41   
I finally found some time to dive deeper into the problem. It is actually a little bit different from what I originally thought.
load_object("") loads the /.c correctly and enters it into the hash table. Unfortunately, lookfor_object() and load_object() cannot find objects with an empty name, thus causing load_object() to load it a second time, upon which it crashes.
lookfor_object() and load_object() both use lookup_object_hash_str() for looking up existing objects. That function uses find_obj_n_str() which calculates the hash by a direct call to whashmem(), which returns 0 as hash for an empty C-string. Thus the object is not found.
In contrast, enter_object_hash() uses find_obj_n() which finally ends in hash_string() in mstrings.c, which does the hash computation by call to whashmem() in a similar way, but ensures to return a non-zero hash to the caller. Thus, even the object with the empty name is found.

There are now 2 possibilities:
1) define "" as illegal object/file name and make load_obect() refuse to load it. I will attach a patch called load_object.patch for that.

2) change find_obj_n_str() to find the object with name "", by using hash_string() from mstrings.c instead of calling whashmem() directly. hash_string() in mstrings.c is an inline function, therefore it is neccessary to move it to mstrings.h if it should remain suitable for inlining. See find_object.patch for that.

Both solutions work fine, which to choose remains to you. ;-) If there is some chance, that an object named "" may cause havoc somewhere else, I would prefer solution 1, otherwise 2 may be an option.
(0000554)
lars   
2007-10-06 22:26   
I liked both solutions, for their own different reasons.

Refusing to load objects with an empty name is a sane thing to do.

And the object table should use exactly the same hash regardless of whether it hashes a given mstring, or a regular C-String. I did not make the hash_string() function inline for the object table, though - the expensive part is whashmem() anyway.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
497 [LDMud 3.3] Compilation, Installation trivial always 2007-01-06 20:58 2018-01-29 22:57
Reporter: Zonk_FF Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.713  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: Compile error: Missing backslashes
Description:   In file hosts/GnuWin32/GnuWin32.h:7
#define HOST_DEPENDENT_INIT
  should be
#define HOST_DEPENDENT_INIT \


  In file hosts/GnuWin32/socket.g:8
#define socket_number(s) (s)

socket_select(a,b,c,d,e) ({ \
  should be
#define socket_number(s) (s) \
socket_select(a,b,c,d,e) ({ \
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000634)
zesstra   
2008-06-30 13:12   
Added backslashes as suggested by Zonk_FF (r2366), thank you.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
494 [LDMud] LPC Compiler/Preprocessor crash always 2006-11-14 07:50 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: lars OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3.713  
Product Build: 3.3.714, build 2307 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.716  
    Target Version:  
External Data (URL):
Summary: 'struct abc abc;' in a global context crashes if the structure is undefined
Description: Just a file s.c with the line
   struct abc abc;
crashes the driver.

2006.11.14 13:30:57 w/gnomi/s.c line 1: Unknown struct 'abc' before ';'.
2006.11.14 13:30:57 w/gnomi/s.c line 1: Missing type before end of line.

Program terminated with signal 11, Segmentation fault.
#0 0x080df975 in define_variable (name=0x8feedf0, type=
      {typeflags = 335544320, t_struct = 0x0}) at prolang.y:3302
3302 dummy.name = ref_mstring(name->name);
(gdb) bt
#0 0x080df975 in define_variable (name=0x8feedf0, type=
      {typeflags = 335544320, t_struct = 0x0}) at prolang.y:3302
0000001 0x080dfe2f in define_global_variable (name=0x8feedf0, actual_type=
      {typeflags = 335544320, t_struct = 0x0}, opt_star=0, with_init=0)
    at prolang.y:3446
0000002 0x080e4f7b in yyparse () at prolang.y:6787
0000003 0x080fa195 in compile_file (fd=11, fname=0xbff0e120 "w/gnomi/s.c",
    isMasterObj=0) at prolang.y:16713
0000004 0x0810b217 in load_object (lname=0x81f9400 "apps/goetter_register",
    create_super=0, depth=0, isMasterObj=0, chain=0x0) at simulate.c:1955
0000005 0x0810c0f3 in lookfor_object (str=0x923de3c, bLoad=1) at simulate.c:2397
0000006 0x0810fa0c in f_load_object (sp=0x8173e90) at simulate.c:4466
0000007 0x08093fd2 in eval_instruction (
    first_instruction=0x8b4af5e "\036\001\003P\036", initial_sp=0x8173e88)
    at interpret.c:7974
0000008 0x080af2f7 in int_call_lambda (lsvp=0x8173e78, num_arg=2, allowRefs=0)
    at interpret.c:17772
0000009 0x080b3c3a in v_funcall (sp=0x8173e88, num_arg=3) at interpret.c:20261
0000010 0x0809517d in eval_instruction (
    first_instruction=0x8b4af76 "`\002\005\036", initial_sp=0x8173e68)
    at interpret.c:8173
0000011 0x080a5fde in eval_instruction (
    first_instruction=0x92bd4aa "a\017\003@\036", initial_sp=0x8173e28)
    at interpret.c:14664
0000012 0x080ada1d in apply_low (fun=0x925189c, ob=0x92a7644, num_arg=1,
    b_ign_prot=0, allowRefs=0) at interpret.c:16811
0000013 0x080adc14 in int_apply (fun=0x925189c, ob=0x92a7644, num_arg=1,
    b_ign_prot=0, b_use_default=1) at interpret.c:16889
#14 0x080ae07e in sapply_int (fun=0x925189c, ob=0x92a7644, num_arg=1,
    b_find_static=0, b_use_default=1) at interpret.c:17050
#15 0x0804c9ce in parse_command (buff=0xbff105d0 "lade s", from_efun=0)
    at actions.c:1094
#16 0x0804cf41 in execute_command (str=0xbff105d0 "lade s", ob=0x9094c48)
    at actions.c:1258
#17 0x08054999 in backend () at backend.c:671
#18 0x080c0079 in main (argc=16, argv=0xbff11f84) at main.c:615
(gdb)

The reason is, that the identifier 'abc' from the lexer (with I_TYPE_UNKNOWN) is freed too early. The following happens:

The parser asks the lexer for two tokens, it gets L_STRUCT and L_IDENTIFIER. The later has an ident_t for "abc" with I_TYPE_UNKNOWN as the semantic value attached. This is not enough for the parser to decide between shift or reduce, so it requests another token as a look-ahead symbol which is again an L_IDENTIFIER with the same ident_t structure for "abc" as the semantic value (still I_TYPE_UNKNOWN). Now the parser reduces using the rule 'identifier: L_IDENTIFIER'. This rule just takes the name and frees the corresponding ident_t structure, because it is I_TYPE_UNKNOWN. But this structure is still used as the semantic value of the look-ahead L_IDENTIFIER token. So when this token is used later in the 'name_list: type optional_star L_IDENTIFIER' rule, the semantic value is overwritten with some other garbage leading to a crash.

I would recommend not to free any shared_identifier during parsing because of these look-ahead symbols. Do they hurt?

Greetings,
Gnomi.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files: idents.diff (3,371 bytes) 2006-11-15 03:15
http://ldmud.eu/file_download.php?file_id=94&type=bug
Notes
(0000524)
Gnomi   
2006-11-15 03:22   
I have uploaded a patch that I'll use in the meanwhile in our test MUD (and later in UNItopia).

I have removed every free_shared_identifier in parsing rules and put a remove_unknown_identifier in the epilog instead. I think the above case is the now the only one where an L_IDENTIFIER is processed while another one is saved as a look-ahead token, so strictly speaking only the free_shared_indentifier in the 'identifier: L_IDENTIFIER' rule needs to be removed. But this can change as rules change and then this problem may not be obvious, so I removed all free_shared_identifier calls.
(0000570)
lars   
2007-10-14 02:22   
I don't see why this approach should cause a problem.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
493 [LDMud] LPC Compiler/Preprocessor crash always 2006-11-14 05:59 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: lars OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3.713  
Product Build: 3.3.714, build 2307 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.716  
    Target Version:  
External Data (URL):
Summary: find_struct should only consider global identifier
Description: void fun()
{
    struct abc abc = (<abc>);
}

without any prior definition of struct abc crashes.

Program terminated with signal 11, Segmentation fault.
#0 0x080ecb7d in yyparse () at lang.y:10244
10244 if ($7.length > STRUCT_MAX_MEMBERS
(gdb) bt
#0 0x080ecb7d in yyparse () at lang.y:10244
0000001 0x080fa195 in compile_file (fd=11, fname=0xbfea5600 "w/gnomi/LPC_zst.c",
    isMasterObj=0) at prolang.y:16713
0000002 0x0810b217 in load_object (lname=0x81f9400 "apps/goetter_register",
    create_super=0, depth=0, isMasterObj=0, chain=0x0) at simulate.c:1955
0000003 0x0810c0f3 in lookfor_object (str=0x90917fc, bLoad=1) at simulate.c:2397
0000004 0x0810fa0c in f_load_object (sp=0x8173ee8) at simulate.c:4466
0000005 0x08093fd2 in eval_instruction (
    first_instruction=0x8b4af5e "\036\001\003P\036", initial_sp=0x8173ee0)
    at interpret.c:7974
0000006 0x080af2f7 in int_call_lambda (lsvp=0x8173ed0, num_arg=2, allowRefs=0)
    at interpret.c:17772
0000007 0x080b3c3a in v_funcall (sp=0x8173ee0, num_arg=3) at interpret.c:20261
0000008 0x0809517d in eval_instruction (
    first_instruction=0x8b4af76 "`\002\005\036", initial_sp=0x8173ec0)
    at interpret.c:8173
0000009 0x080a5fde in eval_instruction (
    first_instruction=0x92b9aa9 "a\r\ra\bU\v\207?b*\r\016*\020c??",
    initial_sp=0x8173e80) at interpret.c:14664
0000010 0x0810858a in catch_instruction (flags=0, offset=24, i_sp=0x823dcc0,
    i_pc=0x92b9aa9 "a\r\ra\bU\v\207?b*\r\016*\020c??", i_fp=0x8173e50,
    reserve_cost=65536, i_context=0x0) at simulate.c:447
0000011 0x08096f4e in eval_instruction (
    first_instruction=0x92b9c6a "`\001\002a\017\003@\036",
    initial_sp=0x8173e40) at interpret.c:9381
0000012 0x080ad5b5 in apply_low (fun=0x9251528, ob=0x92a7210, num_arg=1,
    b_ign_prot=0, allowRefs=0) at interpret.c:16698
0000013 0x080adc14 in int_apply (fun=0x9251528, ob=0x92a7210, num_arg=1,
    b_ign_prot=0, b_use_default=1) at interpret.c:16889
#14 0x080ae07e in sapply_int (fun=0x9251528, ob=0x92a7210, num_arg=1,
    b_find_static=0, b_use_default=1) at interpret.c:17050
#15 0x0804c9ce in parse_command (
    buff=0xbfea8570 "zlpc struct abc abc = (<abc>);", from_efun=0)
    at actions.c:1094
#16 0x0804cf41 in execute_command (
    str=0xbfea8570 "zlpc struct abc abc = (<abc>);", ob=0x91f59a4)
    at actions.c:1258
#17 0x08054999 in backend () at backend.c:671
#18 0x080c0079 in main (argc=16, argv=0xbfea9f24) at main.c:615

The reason is, that find_struct doesn't search for the global identifier (which a struct must be), but instead just takes what find_shared_identifier returns (which may be a local identifier). So find_structs may return an arbitrary number if it is a local identifier, an access to the corresponding struct definition then crashes.

I attached a patch, which fixes this.

Greetings,
Gnomi.

PS: The global case (struct abc abc as a global variable) also crashes, but in a more interesting way. I'll make another bug entry for this.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files: structs.diff (566 bytes) 2006-11-14 05:59
http://ldmud.eu/file_download.php?file_id=93&type=bug
Notes
(0000571)
lars   
2007-10-14 02:28   
Implemented the patch.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
489 [LDMud] Runtime crash always 2006-10-05 04:50 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: lars OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3.713  
Product Build: 3.3.714 (svn 2312) Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.716  
    Target Version:  
External Data (URL):
Summary: assert_simul_efun_object() should check whether the simul_efun was loaded during the master apply
Description: The get_simul_efun() in our master loads a backup simul_efun if the load of the original simul_efun failed. A failure can be a compile or runtime error during loading of the original simul_efun or a recursive call to get_simul_efun().

The last possibility isn't handled by the driver very well. If a new simul_efun object accidentally calls a simul_efun (eg. because of a forgotten prototype or efun:: prefix), the driver calls assert_simul_efun_object and thus get_simul_efun again. The master then switches to the backup and loads it. Hence also the compilation of the original simul_efun succeeds and the driver activates it as the new official simul_efun. Because of this procedure the simul_efun tables first contains all the functions from the backup simul efun and after that all the functions from the original simul_efun.

So if a program, that was compiled before this simul_efun renewal, calls a simul_efun, it will get the function from the backup simul_efun, which will then be executed with the variables from the original simul_efun (because the last activated simul_efun will be in the simul_efun_object variable). This may lead to an error "Illegal variable access 42(33)." and thus to a crash:

2006.10.05 11:36:10 Illegal variable access 42(33).
2006.10.05 11:36:10 Current object was secure/simul_efun/simul_efun
2006.10.05 11:36:10 Dump of the call chain:
' modify_command' in ' i/player/tippse.c' (' obj/player#5') line 548
' command_start' in 'secure/simul_efun/backup/simul_efun.c (/secure/simul_efun/backup/notify_fail.inc)' ('secure/simul_efun/simul_efun') line 55

(gdb) bt
#0 0x081050db in dump_core () at simulate.c:586
0000001 0x080fcdde in fatal (fmt=0x812b4a0 "Illegal variable access %d(%d).\n")
    at simulate.c:649
0000002 0x080abf35 in find_value (num=42) at interpret.c:5834
0000003 0x0808fb76 in eval_instruction (
    first_instruction=0x9358b66 "?<'\003?\003\"j4`", initial_sp=0x816fa80)
    at interpret.c:8137
0000004 0x0809eadc in eval_instruction (
    first_instruction=0x917078a "`\001\ta?n?\017?b\\v\016$\022\036/js\017v\016)\002\016\b\r+\022\n1&Y?~", initial_sp=0x816fa78) at interpret.c:14589
0000005 0x080a1fc9 in apply_low (fun=0x8b2df6c, ob=0x91f2890, num_arg=1,
    b_ign_prot=0, allowRefs=0) at interpret.c:16623
0000006 0x080a2583 in int_apply (fun=0x8b2df6c, ob=0x91f2890, num_arg=1,
    b_ign_prot=0, b_use_default=1) at interpret.c:16814
0000007 0x080a29af in sapply_int (fun=0x8b2df6c, ob=0x91f2890, num_arg=1,
    b_find_static=0, b_use_default=1) at interpret.c:16975
0000008 0x0804ac7a in call_modify_command (buff=0xbff2c610 "s") at actions.c:540
0000009 0x0804bbfa in parse_command (buff=0xbff2c610 "s", from_efun=0)
    at actions.c:883
0000010 0x0804c784 in execute_command (str=0xbff2c610 "s", ob=0x91f2890)
    at actions.c:1258
0000011 0x0805445c in backend () at backend.c:697
0000012 0x080b8156 in main (argc=16, argv=0xbff2e034) at main.c:615

Even if this crash wouldn't happen, the backup simul_efuns could get the content of wrong variables or if the backup simul_efun would be destroyed the entries in the simul_efun table could point to random memory entries.

So I think after the master apply assert_simul_efun_object() should verify that no other simul_efun object mysteriously appeared. I have submitted a patch for this.

Greetings,
Gnomi
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files: sefun.diff (534 bytes) 2006-10-05 04:50
http://ldmud.eu/file_download.php?file_id=92&type=bug
Notes
(0000572)
lars   
2007-10-14 02:36   
Yup.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
488 [LDMud 3.3] Efuns minor always 2006-10-02 06:29 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3.713  
Product Build: 3.3.714 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: ed: The 'r' command leaks the filename
Description: In the implementation of the 'r' command in ed.c the filename returned from getfn is not freed if no error occurs.

Greetings,
Gnomi

2006.10.02 13:28:50 --- Garbage Collection ---
2006.10.02 13:28:50 GC pass 1: Freed 1 objects.
freeing small block 0x090a16cc (user 0x090a16d4) simulate.c 3515
  No object.
090a16e8: 02 00 00 00 00 00 00 00 0b 00 00 00 00 00 77 2f ..............w/
090a16f8: 67 6e 6f 6d 69 2f 61 2e 63 00 18 09 80 08 00 38 gnomi/a.c......8
090a1708: ab ee 72 a3 ec d5 b1 08 01 00 00 ..r........

1 small blocks freed
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0000637)
Gnomi   
2008-07-01 02:49   
Fixed in 3.3.717 (r2368).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
486 [LDMud 3.3] Efuns minor always 2006-09-11 09:40 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version:  
Product Build: 3.3.714 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: input_to with INPUT_PROMPT but an invalid prompt leaks the prompt and all additional parameters
Description: Hi,

efun::input_to("bla",4,({1}),({2}))

yields

2006.09.11 16:36:32 --- Garbage Collection ---
freeing small block 0x0907173c (user 0x09071744) interpret.c::allocate_uninit_array 14709
  By object: w/gnomi/LPC_zst
  By program: w/gnomi/LPC_zst.c line:15
09071758: 01 00 00 00 01 00 00 00 07 00 00 00 44 d1 0f 09 ............D...
09071768: 02 00 00 00 02 00 00 00 4e 05 00 38 ab d8 58 ab ........N..8..X.
09071778: ac c3 06 09 29 00 00 ....)..

freeing small block 0x090717a4 (user 0x090717ac) interpret.c::allocate_uninit_array 14709
  By object: w/gnomi/LPC_zst
  By program: w/gnomi/LPC_zst.c line:15
090717c0: 01 00 00 00 01 00 00 00 05 00 00 00 44 d1 0f 09 ............D...
090717d0: 02 00 00 00 01 00 00 00 68 05 00 38 ab d8 58 ab ........h..8..X.
090717e0: ac c3 06 09 29 00 00 ....)..

2 small blocks freed

Greetings,
Gnomi.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files: inputtoleak.diff (637 bytes) 2006-09-12 04:15
http://ldmud.eu/file_download.php?file_id=91&type=bug
Notes
(0000646)
Gnomi   
2008-07-01 09:46   
Fixed in 3.3.717 (r2370).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
485 [LDMud 3.3] Efuns major always 2006-09-11 07:03 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: lars OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version:  
Product Build: 3.3.714 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: Every sha1/md5 iteration should cost evals
Description: Hi,

the evaluation cost for sha1() or md5() calls is constant, regardless of the given iteration count. So it is possible, to calculate the hash sum with __INT_MAX__ iterations which would probably halt a MUD for over an hour. Even eval costs of 1 per iteration is a bit cheap, because the hash calculation is very CPU intensive. (This could halt our MUD for up to half a second per thread). So, I would recommend 5 to 10 eval points per iteration.

Greetings,
Gnomi.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0000579)
lars   
2007-11-11 19:08   
I used 5 ticks per iteration for now.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
483 [LDMud 3.3] Runtime crash always 2006-08-10 07:44 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: lars OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3.713  
Product Build: 2306 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.716  
    Target Version:  
Summary: replace_program confuses variable sharing
Description: Hi,

while playing around with the pragma share_variables and replace_program,
I tried to provoke a crash and succeeded:

2006.08.10 00:48:10 (free_svalue) Illegal svalue 0xc01f9d4 type 285
...
apps/closure_container <lambda ?> line 0
b9cb4cf: 98 restore_arg_frame (2: 1) line 0
b9cb4d0: 24 return (1: 0)
8555716: 24 25 72 166 50 8 4 0
No program to trace.
2006.08.10 00:48:10 LDMud aborting on fatal error.

#0 0x080da4b0 in fatal (fmt=0x8141348 "\002") at simulate.c:586
586 *((char*)0) = 0/a;
(gdb) bt
#0 0x080da4b0 in fatal (fmt=0x8141348 "\002") at simulate.c:586
0000001 0x0807f2cf in int_free_svalue (v=0xc01f9d4) at interpret.c:1097
0000002 0x080dd92e in remove_object (ob=0xbf01748) at simulate.c:2857
0000003 0x080dda77 in handle_newly_destructed_objects () at simulate.c:2947
0000004 0x08052eea in backend () at backend.c:476
0000005 0x080a7709 in main (argc=0, argv=0x0) at main.c:615

I used the following files (and initialization by __INIT):

--- i/x.c: ---

int dubdidu = 20;

void dummy() {}

--- i/y.c: ---

#pragma share_variables

inherit "x";

int a = 10;
int b = 10;
int c = 10;
int d = 10;
int e = 10;
int f = 10;
int g = 10;
int h = 10;
int i = 10;
int j = 10;
int k = 10;
int l = 10;
int m = 10;
int n = 10;
int o = 10;
int p = 10;
int q = 10;
int r = 10;
int s = 10;
int t = 10;
int u = 10;
int v = 10;
int w = 10;
int x = 10;
int y = 10;
int z = 10;

void rpy()
{
    replace_program();
}

--- obj/z.c: ---

inherit "../i/y";

void rpz()
{
    replace_program();
}

--- app.c: ---

void step1()
{
    object y = load_object(__PATH__(0) "i/y");
    object z = load_object(__PATH__(0) "obj/z");
    y->rpy();
    z->rpz();
}

void step2()
{
    destruct(clone_object(__PATH__(0) "obj/z"));
}

-------------

Calling app->step1() results in three objects:

i/x with the program of i/x.c and one __INITialized variable.
i/y with the program of i/x.c and therefore also one __INITialized variable.
obj/z with the program of i/y.c, one __INITialized variable and
  26 shared variables.

In this constellation the blueprint (given by the efun blueprint) of obj/z
is i/y, but the program of i/y is i/x.c, so the blueprints program does
not correspond to the program of its clones.

When cloning obj/z by app->step2(), init_object_variables looks for the
blueprint and copies shared variables from the blueprint. But as the
blueprint (i/y with the program i/x.c) does only have one variable,
the needed 26 shared values are random bytes from memory beyond the
variable block. Freeing them may then result in a crash.

I would suggest two things to solve this. First replace_program, when called
from a blueprint, should set the blueprint pointer of the replaced program
to NULL, because then the blueprint won't be a blueprint for this program
anymore. Second init_object_variables should copy the variables from the
template given to clone_object and not necessarily from prog->blueprint.

The second proposal may break things (especially when cloning from a clone,
there it is now expected, that the variables are taken from the blueprint),
but I think it's more intuitive. Changing this behaviour only in the case,
when the template is not a clone, seems a half-hearted solution to me.

And this change will allow applications as Fiona described in her Mail
<Pine.LNX.4.33.0509231010370.16774-100000@hasyl03.desy.de>
from September, 23rd 2005 on the LDMud-Talk list (for a specific weapon
inherit a generic weapon, set some global variables like the weapon type
and strength, do a replace_program and let others clone then this specific
weapon).

It would also avoid the "Can't initialize object 'obj/xyz#123': no blueprint."
errors, when the inherit (i/y in this case) was destroyed meanwhile (which
can happen very easily).

Greetings,
Gnomi.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files: sharedvars.diff (3,512 bytes) 2006-09-11 15:25
http://ldmud.eu/file_download.php?file_id=90&type=bug
Notes
(0000516)
Gnomi   
2006-09-11 15:27   
I uploaded a diff which fixes this. This fix doesn't change the behaviour (as described above), because clone_object already searches for a blueprint and uses this instead of the given object.
(0000556)
lars   
2007-10-06 23:28   
Implemented - thanks!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
442 [LDMud 3.3] Networking major always 2006-01-09 13:12 2018-01-29 22:57
Reporter: fippo Platform:  
Assigned To: lars OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.712  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.716  
    Target Version:  
Summary: socket closes after reading MAX_TEXT bytes
Description: When reading large chunks of data from a socket, the driver prematurely closes the socket.

ip->text_end remains at MAX_TEXT, which triggers a zero-byte read in the next cycle, closing the socket.

In the attached example 'reader.c', feed is called first with a newline \n only (most likely the result of a 'faking NL' ~ line 3230 of comm.c), then with the data, finally with an empty string. After that, the driver tries to read zero bytes, which closes the socket.

Workaround: increase MAX_TEXT

(hint: decrease MAX_TEXT for debugging :-)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: reader.c (273 bytes) 2006-01-09 13:12
http://ldmud.eu/file_download.php?file_id=76&type=bug
test.py (544 bytes) 2006-01-09 13:26
http://ldmud.eu/file_download.php?file_id=77&type=bug
Notes
(0000473)
fippo   
2006-01-09 13:27   
test.py reproduces the bug (with MAX_TEXT set to 128).
Only the string of ones is received on LPC level
(0000561)
lars   
2007-10-07 18:42   
While the problem is indeed caused with the faking of a NL when reading a full buffers worth of data
in charmode with combine-charset(!), I couldn't quite determine what exactly is going wrong.

The cheap solution is simply to not read MAX_TEXT worth of data in charmode, avoiding the situation
altogether.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
631 [LDMud 3.3] Implementation minor always 2009-04-26 04:41 2018-01-29 22:57
Reporter: Sorcerer Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Inconsistent behaviour of nested inline closures
Description: Consider the following two functions:

void test1() {
  int i=1;

  if (i) write("Fun ok\n");

  funcall((: if (i) write("Inline 1 ok\n");
             funcall((: int i=$1; if (i) write("Inline 2 ok\n"); :),i);
          :));
}

void test2() {
  int i=1;

  if (i) write("Fun ok\n");

  funcall((: if (i) write("Inline 1 ok\n");
             funcall((: if (i) write("Inline 2 ok\n"); :));
          :));
}

Loading an object that defines these two functions results in an compiler warning "...line 7 before '$1; if (i)': Variable 'i' shadows previous declaration" which seems ok to me since i is in the implicit context of the 1st inline and therefore should also be in the implicit context of the 2nd one (calling test1() works fine).
BUT: calling test2() in this example (which causes no compile-time warnings) results in the following runtime error as soon as the 2nd inline closure is evaluated: "(eval_instruction) context_identifier: inter_context is NULL".

Now, either the implicit context of one inline closure is passed on as implicit context to another nested inline closure - in that case test2() has to work. Or the implicit context is not passed on - than test1() has to compile without compiler warnings, since i is not known in the scope of the 2nd inline closure.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: bug631.diff (26,902 bytes) 2009-05-19 05:57
http://ldmud.eu/file_download.php?file_id=240&type=bug
Notes
(0001061)
Sorcerer   
2009-04-26 04:43   
See also issue 0000613, which is marked resolved for 3.3.718.
(0001062)
Sorcerer   
2009-04-26 04:45   
Oh - I just realized it was filed against 718 but will be resolved only in 719. So this might solve this issue, too, but since I don't know for sure, please have a look at it anyways.
(0001063)
Gnomi   
2009-04-26 19:02   
I don't know how this was supposed to work. check_for_context_local() in prolang.y seems to assume that we can access variables of an outer context. But at runtime when calling the inner closure this outer context might not exist anymore.

There is a second problem:

    funcall(
        function int() : int i = 1
        {
            return funcall((: return i; :));
        }));

This fails because only locals can be adopted as an implied context variable, not outer context variables.

This is not related to 0000613 which dealt only with lambda closures.
(0001064)
Gnomi   
2009-04-27 02:47   
And a third problem:

    int i = 1;

    funcall(
        function int()
        {
            int j = 2;
            return funcall((: return i; :));
        }));

This returns 2 (because i is the first local variable in its block, so is j).
(0001065)
Sorcerer   
2009-04-27 04:43   
One more - which seems to me to be in agreement with the other cases:

  funcall(function int () {
            return funcall(function int () : int i=i {
              return i;
            });
          });

throws an error, while

  funcall(function int () {
            i;
            return funcall(function int () : int i=i {
              return i;
            });
          });
  
works fine (as soon as i is used in the outer inline-closure).
(0001066)
Gnomi   
2009-04-29 05:40   
The last one is a different problem, similar to the following:

  int x = 1; // global variable

  int fun()
  {
    int x = x;

    return x;
  }

fun() will return 0, because the initializer (= x) references the local variable not the global one. The same happens when initializing the context variable int i = i, the parser initializes the context variable i with itself but at that time the context doesn't exist yet, so an error is thrown.

I'll duplicate this bug for these problems.
(0001067)
Gnomi   
2009-04-29 05:56   
I attached a patch that fixes these problems (except 0000632).
(0001082)
Gnomi   
2009-05-05 16:00   
That's a somewhat different problem, which nevertheless i'd like to handle also in this bug:

  int a = 2;

  return funcall(
    function int() : int b = a; int c = b
    {
      return c;
    });
(0001088)
Gnomi   
2009-05-09 08:04   
I uploaded a new patch that also fixes the last problem (0000631:0001065 and 0000631:0001082) by treating explicit context variables during initialization as real local variables of the outer function and let F_CONTEXT_CLOSURE take the values from there.
(0001091)
fufu   
2009-05-10 10:45   
Something is fishy here. Calling the following function results in an infinite loop in inl_transfer_svalue(), caused by an lvalue pointing to itself:

void t(mixed a, mixed b, mixed c)
{
  return funcall(funcall(funcall(
      function :
          mixed i = 1;
          mixed j = function :
              mixed j = function { return i; }
              { return j; };
          { return j; }
  )));
}
(0001092)
fufu   
2009-05-10 10:47   
I'm using r2574 + your patch, configured with ./settings/wunderland --disable-use-ipv6 --enable-debug --enable-check-object-ref --enable-check-object-gc-ref
(0001099)
Gnomi   
2009-05-10 17:47   
I uploaded a modified patch. The old patch calculated the index of the first local variable wrongly when a closure was within the context of another closure.
(0001103)
Gnomi   
2009-05-12 11:06   
I updated the patch to r2584.
(0001118)
Gnomi   
2009-05-19 14:11   
Committed as r2588.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
630 [LDMud 3.3] LPC Compiler/Preprocessor minor always 2009-04-21 05:43 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Imperfect overflow detection
Description: When numeric literals exceed __INT_MAX__ there's usually a warning "Number exceeds numeric limits" and __INT_MAX__ is returned.

This fails for numbers between __INT_MAX__+1 and 2*__INT_MAX__ (and slightly above until the next multiple of 10).

The same applies to to_int.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0001078)
Gnomi   
2009-05-04 18:26   
Fixed in r2561.
(0001090)
fufu   
2009-05-10 09:52   
We'll have to revisit this. Now

   return __INT_MIN__

gives a warning. So does the NAME_INHERITED define from function_list.h (on 32 bit platform)
(0001094)
fufu   
2009-05-10 13:13   
Fixed the latter in r2580.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
629 [LDMud 3.3] Runtime minor always 2009-04-20 14:34 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Close all sockets/files before executing erq.
Description: When erq is started it inherits all open file descriptions and sockets. I suggest closing all sockets except the socket pair for stdin and stdout.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0001119)
Gnomi   
2009-05-19 16:34   
I set the close-on-exec-flag on all files that are opened by the driver, so ERQ doesn't get these. It doesn't work on files opened by libraries, but it's not trivial to catch these descriptors, so I'll leave it at that.

Committed as r2589.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
613 [LDMud 3.3] Efuns minor always 2009-03-13 04:42 2018-01-29 22:57
Reporter: Gnomi Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Context closures in a lambda expression loose their context variables
Description: int x = 0;
funcall(lambda(0,({ (: x :) })));

gives "(eval_instruction) context_identifier: inter_context is NULL".
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: bug613.diff (12,105 bytes) 2009-04-16 03:16
http://ldmud.eu/file_download.php?file_id=208&type=bug
Notes
(0001042)
Gnomi   
2009-04-16 03:25   
I added a patch that implements two opcodes: F_CALL_CLOSURE and F_POP_SECOND. F_CALL_CLOSURE is just like funcall() but as an internal call (so no recursive calls to eval_instruction()). F_POP_SECOND removes the closure from the stack after it was evaluated (and left its return value on top).
(0001057)
Gnomi   
2009-04-19 12:47   
Committed as r2553.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
612 [LDMud 3.3] Efuns minor always 2009-03-11 08:44 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Remove "Arguments passed to variable closure." error
Description: funcall(#'var, 1) gives the error "Arguments passed to variable closure.".
funcall(#'fun, 1) doesn't, even if fun() takes no arguments.
funcall("str", 1) doesn't either, the arguments are simply ignored.

I think funcall(#'var, 1) should behave as funcall("str", 1) and ignore any additional arguments instead of throwing an error.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0001115)
Gnomi   
2009-05-18 16:37   
Done in r2587.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
595 [LDMud 3.3] Runtime crash always 2009-01-15 16:35 2018-01-29 22:57
Reporter: peng Platform:  
Assigned To: Gnomi OS:  
Priority: high OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Crash in 718
Description: Crasher in 718, with FATAL.
See backtrace in appended file.
There is a custom pkg (stringcompiler) in our driver, so this is not out of the box. but since the additional efuns are not in the trace, this seems not to be the reason.
Core und binary is available, if neccesary.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: backtrace_20090115.txt (17,340 bytes) 2009-01-15 16:35
http://ldmud.eu/file_download.php?file_id=181&type=bug
config.h (20,521 bytes) 2009-01-15 17:20
http://ldmud.eu/file_download.php?file_id=182&type=bug
machine.h (13,740 bytes) 2009-01-15 17:21
http://ldmud.eu/file_download.php?file_id=183&type=bug
Makefile (26,371 bytes) 2009-01-15 17:21
http://ldmud.eu/file_download.php?file_id=184&type=bug
save_object_crash.diff (520 bytes) 2009-01-16 05:15
http://ldmud.eu/file_download.php?file_id=185&type=bug
Notes
(0000894)
peng   
2009-01-15 16:37   
Ups, forgotten to append the debug.log:

2009.01.15 22:03:18 Bad stack at F_RETURN, 1 values too low
2009.01.15 22:03:18 Current object was obj/money#1852
2009.01.15 22:03:18 Dump of the call chain:
' disconnect' in 'secure/master.c (/secure/master/connections.inc)' (' secure/master') line 270
' net_dead' in ' i/player/login.c' (' obj/jnaii#1660') line 1596
' dosave' in ' apps/dasaved.c' (' apps/dasaved') line 218
' rsave' in ' apps/dasaved.c' (' apps/dasaved') line 112
' rsave' in ' apps/dasaved.c' (' apps/dasaved') line 152
' save_item' in ' i/item.c' (' obj/money#1852') line 412
' save_object' in 'secure/simul_efun/simul_efun.c (/secure/simul_efun/save.inc)' ('secure/simul_efun/simul_efun') line 53
#'save_object for ' i/money/money.c' (' obj/money#1852')
(0000895)
Gnomi   
2009-01-16 05:19   
Calling save_object without a filename crashes, because in this case no error handler will be put on the stack (none is needed), but afterwards save_object tries to remove the error handler from the stack. The attached patch fixes this.
(0000910)
Gnomi   
2009-01-16 18:02   
Committed as r2498.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
589 [LDMud 3.3] Other minor always 2008-12-30 08:24 2018-01-29 22:57
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: MacOS X  
Priority: low OS Version: 10.5.x  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: GC test failures if GC is not supported
Description: Several tests in the testsuite which check for memory leaks fail because the GC log file is not readable after a try to run the garbage collector when the driver was compiled with a memory manager not supporting the GC.
We should either change the tests to accomodate that or change the garbage_collection() function to write to the requested gcollect_outfd even if no real garbage collection is done (e.g. something like "Garbage collection was requested, but GC is not supported - just freeing all memory possible.").
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0000857)
Gnomi   
2009-01-08 05:37   
There is also a problem if access restrictions are activated.
(0000938)
Gnomi   
2009-01-28 17:39   
I changed the GC test in r2513.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
587 [LDMud 3.3] Portability crash always 2008-12-14 18:17 2018-01-29 22:57
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Possible crash in strftime(), gmtime() and localtime() on 64 bit platforms with timestamp values > 2^55
Description: The values for the 'time' argument of strftime, gmtime() and localtime() are limited to __INT_MAX__.
Unfortunately, at least several libc (libc in MacOS X 10.5.x, glibc), return a NULL with large values of time_t (between 2^55 and 2^56), when the year does not fit into an int. (On my MacOS, this is undocumented. *grrr*)

The driver never checks the return value of gmtime() and localtime() (probably because Lars developed on MacOS as well and read the faulty manpage), which leads to the segfault.
Tags:
Steps To Reproduce: gmtime(__INT_MAX__);
localtime(__INT_MAX__);
strftime(__INT_MAX__);
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0000901)
zesstra   
2009-01-16 07:00   
This issue is a little bit tricky...
So far I found no guaranteed upper limit for time_t (except of 2^32-1 I guess) which any of the time manipulation functions accept... Does anybody knows more?

We could limit the input to time strftime() (or maybe time functions in general) to some hundred years, but that may not be long enough for Muds with an own (accelerated) time frame.
(0000948)
zesstra   
2009-02-13 07:14   
I added a test for this to begin with.
Would be nice to check on different systems if they are affected / have a buggy strftime() in their libc.
(0000949)
zesstra   
2009-02-13 09:05   
Menaures (Gentoo 64, x86_64-pc-linux-gnu-4.3.3) and Fireddl (ELF 64-bit LSB executable, AMD x86-64, Debian etch, glibc-2.3.6) report the same behaviour: 2^55 is still ok, 2^56 crashes.
(0000951)
zesstra   
2009-02-13 13:14   
OK, for the record: the crash in the libc occurs in gmtime()/localtime(), not strftime(). Should have noted it from the beginning, but changes little besides that our efuns gmtime() and localtime() are now affected as well. ;-)
(0000953)
zesstra   
2009-02-15 09:57   
Ok. 3rd try and this time I got the explanation right, I hope. ;-) It is also much easier to fix properly. *g*
(0000954)
zesstra   
2009-02-15 10:29   
Should be fixed by r2519, which also adds additional tests for the other affected efuns to the testsuite.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
584 [LDMud 3.3] LPC Compiler/Preprocessor minor always 2008-12-03 03:24 2018-01-29 22:57
Reporter: _xtian_ Platform: 64bit  
Assigned To: Gnomi OS: debian  
Priority: normal OS Version: lenny  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: variable definition in outer switch block
Description: It is possible to define a variable in the outer switch block (before the first case-statement).
I find this uncommon an am not sure if this was intended.

Also: This variable, if initialised before this first case-statement, will not be initialised correctly. Please see the following LPC code:
Tags:
Steps To Reproduce: mixed test()
{
  int i=1;

  switch(i)
  {
    mixed mx=2; // either: this definition shouldnt be allowed here

    case 1:
    // ...
      return mx; // or: this yield 0
  }
}
Additional Information:
Attached Files: bug584.diff (5,838 bytes) 2008-12-06 12:48
http://ldmud.eu/file_download.php?file_id=171&type=bug
turn-parse-errors-into-assertions.patch (1,722 bytes) 2008-12-10 10:10
http://ldmud.eu/file_download.php?file_id=172&type=bug
Notes
(0000810)
Gnomi   
2008-12-06 12:53   
I uploaded a patch that changes the language parser, so that it explicitly expects case/default statements in the switch block and puts the non-case statements afterwards into their own block scope.
(0000812)
fufu   
2008-12-10 10:26   
Looks good to me. I've attached an additional patch that turns some parse errors that can't happen anymore into assertions.

There's a slight degradation in the error message for "switch (0) { }" -- now it's just a "syntax error" while previously the message was "switch without case not supported" (because it parsed and failed later, when storing the case labels), but I think we can live with that.
(0000828)
Gnomi   
2008-12-23 19:57   
Applied both patches as r2454.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
583 [LDMud 3.3] Other crash sometimes 2008-11-23 14:27 2018-01-29 22:57
Reporter: willem Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version:  
Summary: TLS: context->client_CA free()'d while still in use
Description: If using OpenSSL, and the driver is invoked without --tls-trustfile, "context->client_CA" is freed, and the memory gets overwritten with other data. On one of my machines, "context->client_CA->num" always gets overwritten with 0x0, so it thinks it has no certificates, but doesn't crash. On another machine the value is instead a large integer. This produces a SIGSEGV when attempting to dereference "context->client_CA->data" which also contains garbage.

The problem occurs because SSL_CTX_set_client_CA_list() doesn't check to see if "context->client_CA" and "stack" are already the same. This is the case when no trustfile is specified. It will free "context->client_CA" immediately if it is not NULL, and replace it with "stack" (the same value, and a bad pointer).

Below is an untested patch that might fix the problem.
Tags:
Steps To Reproduce:
Additional Information: --- pkg-tls.c 2008-08-11 08:28:52.000000000 +0700
+++ pkg-tls.c 2008-11-24 01:43:35.000000000 +0700
@@ -389,6 +389,7 @@
     if (trustfile != NULL)
     {
        stack = SSL_load_client_CA_file(trustfile);
+ SSL_CTX_set_client_CA_list(context, stack);
     }
     else
     {
@@ -398,11 +399,6 @@
     {
        SSL_add_dir_cert_subjects_to_stack(stack, trustdirectory);
     }
-
- if (stack != NULL)
- {
- SSL_CTX_set_client_CA_list(context, stack);
- }
 }
 #endif

Attached Files:
Notes
(0001020)
Gnomi   
2009-04-12 14:03   
Fixed in r2543.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
582 [LDMud 3.3] Implementation crash always 2008-10-01 17:18 2018-01-29 22:57
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: Potential crash in db_conv_string() due to stack overflow
Description: db_conv_string() may crash with large argument strings.

As the mysql package is optional and not enabled by default, I set the priority to normal, not high.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: db_conv_string.diff (671 bytes) 2008-10-04 15:11
http://ldmud.eu/file_download.php?file_id=165&type=bug
Notes
(0000801)
zesstra   
2008-10-04 15:12   
Patch is attached.
(0000815)
zesstra   
2008-12-12 19:25   
Patch committed in r2443.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
581 [LDMud 3.3] Implementation crash always 2008-10-01 17:13 2018-01-29 22:57
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: high OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: Potential crashes in rename_object() and replace_program() due to stack overflows
Description: rename_object() and replace_program() in object.c may crash with large argument strings.

Note: the crash in rename_object() occurs _before_ the call to privilege_violation. Therefore any non-privileged object can cause a crash.
Tags:
Steps To Reproduce: replace_program("a"*8400000);
rename_object(ME, "a"*8500000+".c");
Additional Information:
Attached Files: objects.diff (5,330 bytes) 2008-10-04 16:54
http://ldmud.eu/file_download.php?file_id=166&type=bug
Notes
(0000802)
zesstra   
2008-10-04 16:55   
Patch is attached.
It fixes a memory leak in rename_object() as well. The new name was leaked in case the master disallowed the rename in privilege_violation().
(0000822)
zesstra   
2008-12-15 12:16   
Patch applied in r2451.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
580 [LDMud 3.3] Implementation crash always 2008-10-01 17:06 2018-01-29 22:57
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: high OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: Potential crash in load_object() due to stack overflow
Description: Large strings as arguments to load_object() in simulate.c may lead to crashes.
Tags:
Steps To Reproduce: load_object("a"*8000000);
Additional Information:
Attached Files: load_object.diff (2,398 bytes) 2008-10-04 15:02
http://ldmud.eu/file_download.php?file_id=164&type=bug
Notes
(0000800)
zesstra   
2008-10-04 15:02   
I attached a draft of a patch.
(0000820)
zesstra   
2008-12-14 18:05   
Patch applied in r2449.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
578 [LDMud 3.3] Implementation crash always 2008-09-28 16:24 2018-01-29 22:57
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: high OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: Potential crashes in regexplode(), process_string(), present_clone()
Description: f_regexplode(), process_string() and f_present_clone() in efuns.c may crash due to stack overflows if given large enough strings.
process_string() and f_present_clone() allocate temporary buffers on the stack holding the argument string.
f_regexplode() allocates only a structure of about 40 bytes per match, but if string and regexp match suffiently often, even this will exceed the available stack space. Low eval cost limits can be a workaround for the latter, as each match costs one tick. However, an 8MB stack will only have enough memory for about 174k Matches, so the eval cost limit has to be well below 174k.
Tags:
Steps To Reproduce: regexplode("ad"*50000000, "d", RE_OMIT_DELIM);
process_string(@@"+"a"*12000000+"@@");
present_clone("a"*12000000+"0000123");
Additional Information:
Attached Files: efuns_alloca_patch.diff (12,866 bytes) 2008-09-29 18:29
http://ldmud.eu/file_download.php?file_id=162&type=bug
efuns_alloca_patch-V2.diff (11,701 bytes) 2008-10-01 16:06
http://ldmud.eu/file_download.php?file_id=163&type=bug
Notes
(0000796)
zesstra   
2008-09-29 18:18   
Forgot regexp(), which is also affected, but in this case a huge array instead of a large string is needed and most muds limit the maximum array size.
I attached a patch for fixing these 4 issues in efuns.c, but have to do some more tests tomorrow.
(0000797)
zesstra   
2008-10-01 16:08   
I didn't like the repeated allocation of small structures on the heap. The curretn version of the patch uses a mempool for reducing the number of allocations and combines several structures in one block.
(0000817)
zesstra   
2008-12-14 15:54   
Applied the second patch (without 2 bugs) in r2446.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
570 [LDMud 3.3] Implementation tweak always 2008-09-10 15:54 2018-01-29 22:57
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: low OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: fatal() fails to dump a core if the master is not loaded
Description: fatal() calls shutdown() in the master and in that process assert_master_ob_loaded() is called. If there is no master object yet, exit(1) is called. In that way, a core dump is not available and to debug it, you have to reproduce with breakpoints at the right places in the debugger. I think, it would make more sense to call fatal() (again). fatal() will anyway detect that it was called recursively and directly dump a core by calling dump_core() without doing anything else which is the desired behaviour I guess.

Or do you see a special reason why the driver should exit normally in this case? After all some part of the driver called fatal()... (In my case it was called from slaballoc.c because of a double free.)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000819)
zesstra   
2008-12-14 17:35   
r2448 replaces the call to exit() by a call to fatal().

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
548 [LDMud 3.3] Efuns major always 2008-07-03 06:37 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version: 3.3.716  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version:  
Summary: restore_value is not reentrant
Description: I tried to call restore_value recursively (via privilege_violation e.g. for error handling) and it crashed:

(restore) Freeing lost shared_restored_values.
2008.07.03 12:31:12 Null pointer to assign_svalue().
2008.07.03 12:31:12 Current object was unpriv

Program terminated with signal 8, Arithmetic exception.
#0 0x080fef36 in dump_core () at simulate.c:587
587 *((char*)0) = 0/a;
(gdb) bt
#0 0x080fef36 in dump_core () at simulate.c:587
0000001 0x080fecf9 in fatal (
    fmt=0x81438f8 "remove_from_free_list: block %p, magic match failed: expected %lx, found %lx\n") at simulate.c:609
0000002 0x0811b3be in remove_from_free_list (ptr=0x8cb3bcc) at slaballoc.c:2307
0000003 0x0811c5d3 in large_malloc (size=67, force_more=0) at slaballoc.c:3306
0000004 0x0811a212 in mem_alloc (size=254) at slaballoc.c:1574
0000005 0x0811d9c6 in xalloc_traced (size=254,
    malloc_trace_file=0x8141830 "strfuns.c", malloc_trace_line=123)
    at xalloc.c:540
0000006 0x081097d5 in strbuf_grow (buf=0xbfce90ac, len=78) at strfuns.c:123
0000007 0x081096c1 in strbuf_add (buf=0xbfce90ac,
    text=0xbfce7f78 "' epilog' in '", ' ' <repeats 12 times>, "master.c' ('", ' ' <repeats 14 times>, "master') line 21\n") at strfuns.c:152
0000008 0x08109a0f in strbuf_addf (buf=0xbfce90ac,
    format=0x812ccd0 "'%15s' in '%20s' ('%20s') line %d\n") at strfuns.c:226
0000009 0x080b2070 in collect_trace (sbuf=0xbfce90ac, rvec=0x0)
    at interpret.c:18878
0000010 0x080b250e in dump_trace (how=1, rvec=0x0) at interpret.c:18950
0000011 0x080fee46 in fatal (fmt=0x8129598 "Null pointer to assign_svalue().\n")
    at simulate.c:632
0000012 0x0808ebd4 in inl_assign_svalue_no_free (to=0x8c58fec, from=0x0)
    at interpret.c:1464
0000013 0x0808ebba in assign_svalue_no_free (to=0x8c58fec, from=0x0)
    at interpret.c:1522
#14 0x080daac2 in restore_svalue (svp=0x8c58fec, pt=0xbfce931c,
    delimiter=44 ',') at object.c:8432
#15 0x080db707 in restore_array (svp=0x8c58fec, str=0xbfce931c)
    at object.c:7600
#16 0x080da6eb in restore_svalue (svp=0x8168178, pt=0xbfce931c,
    delimiter=10 '\n') at object.c:8299
#17 0x080dcc2d in f_restore_value (sp=0x8168178) at object.c:9095
#18 0x08094686 in eval_instruction (first_instruction=0x8cb3ba2 "\n",
    initial_sp=0x8168168) at interpret.c:8003
#19 0x080ae1f1 in apply_low (fun=0x8c77440, ob=0x8cb3bd4, num_arg=0,
    b_ign_prot=0, allowRefs=0) at interpret.c:16843
#20 0x080ae3e8 in int_apply (fun=0x8c77440, ob=0x8cb3bd4, num_arg=0,
    b_ign_prot=0, b_use_default=1) at interpret.c:16921
#21 0x080a92c4 in eval_instruction (first_instruction=0x8cb06e2 "an\a",
    initial_sp=0x8168148) at interpret.c:16191
#22 0x080ae1f1 in apply_low (fun=0x8c09b1c, ob=0x8cb07a4, num_arg=1,
    b_ign_prot=1, allowRefs=0) at interpret.c:16843
#23 0x080ae3e8 in int_apply (fun=0x8c09b1c, ob=0x8cb07a4, num_arg=1,
    b_ign_prot=1, b_use_default=0) at interpret.c:16921
#24 0x080ae852 in sapply_int (fun=0x8c09b1c, ob=0x8cb07a4, num_arg=1,
    b_find_static=1, b_use_default=0) at interpret.c:17082
#25 0x080af0c5 in apply_master_ob (fun=0x8c09b1c, num_arg=1, external=1)
    at interpret.c:17376
#26 0x08055cd8 in preload_objects (eflag=1) at backend.c:1252
#27 0x080c083c in main (argc=40, argv=0xbfcebc74) at main.c:612
Tags:
Steps To Reproduce: I made a testcase and will add the testsuite to svn soon.
Additional Information:
System Description
Attached Files: restore_value.diff (12,832 bytes) 2008-12-26 20:55
http://ldmud.eu/file_download.php?file_id=176&type=bug
Notes
(0000832)
Gnomi   
2008-12-26 20:44   
I uploaded a patch that puts all global variables for restore_object/value into one structure that can be stacked (the error handlers take care of them). save_object/value might have the same problem, but I can't see how they can be called recursively.
(0000890)
Gnomi   
2009-01-14 09:20   
Committed as r2490.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
538 [LDMud 3.3] Efuns feature always 2008-05-06 14:34 2018-01-29 22:57
Reporter: Bardioc Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version:  
Summary: New Package pkg-iksemel for driver that adds xml_parse() as well as xml_generate() (using libiksemel)
Description: New Package that adds XML functionality to the driver in the way of parsing an xml document into a array-based structure and back.

Based on bug report 326, but heavily modified (I did not include any of the socket stuff of the old patch)

The patch introduces two new efuns: xml_parse() and xml_generate(). While the first parses an XML document into an array-based structure, the second generates one out of this structure, thus x == xml_generate(xml_parse(x))

Currently only DOM is supported, however libiksemel even provides SAX methods, so if interested, I can extend it.

Patch includes documentation in doc/efun as well as a new mudlib/sys/xml.h header file.

To use the patch, apply it first and afterwards call 'autoreconf' inside src/autoconf. Then move the newly generated files src/autoconf/configure and src/autoconf/machine.h.in to src/

The newly generated 'configure' will include a --enable-use-iksemel.

You need the libiksemel, a lightweight iksemel library from Google. I choose it, cause Gawain used it and it turned out to be fairly useful.

Please tell me if you like it.

Greetings,

Bardioc@Evermore
Tags:
Steps To Reproduce:
Additional Information: I would like to thank Gnomi for his support in the development of this patch.

Additionally the patch includes a recreation of the src/autoconf/configure.in that obsoletes the second file aclocal.h in that directory. This is necessary as m4 as well as autoconf/autoreconf do in some versions no longer run properly.
This patch has been done by Gnomi too, well again Thanx!
Attached Files: pkg-iksemel.diff (46,448 bytes) 2008-05-06 14:34
http://ldmud.eu/file_download.php?file_id=119&type=bug
pkg-iksemel-v2.diff (45,637 bytes) 2008-05-06 16:11
http://ldmud.eu/file_download.php?file_id=120&type=bug
pkg-xml2-2505.diff (30,932 bytes) 2009-01-17 19:18
http://ldmud.eu/file_download.php?file_id=193&type=bug
bug538.diff (39,464 bytes) 2009-05-04 16:18
http://ldmud.eu/file_download.php?file_id=229&type=bug
Notes
(0000612)
zesstra   
2008-05-06 14:52   
Nice. Mhmm, the XMPP parser may be interesting for our friends from psyced, maybe they don't have to maintain a own implementation then but use the external lib.
I had only a quick glance, but could you check the diff for acconfig.h, config.h.in and configure.in in the patch? There seem to be more changes than only the ones for pkg-iksemel, e.g. config.h.in contains stuff from my patch for bug 0000527. ;-)
(0000615)
Bardioc   
2008-05-06 16:11   
Thank you very much Zesstra. I appologize for the part from your patch. I removed it in the new version 'pkg-iksemel-v2.diff'

The file acconfig.h however is removed by this patch as Gnomi integrated all necessary parts directly into configure.h.in.
(0000816)
Gnomi   
2008-12-14 10:31   
Applied as r2445.
(0000840)
Gnomi   
2008-12-29 13:19   
Fippo wants to comment on the choice of iksemel and offer an alternative, so I reopen this bug.
(0000841)
fippo   
2008-12-29 14:14   
(Last edited: 2008-12-29 14:16)
thanks gnomi

iksemel seems to be no longer maintained. If I recall correctly it was even 'dead' (in the sense of few/no commits) when it was hosted on jabberstudio.org. And there is only the initial import at google code.

In psyclpc we have an expat package which might be interesting. We never switched from our LPC parser to that because it was not really faster.
Most of the processing (building the data structures) was done in LPC via a set of callbacks, which made this very flexible (needed for parsing XMPP) but comparatively slow. Building the data structures on C level would probably make this better. I still have a diff against an unmodified ldmud at http://hancke.name/ldmud/expat2/
The configure bits are missing the but should be in psyclpc ( http://lpc.pages.de ).

I am not sure if I really like the structure of your XML nodes.
For working with it I always found xpath-style expressions useful. For example if you have XML like
<foo bar='baz'><q/><c/></foo>
and then access 'baz' as node["@bar"], the node "q" as node["/q"], "c" as node["/c"] and the first child of the node (q in this case) as node[1].
But that is mostly a matter of taste :-)

zesstra: we would have to maintain iksemel, too. And XMPP is - despite it's name - not really XML and you need lots of hacks to parse and generate it ;-)

(0000852)
Gnomi   
2009-01-05 10:12   
I don't mind supporting more than one XML library, but they should present the same interface to LPC. And as such I don't really like the SAX interface, because LPC is an amateur language and so reading an XML file should be as easy as xml_parse(read_file("a.xml")).
(0000912)
Bardioc   
2009-01-17 07:39   
I uploaded a new Package that has the exact same interface as the old one, but now uses libxml2 instead of libiksemel. It does not remove pkg-iksemel.c but introduces a new pkg-xml2.c

The diff inside of the tar.bz2 will modify autoconf/configure.in and integrate a new configuration option --enable-with-xml2. It also checks that only xml2 or iksemel is used, as they define the same efuns (mutually exclusive).

Gnomi is currently checking this. Hope it will be added to the driver soon.
(0000913)
Bardioc   
2009-01-17 07:45   
Ok now the diff-file includes even the new files.

This patch was made against revision 2498
(0000924)
Bardioc   
2009-01-17 19:19   
Added new version against revision 2505 that fixes a small bug in the xml parsing (added 0 elements for comments).
(0001077)
Gnomi   
2009-05-04 16:21   
I attached a modified version of Bardioc's patch that uses the xmlreader/xmlwriter API, so there's no need to build an intermediate DOM representation anymore.

It adds an arraylist.c which helps to build an array whose size is unknown.
(0001108)
Gnomi   
2009-05-18 03:43   
libxml2 support committed as r2585.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
535 [LDMud 3.3] Efuns minor always 2008-03-28 06:50 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version: 3.3.713  
Product Build: 2363 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version:  
Summary: set_input_to should be reset before a heart_beat or call_out
Description: If there is already an input_to running and a heart_beat or call_out starts a new one, this new input_to might be ignored because set_input_to is still set to true.

Greetings,
Gnomi
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0000724)
Gnomi   
2008-07-11 05:52   
This is more complicated. If you enter a command (using "!") during an input_to and this command does something like input_to, remove_input_to, input_to, then remove_input_to will not clear the set_input_to flag because of the already pending input_to and thus the second input_to will not be executed.

Because of this I suggest using the in bug 0000477 proposed eval_number and save it in set_input_to, so set_call can always compare it with the current number.
(0000725)
Gnomi   
2008-07-11 05:57   
The eval number has to be saved in the input_to_s structure, not like set_input_to in the interactive_s.
(0000937)
Gnomi   
2009-01-28 17:25   
Committed as r2512.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
527 [LDMud 3.3] Portability minor always 2008-01-27 15:28 2018-01-29 22:57
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: New version of the Mersenne Twister needed for 64 bit platforms
Description: The Mersenne Twister RNG uses a 32-bit word length. I think for 64-bit platforms we need the MT19937-64 with a 64-bit word length.
Right now the drivers PRG is limited to the range of 0 - 2^32-1, which should be extended on 64-bit platforms.
I will have a look at that later, but if anyone else has something ready, please feel free ;-)
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files: sfmt-V4.diff (79,385 bytes) 2009-01-03 16:49
http://ldmud.eu/file_download.php?file_id=178&type=bug
Notes
(0000593)
zesstra   
2008-01-27 18:20   
I just had a look at the 64-bit version of the MT and read a note from its author. He states, that the SIMD-oriented Fast Mersenne Twister (SFMT), a variant of the MT, is much faster:
"It is faster than the original MT, even in non-SIMD CPUs, and has better assurance of randomenss."
The SFTM homepage states:
"SFMT is much faster than MT, in most platforms. Not only the speed, but also the dimensions of equidistributions at v-bit precision are improved. In addition, recovery from 0-excess initial state is much faster."
The license of SFMT is the same as for the original MT.
Details can be found at:
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html

The speed comparisons look quite impressive. Has anyone an opinion about this?
(0000617)
zesstra   
2008-05-07 15:50   
If there is nobody speaking against the SFMT, I would like to give it a shot and start working on a patch integrating it into the driver, with 32-bit and 64-bit variants and probably the optimized code for SSE2, Altivec and CPUs without both. Just to let you know. ;-)
(0000621)
zesstra   
2008-05-09 18:43   
OK. First version of a patch which replaces the MT with the SFMT-1.3.3 and make the PRNG usable in 64-bit environments.
random.c and random.h are a wrapper around the functions of the SFMT.
The SFMT is contained in a new sub-directory src/random/, because it contains multiple Files for different period lengths and optimizations.
random.c includes random/SFMT.c, so a number of functions should be inlinable by the compiler.
I removed non-necessary files from the SFMT (like Makefile, most of the documention), but I didn't remove functions from the source, which we don't use. The reasoning behind this is, that it is easier to update the SFMT if we use their source more or less 'as is'. If it really disturbs someone, we may remove some public functions like get_idstring() and 2 functions which generate arrays of random numbers.
I added a --with-random-period-length to autoconf/configure.in and a corresponding define to config.h.in for choosing the period length of the SFMT (default: 19937 -> 2^19937 - 1, supported are several length between 2^607-1 to 2^216091-1).

Additionally the patch includes my changes for seeding the PRNG from /dev/urandom or /dev/random (see 0000515) which make it impossible to guess the seed and removes the problem that the 32-bit integer seed can only make 2^32 kinds of initial state.

However there is something still missing: I did not mange until now to include the necessary autoconf magic to automatically set HAVE_SSE2 and -msse2 (and the corresponding altivec variants). If anybody has a working solution for this I would be delighted. ;-)

If anybody is interested to test the patch, I will be happy about comments.
(0000638)
Gnomi   
2008-07-01 04:35   
The command line option --randominit seems somewhat limiting. Wouldn't it be better to specifiy the random device name itself? (And if it's missing stick to the system clock.)

In random.c random.h should be included before random/SFMT.c, otherwise the definition of MEXP comes too late. I also got the following warning:
  random.c: In function 'seed_random':
  random.c:82: warning: passing argument 1 of 'init_by_array' from incompatible pointer type

I can't comment on the SFMT itself, so go for it.
(0000648)
zesstra   
2008-07-01 18:40   
Ok, the incompatible pointer type was due to use of uint32 in the driver and uint32_t in the SFMT, and I missed one. I use now in the random wrapper consistently uint32_t (and uint64_t).

Generalizing --random-init is definitely a good idea, it can now be used to specify arbitrary filenames. (We may think about deprecating --random-seed as you could give a constant seed in a file. It would be nice to change the behaviour of -random-seed instead of introducing --random-init, but I don't know, if we can do that... ;-) Or maybe --random-device would also be appropriate.)

Mhmm, what about adding a configure switch to specify the default filename/device to use for seeding the PRNG (defaulting to /dev/urandom?). If that is non-readable, the driver will use the clock as fallback as always, if the given file is non-readable. Setting the filename to an empty string would also cause the driver to use the system clock.

One thing may be interesting as well: we could store the file name for the uptime and enable re-seeding the PRNG, e.g. by efun (specifying files similar to the garbage_collection() efun) or automatically at some point in the backend.

BTW: any autoconf experts there, who know some working magic to enable HAVE_SSE2 and -msse2 (and the corresponding altivec variants)?
(0000821)
zesstra   
2008-12-15 07:49   
Fuchur asked about the difference in performance between SSE2-optimized and non-optimized versions of the SFMT (I don't have any PowerPC available for Altivec). His idea was to skip any automatic detection of SSE stuff during configure and don't use any fancy compiler settings.

Execution time for 300k numbers (including loop overhead):
foreach(int i: 300000) random(__INT_MAX__);

SFMT, i386: 172ms
SFMT, x86_64 85ms

SFMT-sse2, i386: 137ms
SFMT-sse2, x86_64: 82ms

As you see, there is no difference on x86_64 platforms. The reason is AFAIK, that on this platform gcc implicitely uses the SSE stuff, which is good news. On i386 platforms, there is a larger difference. Don't know, if it warrants the effort to find some autoconf magic...

One odd thing:
Old PRNG, i386: 101ms
Old PRNG, x86_64 80ms

As you see, the old PRNG ist actually faster than the new one. This should not be the case if you compare with the speed comparison the authors did:
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/speed.html
(0000846)
zesstra   
2009-01-03 16:48   
Im preparing the latest SFMT patch now and will probably apply it tomorrow.
I added some improvements, e.g. changing the "public" functions of the the SFMT to static ones, because they are only used through the wrapper of the driver. Now the complete stuff of the PRG is inlined into one function (random_number).

Timings for 1000k numbers (foreach(int i: 1000000) random(__INT_MAX__);)
SFMT, 64: 285ms
SFMT, 32: 550ms
SFMT, 32-sse2: 470ms

Alt, 64: 255ms
Alt, 32: 475ms

I am still curious about this unexpected increase in execution time, but I guess, it is not that significant... Most of the time (about 65-75%) is spent in eval_instruction() anyway (according to a statistical sampling while generating random numbers), see below.

SFMT-32:
- 64.4%, eval_instruction, ldmud.random
- 12.7%, random_number, ldmud.random
- 8.1%, check_object_shadow, ldmud.random
- 4.1%, check_all_object_shadows, ldmud.random
- 3.5%, int_free_svalue, ldmud.random
- 3.5%, assert_stack_gap, ldmud.random
- 2.7%, free_svalue, ldmud.random
- 1.0%, f_random, ldmud.random

SFMT-32-sse2:
- 62.8%, eval_instruction, ldmud.random.sse2
- 12.1%, random_number, ldmud.random.sse2
- 9.4%, check_object_shadow, ldmud.random.sse2
- 4.6%, assert_stack_gap, ldmud.random.sse2
- 4.1%, free_svalue, ldmud.random.sse2
- 3.4%, check_all_object_shadows, ldmud.random.sse2
- 3.3%, int_free_svalue, ldmud.random.sse2
- 0.5%, f_random, ldmud.random.sse2

SFMT-64:
- 71.6%, eval_instruction, ldmud64.random
- 11.8%, random_number, ldmud64.random
- 7.5%, assert_stack_gap, ldmud64.random
- 4.3%, free_svalue, ldmud64.random
- 3.8%, int_free_svalue, ldmud64.random
- 1.0%, f_random, ldmud64.random

MT-32:
- 64.9%, eval_instruction, ldmud
- 9.0%, check_object_shadow, ldmud
- 6.6%, random_number, ldmud
- 4.4%, assert_stack_gap, ldmud
- 4.1%, int_free_svalue, ldmud
- 3.8%, check_all_object_shadows, ldmud
- 3.6%, genrand_int32, ldmud
- 3.1%, free_svalue, ldmud
- 0.6%, f_random, ldmud

MT-64
- 75.2%, eval_instruction, ldmud64
- 7.9%, assert_stack_gap, ldmud64
- 4.1%, random_number, ldmud64
- 4.1%, free_svalue, ldmud64
- 3.9%, genrand_int32, ldmud64
- 3.4%, int_free_svalue, ldmud64
- 1.4%, f_random, ldmud64
(0000847)
zesstra   
2009-01-04 14:33   
Committed as r2470.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
522 [LDMud 3.3] Efuns minor always 2008-01-04 18:55 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3  
Product Build: 3.3.716-2363 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Starting an input_to from within an ed session doesn't behave intuitively
Description: From within an ed session you can call commands using a bang. But if that command starts an input_to the driver shows the prompt of that input_to, but the user input stills goes to the ed session. It is not until the ed session ended that the input_to function gets the input.

A simple solution would be to put the ed session into the input_to list, so it can be stacked just like a normal input_to. (A long term solution is already mentioned as TODO in ed.c, let the mudlib do the ed command interpretation.)

Greetings,
Gnomi
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files: bug522.diff (53,645 bytes) 2009-05-14 16:14
http://ldmud.eu/file_download.php?file_id=239&type=bug
Notes
(0000939)
Gnomi   
2009-01-29 08:15   
I'd like to do this, but putting the ed_buffer pointer into the input_to structure would mean subordinating them to interactive_t instead of object_t. As a result, the ed session would be destroyed on a relogin just as input_tos are destroyed now.

Furthermore there is a TODO item that goes in the opposite direction:
 * TODO: Make it possible to attach an editor to any object, and let
 * TODO:: the editor communicate via efuns - no direct io.

Despite all that I would like to do this, because input_to and ed share a lot similarities.
(0001107)
Gnomi   
2009-05-14 16:14   
I uploaded a patch that does that.
(0001168)
Gnomi   
2009-05-27 14:17   
Committed as r2595.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
479 [LDMud 3.3] Compilation, Installation minor always 2006-07-19 11:07 2018-01-29 22:57
Reporter: lynx Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.713  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: disable TLS at runtime no longer possible
Description: in earlier versions of ldmud you just needed to leave out --tls-key
and the driver would not activate its TLS abilities. nowadays the
behaviour has changed, openSSL looks for default certificates and
complains if it doesn't find any.

we find it very practical to compile ldmud with TLS because the admin
might at a later time decide to use it and can then simply activate it
in the configuration files.

so we think either openSSL should not complain after not being successful,
or we should be able to provide a --no-tls flag to the driver.
of course we can also redirect ldmud output to /dev/null ... ;)
then the admin will never know what went wrong.. like with a microsoft product.
Tags:
Steps To Reproduce:
Additional Information: this sort of output is making casual new ldmud users nervous:

2006.07.19 17:51:44 LDMud 3.3.714 (Build 2308) (development)
2006.07.19 17:51:44 TLS: (OpenSSL) x509 keyfile 'key.pem', certfile 'cert.pem'
2006.07.19 17:51:44 TLS: (OpenSSL) trusted x509 certificates from directory '/et
c/ssl/certs'.
2006.07.19 17:51:44 TLS: Error setting x509 keyfile:
2006.07.19 17:51:44 TLS: SSL error:02001002:system library:fopen:No such file or
 directory.
2006.07.19 17:51:44 TLS: SSL error:20074002:BIO routines:FILE_CTRL:system lib.
2006.07.19 17:51:44 TLS: SSL error:140B0002:SSL routines:SSL_CTX_use_PrivateKey_
file:system lib.
2006.07.19 17:51:44 Random seed: 0x44be4700
2006.07.19 17:51:44 Attempting to start erq '/home/nt/psyced/bin-linux/erq'.
Attached Files:
Notes
(0000514)
fippo   
2006-08-16 03:55   
tls is disabled, as the driver does not find the default certificate files.
Are you sure that previous versions simply disabled tls and did not generate error messages?
(0001120)
Gnomi   
2009-05-19 17:40   
TLS can now be deactivated by default using configure (--with-tls-keyfile=no) and still used using the command line option --tls-key. (The other way around is also possible using '--tls-key none' on the command line to deactivate it.)

Committed as r2590.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
398 [LDMud 3.3] Runtime minor always 2005-08-25 16:15 2018-01-29 22:57
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3  
Product Build: 3.3.710 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: ed/check_valid_path leaks file name
Description: Starting ed("file", "ed_ends"), doing a garbage collection meanwhile and then exiting ed with 'x' leaks the filename. This is the output from a second garbage collection after that:

2005.08.25 21:27:56 --- Garbage Collection ---
freeing small block 0x08cbfcb8 (user 0x08cbfcc0) simulate.c 3446
  By object: obj/zauberstab#10
  By program: i/zauberstab/zauberstab.c (/i/zauberstab/zlib.inc) line:407
08cbfcd4: 02 01 00 00 00 00 00 00 11 00 00 00 00 00 77 2f ..............w/
08cbfce4: 67 6e 6f 6d 69 2f 70 72 6f 6c 61 6e 67 2e 79 00 gnomi/prolang.y.
08cbfcf4: 00 98 e2 08 06 09 00 38 c9 6c 2e ed 78 f1 16 09 ..â....8Él.íxñ..
08cbfd04: 04 00 00 ...

1 small blocks freed
2005.08.25 21:27:56 GC freed 0 destructed objects.

Greetings,
Gnomi.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0000662)
Gnomi   
2008-07-02 10:53   
During a GC count_ed_buffer_refs() counts the reference to this string, but clear_ed_buffer_refs() does not clear it in the beginning. All tabled strings get their refcounts cleared automatically, so when this string is not tabled its reference count will be doubled and this will be found by the next GC.
(0000663)
Gnomi   
2008-07-02 12:10   
This is not the only missing refcount clearance. I found a second one also in ed.c, and there are a lot less clear_string_ref() calls than count_ref_from_string() calls, so I have to check them all. (Most of these missing calls maybe okay, because the compiler puts all of its strings into the table, but I have to take a look to make sure of that.)
(0000827)
Gnomi   
2008-12-23 19:26   
Fixed in r2452.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
375 [LDMud 3.3] Runtime minor always 2005-03-17 23:42 2018-01-29 22:57
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: call_out() timing is incorrect
Description: Assuming an alarm interval of 2: a call_out("fun", 2) done from inside a heartbeat will have fun() executed inside the current backend cycle, and not the next.

This behaviour is caused by the fact that the call_out timing is based on relative delays, instead of being tied directly to the current time. On the other hand, some old code exploits this behaviour to have functions execute after the current player commands, but before the next.
Tags:
Steps To Reproduce:
Additional Information: The basic problem can be solved by storing absolute execution times into the call_out list; but I don't see any way to preserve the old code behavior in this.
Attached Files: bug375.diff (5,020 bytes) 2009-05-26 14:17
http://ldmud.eu/file_download.php?file_id=241&type=bug
Notes
(0000357)
peng   
2005-03-19 13:01   
Iirc we use call_out("fun",0) to achieve the goal of putting the call_out behind the current commands and just before the next ones. Main reason for this is resetting evals for some expensive operations. But I may wrong here.
(0000973)
zesstra   
2009-03-04 16:39   
call_out chains for preventing 'too long eval' is standard behaviour, yes.

I suggest, if we change the timing behaviour, we should do it in 3.5.x.
Any opinions, if we want to change it or declare it a feature...?
(0000976)
Gnomi   
2009-03-04 17:14   
I think the timing problem should be fixed in 3.5 (I wouldn't mind if we do it in 3.3). I don't see any problem with old code behavior: If you wan't the old behaviour you use call_out("fun",0).

As for too long eval errors: When calling from a heart_beat you don't want the old behavior (heart_beat and call_outs from the same object share their eval count in each cycle).
(0000979)
zesstra   
2009-03-04 17:52   
I thought to not force wizards to check and change their code between e.g. 3.3.719 and 3.3.720. Probably the code Lars described is rather rare. But I guess, very difficult to find. But I could ultimately also live with fixing it in 3.3.

You are right concerning the eval costs. I meant call_out chains in general, not with a specific delay of 2 or 0, which are not a good idea, right. When we migrated from our old LP driver to LDMud 3.3 we had about 2-3 dozens call_out(...,0) in a call_out, which resulted in a callout chain with zero delay, was quite funny. ;-)
(0001125)
Gnomi   
2009-05-20 17:31   
(Last edited: 2009-05-21 06:58)
I don't think, wizards have to check their code. If someone wanted that behavior of starting a call_out directly after a heart_beat he would have called call_out("fun", 0). If there's somewhere a call_out("fun", 2) from a heart_beat it almost never was meant to start directly after the heart_beat but 2 seconds later. That's why I don't think this bugfix would break code.

(0001164)
Gnomi   
2009-05-26 14:19   
I uploaded a patch that fixes this by starting the call_out cycle before heart_beats are handled (call_outs are not executed, but the first delay is decremented and last_time is updated, so it does correctly reflect the timing during the heart_beats).
(0001166)
zesstra   
2009-05-26 17:28   
Looks good to me, I did not expect it to be that simple. :-)
(0001169)
Gnomi   
2009-05-27 14:24   
Committed as r2596.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
297 [LDMud 3.3] Networking feature N/A 2004-11-27 01:00 2018-01-29 22:57
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.10  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version:  
Summary: Better buffering of data sent to players
Description: Short: Better buffering of data sent to players
From: Gnomi
Date: 2002-07-14
Type: Feature
State: New
Driver: 3.2.9-dev.440

If too much data is sent to the player over a slow connection, it can happen
that the socket_write() consistently fails with EWOULDBLOCK (== EAGAIN under
Linux). The driver then discards the message even if a few seconds later the
transmission would succeed.

Reason for this behaviour is that the buffer for text to send is of fixed size
and has to be emptied. By making the buffer a FIFO (and extending the backend
loop by a new call to some send_pending_data()) this problem could be solved.

When implementing this, consider that the mudlib must be able to detect and
shutdown continually starved connections before the buffers grow too big.
Maybe a control efun set_max_buffer_size() for each interactive (with an
'unlimited' setting available). This might require calls to forcefully
'abandon' data from the mudlib, and an internal setting to let data expire
once a certain buffer size is reached (set_buffer_mode(): BUF_LIMITED,
BUF_UNLIMITED, BUF_FIFO).
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: writebuffer.diff (40,041 bytes) 2009-01-05 04:47
http://ldmud.eu/file_download.php?file_id=180&type=bug
writebuffer2.diff (31,638 bytes) 2009-04-08 03:52
http://ldmud.eu/file_download.php?file_id=204&type=bug
Notes
(0000851)
Gnomi   
2009-01-05 04:44   
I attached a patch that implements the write buffers without pthreads.

The buffer has (as it were with pthreads) a limit that is configured during compile time or given as a command line argument. So now we need to give the mudlib some control over the buffer. I'm thinking about an efun for setting the maximum buffer size and a driver hook to inform about abandoned data.
(0000889)
Gnomi   
2009-01-14 09:06   
First part is committed as r2489.
(0001011)
Gnomi   
2009-04-07 15:22   
I attached a patch for the second part (configuration efun and driver hook). The driver hook is called in the backend loop (while processing dirty interactives) because I didn't want to call LPC code from add_message, which is not reentrant.
(0001045)
Gnomi   
2009-04-16 12:59   
Committed as r2551.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
243 [LDMud 3.5] Efuns feature N/A 2004-11-26 23:54 2018-01-29 22:57
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.8 and before  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: add_action() on closures
Description: Short: Allow add_actions() on closures
Date: 2001-05-16
From: Gnomi
Type: Feature
State: New

Allow to add actions to closures.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: closure-actions.diff (22,604 bytes) 2009-06-15 06:25
http://ldmud.eu/file_download.php?file_id=247&type=bug
Notes
(0001206)
Gnomi   
2009-06-15 06:30   
I attached a patch, that uses a callback_t for saving the function to call upon an action (thus allowing a closure). There is some overhead (we have no arguments to save, on named functions the object to be called is saved twice), but we can rely on the existing callback infrastructure.

As a side effect actions on static functions called using command() don't throw errors anymore (because execute_callback ignores them).
(0001221)
Gnomi   
2009-06-18 03:27   
Committed as r2662.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
71 [LDMud 3.3] Networking minor always 2004-06-18 02:29 2018-01-29 22:57
Reporter: lynx Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: binary_message cannot flush zero bytes?
Description: is this intended behaviour or a bug:

when using flag "1" with binary_message
zero bytes contained in the data will be
filtered, no matter if given as string or
int*

in fact i don't feel like the binmsg doc
is absolutely clear on the meaning of its
flags..

thanx
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001123)
Gnomi   
2009-05-19 18:33   
Hmm, that's because of the connection charset. Regardless of the given bitvector, \0 and \n are always removed from it. (\n is treated specially in add_message.)
I don't see any necessity for removing \0. Any opinions on allowing \0 in a connection charset?
(0001126)
Gnomi   
2009-05-21 07:48   
I stand corrected, there's a special condition for binary_message that a character has to be != 0. I think that condition can be removed, too.
(0001170)
Gnomi   
2009-05-27 16:03   
I fixed this in r2597.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
52 [LDMud 3.3] Compilation, Installation tweak always 2004-04-19 00:09 2018-01-29 22:57
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version:  
Summary: Use crypto functions from ssl libs when available.
Description: If the ssl-libs are available, use their implementation of sha1() and md5() instead of compiling our own. This of course requires checking for the existence of those libs, and wrapping those functions into my-xxx files.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000506)
fippo   
2006-05-07 07:05   
the addition of hash() resolves this bug (more or less, I would to let the old-style md5() and sha1() raise errors sometime)
(0000825)
zesstra   
2008-12-15 13:45   
It would be much nicer to call hash() by md5() and sha1(), if available, than to deprecate them. In fact, I prefer the latter in mudlibs, because I don't have to check with __EFUN_DEFINED__() or use an sefun.
If we want to deprecate md5() and sha1(), I suggest to make OpenSSL a requirement for the driver.
(0000829)
Gnomi   
2008-12-26 10:02   
I like the new hash() function, because the development of cryptographic algorithms will continue (NIST is currently searching for the next hash function, which is to be named SHA-3) and I don't like adding new efuns for each new algorithm.

What I don't like is the dependancy on OpenSSL (due to its license conditions). So I propose to always have a hash() and a hash_crypt() efun (the latter should be similar to md5_crypt), that uses OpenSSL or GCrypt (when using GNUTLS) or the internal md5 and sha1 routines.
(0000834)
zesstra   
2008-12-29 05:44   
I fully concur that hash() is nice. I am just not the opinion that the bug is solved and we should just obsolete md5() and sha1().
If we actually move the functionality of md5() and sha1() as fall-back into hash() so that it is always available independent of OpenSSL, it is fine for me.
(0001019)
Gnomi   
2009-04-12 13:30   
Since r2542 hash() is always available and uses OpenSSL, libgcrypt (used by GnuTLS) or the internal md5() and sha1() implementations. I marked md5() and sha1() as obsoleted by hash().

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
666 [LDMud 3.5] Runtime feature N/A 2009-06-24 08:13 2017-10-04 21:35
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version: 3.5.0  
Summary: RfC: Type-checking at run-time
Description: Currently, types are checked at compile-time (if checked at all). One consequence is, that it is not possible to ensure that functions are only called with arguments of the correct type. Which is the reason for the existence of
if (!stringp(arg) && !closurep(arg))
   handle_error(); // e.g. raise_error().
at the beginning of many functions to ensure correct input data ('garbage in - garbage out').

I would like to discuss an optional type-checking at run-time (restricted to stuff which can't be checked at compile-time, e.g. function arguments during call_other()), which can be enabled by a pragma 'runtime_type_check' (Prequesite is save_types, which could IMHO be implicitly enabled then.)
This way programmers don't have to check their arguments themselves but just rely on the correct types if they use '#pragma runtime_type_check'.
We may have to check how big the run-time impact of such an optional check (for programs without that pragma) is. (If programs use the pragma and don't check in LPC, we improve performance.)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001233)
Gnomi   
2009-06-24 10:09   
I think it's a good idea, especially for library code.

Do we want to check only call_others or internal calls as well?
For call_others the overhead is insignificant, but for internal calls it might have a small impact. On the other side the compile-time type checks are insufficient for internal calls (because of 'mixed' variables or overriding functions with other argument types).

Do we want to check unsafe assignments to variables (a mixed or unknown value to a variable with a type != mixed)?
(0001234)
Sorcerer   
2009-06-24 10:20   
I agree that this would be a major improvement.

It would get rid of a lot of typechecking that is being done explicitely in the LPC-code right now. It would be very nice to have it for internal calls as well if it does not have a too severe impact on performance - nevertheless for call_other it seems even more important to me (for all that stuff that is handled by central applications that receive calls from a lot of programs of different coders).

I personally like the idea of warnings at unsafe assignments though I would do that only if strong_types or even strict_types has been declared.
(0001235)
zesstra   
2009-06-24 11:08   
Yes, I would also use it especially for library code. :-)

Originally I thought, a check for inter-object calls would sufficient, but because of the behaviour Gnomi mentioned, Im afraid, we should check intra-object calls as well. Which contradicts my wish to decrease function call overhead for intra-object calls. :-( So I have no definite position on this yet.

Warnings for 'unsafe' assignments might be a good idea, but we should do that in a third step and after evaluating the run-time impact. (I would see function calls/arguments as first step and definitely wrong assignments as second step.)

I agree, that all of this should only be in effect for strong_types/strict_types, for programs using weak_types it is probably anyway useless (too much work).
(0001236)
invisible   
2009-06-24 19:28   
(Last edited: 2009-06-24 19:32)
The really interesting question about performance is: would it be slower than the existing "if( !stringp(foo) && !closurep(foo) )"s?


Another point: take the example above: foo would be declared as 'mixed' here, like eg.

void bar(mixed foo) { if(...) ... }

How shall the driver check a type against mixed? Strictly speaking if we want to get rid of that if() we would have to declare the function somewhat like

void bar(string|closure foo) { ... }


For any other type than mixed checking would be a nice feature, but OTOH it would be rather inconsistent simple because there *is* a 'mixed' type at all, that has to be checked (if at all) manually anyways.

Looking at it that way the existing checks (e.g. at assignments from call_other) seem sufficient; the mere existence of 'mixed' makes LPC not inherently typesafe, thus there is no "clean" way to introduce type checking...

(0001237)
zesstra   
2009-06-25 04:04   
Doing the check in C will be significantly faster (at least an order of magnitude, I guess) than in LPC. However, not all functions check their argument types. Some wizards forget it, some are too lazy (both would profit in theory), some don't think it is necessary for the specific function.

I admit, my example above it not the best one, because that function argument would be mixed and then checks of the driver are pointless/not possible.
A syntax like void bar(string|closure foo) would be nice for this, but (because IMHO only a tiny fraction of functions use 'mixed' arguments) not a prerequisite for a run-time type check to be useful.

I don't think it is inconsistent. If you deliberately use 'mixed' you just tell the driver that you don't care (this time) and that the driver should not care, thats all. Why should it be inconsistent to check all other types, only because you have a type which can hold any type? If I don't use mixed (I think I wrote only 5-10 functions accepting 'mixed' in the last years) and have a string argument, I would still be happy if the driver takes care that my function is only called with a string argument.
(0001238)
invisible   
2009-06-25 19:22   
We use mixed very often for functions that offer different ways of calling. I agree this is not 100% clean either, but our coders are used to it :-) And of course in that case typechecking is up to the coder anyways.
(0001239)
_xtian_   
2009-06-26 02:46   
What about the zero? (as an unitialized variable or destructed object)
Should it be treated like an int like in many error messages or as a special case of the declared argument variable type?

example:

void dance(object who);

...
object ob;

dance(&ob); // unitialized, but maybe I want to get a referenced object back
ob= ...;
destruct(ob);
dance(ob); // destructed object, syntactically this is still type 'object'
(0001240)
Gnomi   
2009-06-26 02:56   
Zero has to be considered as an element of every type. Otherwise this would break a lot of code.
(0001250)
Bardioc   
2009-09-04 11:57   
I really really really really want this ;-) My whole LIB contains a LOT of checks just for types. We introduced a system like this for every lib method in this way:

void dance(object who, int foo)
{
    check(who, IS_OBJECT, foo, IS_INT);

    ...
}

It produces something like 'Bad argument 2 to dance(): expected 'int' but got 'object'.'

its OK, but i would love to get rid of these ;-)
(0001251)
zesstra   
2009-09-04 12:14   
Actually, I started working on these checks yesterday on a private branch. There is still quite a lot to discuss and decide, but some first patches will probably find their way into trunk during the next weeks.
The first problem is that svalues and vartype_s/fulltype_s (typeid_t, typeflags_t) use very different schemes to encode types and modifiers.
(0001568)
zesstra   
2009-10-28 11:28   
I had a look today at the possibility for type-checks on variable assignments. This is not so easy, because the compiler just generates F_ASSIGN/F_VOID_ASSIGN, which transfer/copy data from one svalue to another. In this case, there is no data available to decide, which type the destination svalue should have.
In the case of global variables, this data at leasts exists as variable_t.type in ob->prog->variables, but in case of local vars, this information is lost after compilation.
So we have to make the type info available first. Therefore I will concentrate first on type-checks upon function calls.
(0001575)
zesstra   
2009-10-31 10:23   
ok. experimentally in 3.5. (trunk) now:
type checks at runtime are enabled by a pragma 'rtt_checks'. Currently the argument types upon function calls are checked. The checks depend on the pragma set in the defining program, not in the inheritee.
If you like to test it, I am happy about feedback. But keep in mind, that it is experimental and there are surely errors.
(0001579)
zesstra   
2009-11-01 16:44   
I added checks for the correct return types when returning from lfuns and sefuns.
Interestingly, this caused more errors in our mudlib so far than the checks for function arguments... ;-)
(0001583)
zesstra   
2009-11-02 16:22   
Bardioc notified me that it would be better to accept structs having the declared one as a base. ;-) So r2793 changed that behaviour and does not check to type identity anymore.
(0001602)
zesstra   
2009-11-04 18:22   
restore_object() now checks the types of restored variables (if the restored entity from the savefile has the same type as the variable the data was restored to).
Similarly restore_struct() checks the types of the restored data with the declared types of its members.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
850 [LDMud 3.5] Networking feature N/A 2016-10-11 18:54 2017-10-04 21:24
Reporter: zesstra Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version: 3.5.1  
Summary: built-in support for address/name resolution
Description: Adress/name resolution facilities are a fundamental feature of network nodes, and its getting even more important with IPv6. The usual recommendation in various RfC is to store names, not addresses and to not design protocols to rely on IP addresses.
I think, that the driver should offer built-in facilities instead of only an ERQ-based approach.
This feature should also offer an asynchronous lookup with callback.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002278)
zesstra   
2016-10-12 18:55   
Ideas to check:
getaddrinfo_a() on systems with glibc
http://www.corpit.ru/mjt/udns/udns.3.html
https://c-ares.haxx.se/

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
702 [LDMud 3.5] LPC Compiler/Preprocessor minor N/A 2009-11-05 14:56 2017-10-04 20:57
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: low OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: RfC: Remove some pragmas
Description: I thought about some pragmas and if we still need them in 3.5.

+ combine_strings, no_combine_strings: Is there a real advantage of no_combine_strings? Does need the behaviour of no_combine_strings?

+ verbose_errors: would it be harmful to always enable that it? Honest question, I don't even know a program in MG which does not use it.

+ local_scopes, no_local_scopes: Are there still Muds with more than sporadic programs which need no_local_scopes?
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001609)
_xtian_   
2009-11-05 15:51   
Never seen a MUD where this would be a problem.

Additionally I would propose activating warn_deprecated
This means less pain changing the driver and mudlib code in the long run.
(0001611)
zesstra   
2009-11-05 16:31   
I think, that suggestion makes sense, because it warns Mud admins and they can turn the warnings off with the auto include hook.
(0001733)
zesstra   
2010-02-15 19:17   
Will do so for 3.5.
(0001737)
zesstra   
2010-02-16 17:50   
In r2866 - 2868 I removed the pragmas (no_)combine_strings, verbose_errors and (no_)local_scopes. All these are being ignored by the lexxer. The behaviour of combine_strings, verbose_errors and local_scopes is now always enabled.

r2869 enables warn_deprecated by default.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
785 [LDMud 3.5] Networking minor N/A 2011-08-22 14:32 2017-09-30 19:50
Reporter: zesstra Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.3.721  
Summary: Possibility to reload server private key + cert
Description: We can reload the CAs certificates and trusted certs with tls_reload_certs(), but I could not find a possibility to reload the server key + cert, e.g. when the cert expired. It is a pity to end a (long) uptime just for reloading some cert, so there should be a possibility to do that during the uptime.
Tags:
Steps To Reproduce:
Additional Information: http://www.gnu.org/software/gnutls/reference/gnutls-gnutls.html#gnutls-certificate-set-x509-key-file
http://www.openssl.org/docs/ssl/SSL_CTX_use_certificate.html
Attached Files:
Notes
(0002176)
zesstra   
2012-12-09 11:47   
Gnomi, I take the liberty to assign this to you since you anyway work on this stuff. ;-)
(0002256)
zesstra   
2015-05-23 12:24   
Gnomi: I believe, this was already fixed, right?
(0002282)
Gnomi   
2017-09-30 19:50   
tls_refresh_certs() now also reloads the server key and certicate.

Commit: db9efaeab56581cb0973d86190d7f32dac75c7f9 and de4a199debf496649d8d652712e68b965412dc16

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
655 [LDMud 3.5] LPC Compiler/Preprocessor minor always 2009-06-03 15:27 2017-09-30 18:50
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: lvalue 7: Make reseating of aliases possible
Description:
    a = &b;
    a = &c;

Here b will be made a reference to c. It should be possible to change the reference of a from b to c instead. (foreach can do such a thing for its variables already.)

As the syntax I'd propose &a = &c;
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
653 [LDMud 3.5] LPC Compiler/Preprocessor major always 2009-06-03 15:11 2017-09-30 18:49
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: lvalue 5: Make explicit lvalues fragile
Description: Explicitly created lvalues behave somewhat inconsistent. Sometimes they are automatically derefenced, sometimes not.

   int var = 10;
   mixed lv;

   lv = &var; /* typeof(lv) returns T_NUMBER. */
   lv = ({ &var }); /* typeof(lv[0]) returns T_LVALUE. */

I think when pushing an element which is a protected lvalue onto the stack it has to be dereferenced. The only exception is pushing it as an lvalue on the stack (in the above example typeof(lv) and typeof(lv[0]) should return T_NUMBER, but typeof(&lv) and typeof(&(lv[0])) should return T_LVALUE).

So conceptually lvalues are fragile, to keep them you have to use & everywhere you want to copy them.) This is also for security reasons: It shouldn't be possible to give an object an lvalue and observe the values it gets during its processing, unless the object preserves the lvalues by using &.

That's why also x=fun() and x=&(fun()) have to be distinguished (if the former returns an lvalue it has to be changed to an rvalue).
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
652 [LDMud 3.5] Runtime minor have not tried 2009-06-03 14:53 2017-09-30 18:48
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: lvalue 4:Introduce mutable strings
Description: Strings are normally seen as constant, they have copy-on-write/copy-by-value semantics. Wenn creating an lvalue to a single string character the string is copied (if it has a reference count > 1). That makes it impossible to create more than one char lvalue of a string (string str="1x1"; fun(&(str[0]), &(str[2])); - it's ugly but should be possible). But it also messes strings up when the string is put into the string table again before the lvalue is used:

    string str1,str2;
    mixed c;
    
    str1="abcdefgh";
    c = (0||&(str1[3]));

    c='1';
    str2=str1; /* str2 should be "abc1efgh"; */
    c='2'; /* should only change str1. */

    return ({str1,str2});

returns ({"abc2efgh","abc2efgh"}).

This also messes up string hashing:

    mapping m = ([:1]);
    string str; mixed c;
    
    str="abcdefghi";
    c = (0||&(str[3]));
    c='1';
    
    m[str] = "Nr. 1";
    c='2';
    m["abc2efghi"] = "Nr. 2";
    return m;

returns (["abc2efghi":"Nr. 2","abc2efghi":"Nr. 1"]) which is quite unusual for mappings (having a key twice).

So my idea is to create a special type for mutable strings, so that they can have more than one reference to it. That would also prevent char lvalues from getting invalid, because such a string would exist as long as references to it exist.

They should be another subtype of strings. (There already are tabled and non-tabled but also constant strings). Mutable strings are strings that can be changed in-place. An untabled string can be changed into a mutable one if it has a refcount of 1. A mutable string can be made constant again if it has a refcount of 1 and if this refcounts comes from a svalue structure (and not from an lvalue).

Whenever a mutable string is pushed as an rvalue on the stack it is changed if possible or copied into a constant string.

To mark a string as mutable, one of the refcounting bits can be used. (2^30 references to a string should still be enough...)

Mutable strings still have a constant length (as have vectors), length-changing replacements (str[1..1]="abc") create a new string.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0001196)
Gnomi   
2009-06-09 10:21   
This might not be necessary. Char lvalues just have to behave different. Now they store a pointer (char*) to the char and keep a reference to the full string. Instead we need a reference to the string, the local variable (which has to be a protected lvalue) and the index. When assigning a value to the local variable, change the string, copy the string when necessary (tabled or more than one reference) and when doing so, update the variable lvalue to point to the new string.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
650 [LDMud 3.5] Runtime major always 2009-06-03 14:29 2017-09-30 18:46
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: lvalue 2: Give variable references unlimited lifespan
Description: Currently it is possible to create variable references that life longer than the variable itself:

    int var;
    return ({ 0 || &var });

This function would return an lvalue to an invalid stack entry. The compiler tries to check this (return &var; is forbidden), but I don't think it can catch all possibilities.

There are to kinds of variable lvalues: Implicit (var = ...) and explicit (&var). The first kind will have subtype LVALUE_UNPROTECTED and any such lvalue must be consumed by the next operation, it's reference to the svalue is uncounted (just as it is now).

The second kind will have subtype LVALUE_PROTECTED and points to a dynamically allocated structure consisting of a reference count and a svalue_t. Whenever an explicit reference to a variable is done, the contents of the variable is copied to such a structure and the variable itself is replaced by a protected lvalue pointing to this structure.

&(arr[i]) can also be implemented that way without the need for protector references of the array.

All other protected lvalue structures (for ranges) get a reference counter, too.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
487 [LDMud 3.5] Runtime crash always 2006-09-14 09:58 2017-09-30 18:46
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 3.1  
Status: resolved Product Version: 3.3.713  
Product Build: 3.3.714 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: Protected lvalues are copied without their protectors
Description: The following LPC code crashes the driver:

     mapping m=([]);
     funcall(lambda(0,({#'=,'a,({#'copy,({#'&,({#'[,m,0})})})})));

2006.09.14 16:22:00 Ref count in freed hash mapping: -1
2006.09.14 16:22:00 Current object was w/gnomi/LPC_zst

2006.09.14 16:21:59 free_protector_mapping() : no hash reference

w/gnomi/LPC_zst w/gnomi/LPC_zst.c line 8
92996a6: 171 previous_object0 (0: 14) line 8
92996a7: 38 7 && (1: 15)
92996a9: 205 this_interactive (0: 14)
92996aa: 60 ! (1: 15)
92996ab: 39 3 || (1: 15)
92996ad: 205 this_interactive (0: 14) line 9
92996ae: 207 this_player (1: 15)
92996af: 51 == (2: 16)
92996b0: 38 7 && (1: 15)
92996b2: 171 previous_object0 (0: 14) line 10
92996b3: 256 27 geteuid (1: 15)
92996b5: 207 this_player (1: 15)
92996b6: 256 27 geteuid (2: 16)
92996b8: 51 == (2: 16)
92996b9: 38 7 && (1: 15)
92996bb: 207 this_player (0: 14) line 11
92996bc: 256 27 geteuid (1: 15)
92996be: 206 this_object (1: 15)
92996bf: 256 27 geteuid (2: 16)
92996c1: 51 == (2: 16)
92996c2: 106 56 branch_when_zero (1: 15)
92996c4: 96 256 clear_locals (0: 14) line 15
92996c7: 168 256 m_caggregate (0: 14)
92996ca: 123 0 push_local_variable_lvalue (1: 15)
92996cc: 41 (void)= (2: 16)
92996cd: 97 save_arg_frame (0: 14)
92996ce: 15 const0 (1: 15)
92996cf: 22 61480 closure (2: 16)
92996d4: 10 2 cstring0 (3: 17)
92996d6: 294 65 quote (4: 18)
92996d8: 22 61679 closure (4: 18)
92996dd: 22 61494 closure (5: 19)
92996e2: 22 61501 closure (6: 20)
92996e7: 30 0 local (7: 21)
92996e9: 15 const0 (8: 22)
92996ea: 166 3 aggregate (9: 23)
92996ed: 166 2 aggregate (7: 21)
92996f0: 166 2 aggregate (6: 20)
92996f3: 166 3 aggregate (5: 19)
92996f6: 350 17 lambda (3: 17)
92996f8: 416 funcall (2: 16)
w/gnomi/LPC_zst <lambda ?> line 0
8b1056b: 172 0 lambda_cconstant (0: 17) line 0
8b1056d: 15 const0 (1: 18)
8b1056e: 144 push_protected_indexed_lvalue (2: 19)
8b1056f: 239 10 copy (1: 18)
8b10571: 123 0 push_local_variable_lvalue (1: 18)
8b10573: 40 = (2: 19)
8b10574: 24 return (1: 18)
w/gnomi/LPC_zst w/gnomi/LPC_zst.c line 15
92996fa: 98 restore_arg_frame (2: 16) line 15
92996fb: 92 pop_value (1: 15)
92996fc: 25 0 0 0 164 69 41 9
' z_lpc' in 'i/zauberstab/zauberstab.c (/i/zauberstab/zmarker.inc)' (' obj/zauberstab#9') line 495
' start_lpc' in 'i/zauberstab/zauberstab.c (/i/zauberstab/zmarker.inc)' (' obj/zauberstab#9') line 404
' fun' in ' w/gnomi/LPC_zst.c' (' w/gnomi/LPC_zst') line 15
2006.09.14 16:22:00 LDMud aborting on fatal error.

Program terminated with signal 8, Arithmetic exception.
#0 0x08108cd3 in dump_core () at simulate.c:586
586 *((char*)0) = 0/a;
(gdb) bt
#0 0x08108cd3 in dump_core () at simulate.c:586
0000001 0x08108ca5 in fatal (
    fmt=0x813dcc8 "Ref count in freed hash mapping: %ld\n") at simulate.c:649
0000002 0x080c3225 in _free_mapping (m=0x9296900, no_data=0) at mapping.c:631
0000003 0x080c34bb in free_protector_mapping (m=0x9296900) at mapping.c:723
0000004 0x0808dfe3 in free_protector_svalue (v=0x835af5c) at interpret.c:1069
0000005 0x0808e2c2 in int_free_svalue (v=0x8174140) at interpret.c:1156
0000006 0x0808e5b1 in free_svalue (v=0x8174140) at interpret.c:1271
0000007 0x080a40fd in eval_instruction (
    first_instruction=0x92996a6 "?&\a?'\003?3&\a?\003\033?003\0333&\a?003\033?003\0333j8`", initial_sp=0x8174138) at interpret.c:13031
0000008 0x080adc6d in apply_low (fun=0x9049354, ob=0x92d6ba4, num_arg=0,
    b_ign_prot=0, allowRefs=0) at interpret.c:16811
0000009 0x080ade64 in int_apply (fun=0x9049354, ob=0x92d6ba4, num_arg=0,
    b_ign_prot=0, b_use_default=1) at interpret.c:16889
0000010 0x080a8e2a in eval_instruction (
    first_instruction=0x92b8c12 "`\001\002a\017\003@\036",
    initial_sp=0x81740e0) at interpret.c:16159
0000011 0x080adc6d in apply_low (fun=0x924bf5c, ob=0x92b2ab0, num_arg=1,
    b_ign_prot=0, allowRefs=0) at interpret.c:16811
0000012 0x080ade64 in int_apply (fun=0x924bf5c, ob=0x92b2ab0, num_arg=1,
    b_ign_prot=0, b_use_default=1) at interpret.c:16889
0000013 0x080ae2ce in sapply_int (fun=0x924bf5c, ob=0x92b2ab0, num_arg=1,
    b_find_static=0, b_use_default=1) at interpret.c:17050
#14 0x0804c9ce in parse_command (
    buff=0xbfb662c0 "zlpc mapping m=([]); funcall(lambda(0,({#'=,'a,({#'copy,({#'&,({#'[,m,0})})})})));", from_efun=0) at actions.c:1094
#15 0x0804cf41 in execute_command (
    str=0xbfb662c0 "zlpc mapping m=([]); funcall(lambda(0,({#'=,'a,({#'copy,({#'&,({#'[,m,0})})})})));", ob=0x91f7e58) at actions.c:1258
#16 0x08054999 in backend () at backend.c:671
#17 0x080c02c9 in main (argc=16, argv=0xbfb67c74) at main.c:615
(gdb)

The reason is, that assign_svalue(_no_free) does copy the T_LVALUE svalue structure, but not the corresponding protector structure. So the protector structure will be freed twice (each time one of the svalues will be freed), resulting in the negative hash ref. (If this hash ref wouldn't be checked, xfree would later complain about freeing a block twice.)

I used a lambda closure and the copy efun to circumvent several lvalue restrictions. But even if these restrictions were extended to cover such a lambda, the problem would still exist with simul_efuns, which have to deal with lvalues in vararg arguments:

nomask varargs void printf(varargs mixed *args)
{
    if (this_player())
        write(apply(#'sprintf,args));
}

nomask varargs void sefun(varargs mixed *args)
{
    args[0];
}

The first is a real world simul efun, the second just for demonstration.
With these simul efuns the following code crashes the driver in the same way:

     mapping m=([]);
     printf("%O\n", &(m[0]));
     sefun(&(m[0]));

Here apply() or F_INDEX just copy the protected lvalue without their protectors.
Can these protectors be given ref counts?

Greetings,
Gnomi.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0000574)
lars   
2007-10-14 03:12   
Note to self: It's not just adding refcounts - assignments of a PROTECTED_LVALUE will have to create
a regular LVALUE in the destination pointing to the PROTECTED_LVALUE. Reason is that protected_lvalue structures are larger than regular svalues.
(0000623)
Gnomi   
2008-06-30 05:04   
This one is for the next unstable branch.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
649 [LDMud 3.5] Runtime tweak always 2009-06-03 13:58 2017-09-30 18:43
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: lvalue 1: Redesign T_LVALUE
Description: As the first step I think, T_LVALUE should be redesigned.

Now T_LVALUEs have a pointer to another svalue_t, which for unprotected plain lvalues is the lvalue itself, or for other lvalue types have a special type entry like T_POINTER_RANGE_LVALUE, which is only allowed to occur in an svalue_t where a T_LVALUE points to. This type then indicates how its pointer has to be interpreted to reveal more information about the lvalue.

I'd propose that the lvalue type should be stored as a subtype of T_LVALUE (like the closure subtypes). And according to this subtype the .u entry in the lvalue is one of several special structures. I think, this is a more cleaner approach.

T_CALLBACK and T_ERROR_HANDLER should also be moved as subtypes to a new T_META type.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
531 [LDMud 3.5] LPC Compiler/Preprocessor feature always 2008-02-17 19:56 2017-09-30 18:42
Reporter: Sorcerer Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: Passing varargs argument by reference
Description: It would be great to be able to pass references to functions using varargs arguments for constructs like:

walk_mapping(m, function void (mixed key, varargs mixed *values) { ... })


(I filed this originally as 0000530 against 3.2-dev but it was meant to go here to 3.3, sorry for that)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000609)
zesstra   
2008-04-30 05:30   
Yes, actually I had some code yesterday, which contained your example line in the first attempt. ;-)
But I don't know if there is an easy way for doing this. The driver justs puts all the args into an ordinary array and puts that array on the stack. So it would be necessary to allow putting T_LVALUES into arrays. In setup_new_frame2() in interpret.c is the following comment:
* If <allowRefs> is TRUE, references may be passed as extended varargs
* ('(varargs mixed *)'). Currently this is used only for simul efuns.
* TODO: Investigate if holding references in arrays is really such a
* TODO:: a bad thing. Maybe it's just an implementation issue.
* TODO:: This also affects apply_low() and call_lambda().

My current knowledge of the driver code is not deep enough to give a qualified statement if it is 'bad thing'... ;-) Maybe someone else can comment on this one?

BTW: My code yesterday had no need for the arguments to be passed as reference,so I used filter() (map() is ok as well).
(0000624)
Gnomi   
2008-06-30 05:10   
This one is also for the next unstable branch.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
694 [LDMud 3.5] General feature N/A 2009-10-24 06:55 2017-09-30 18:42
Reporter: zesstra Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: sort() should accept protected ranges (&(a[3..5]) as first argument
Description: sort_array() accepts references to arrays to sort in-place, but it does not accept protected ranges right now.
I suggest to add support for this after Gnomis rework of lvalue handling, which will save some time to code it twice.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
813 [LDMud] Efuns minor always 2012-11-26 22:10 2016-01-26 20:05
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/LInux  
Priority: normal OS Version: 5.0  
Status: resolved Product Version:  
Product Build: Resolution: no change required  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: query_ip_number(&ob) returns &ob
Description: If query_ip_number is given a reference to a variable, query_ip_number returns that reference instead of a string (as stated in the documentation).

I like the documented way better, because returning a reference can be very dangerous (a function might return the result of query_ip_number directly and so return a reference to a local variable, even an experienced admin occasionally crashes a MUD in such a way...)

Btw, I find it annoying that query_ip_number returns bytes > 127 as negative integers.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0002154)
Gnomi   
2012-11-26 23:31   
query_ip_number might be obsoleted by 0000596. So it might not be worth to implement this suggestion and remove this efun instead.
(0002276)
Gnomi   
2016-01-26 20:05   
The efun mysteriously vanished.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
258 [LDMud 3.5] Efuns feature N/A 2004-11-27 00:10 2016-01-26 20:04
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Shadow efuns: next_shadow/query_shadow() instead of shadow(ob,0)
Description: Short: New shadows efuns
From: Tomba@Batmud
Date: 2001-08-25
Type: Feature
State: New


call_shadow() works like call_other, but it does NOT call any shadows and
so it always calls the functions in the object that was given as argument.

all_shadows() returns an array of objects shadowing the given object.

first_shadow, next_shadow, last_shadow are used to traverse shadows of an
object.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001296)
zesstra   
2009-09-26 18:05   
While I appreciate the possibility to find out the currently existing shadows and which objects are in which shadow chain, I perceive call_shadow() a) as ill-named and b) contradictory to the purpose of shadows. I believe, once a shadow has been granted, it should be ensured, that the shadow is actually called.
(0001332)
Gnomi   
2009-09-29 11:19   
Hmm, all those functions can be implemented as simul-efuns. So there is no need for efuns, maybe only for the sake of consistency between mudlibs.

On the other hand I don't like the double purpose of shadow() (retrieving information about shadows and actually shadowing another object), so having first/next_shadow instead of shadow(ob, 0) is imho a prettier interface.
(0001351)
Coogan   
2009-09-29 16:47   
I agree to Gnomi that for those who are in need of such functions, all of these can be implemented as simul-efuns.
The double purpose of shadow() should be noted as another issue.
(0001365)
zesstra   
2009-09-30 16:50   
I just changed the title of this bug to reflect, that this deals now with only the issue of a better interface than shadow(ob,0) and moved the bug to 3.5.
(0001988)
zesstra   
2011-02-14 18:01   
I would suggest to include the querying functionality in object_info() as:

OINFO_SHADOWS:
OIS_NEXT: next shadow in chain
OIS_PREV: previous shadow in chain
OIS_ALL: array of shadowers in their correct order

Should we keep shadow() as well as it is or remove the querying feature?
(0001990)
Gnomi   
2011-02-14 18:39   
I'm in favor of removing. 3.3 is for compatibility, 3.5 for beauty.
(0002275)
Gnomi   
2016-01-26 20:04   
object_info(ob, OI_SHADOW_NEXT/_PREV/_ALL) does what was proposed.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
848 [LDMud 3.5] Networking feature N/A 2016-01-14 14:25 2016-01-14 17:07
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: high OS Version:  
Status: resolved Product Version: 3.5.0  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Enable support for elliptic curves in pkg-openssl.c
Description: pkg-openssl does not select a curve for EC key exchanges, which disables the complete support EC KEX.
This should be fixed ASAP.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
663 [LDMud 3.5] LPC Language minor always 2009-06-18 05:00 2015-05-10 20:18
Reporter: Gnomi Platform: i686  
Assigned To: zesstra OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: RfC: Remove some configuration switches in 3.5.x
Description: The reduce complexity of the code and fragmentation of the language some configuration options should be removed.

USE_ARRAY_CALLS can always be on. The only visible change is, that instead of throwing an error on call_other with arrays it does work.

USE_STRUCTS, too. That makes 'struct' a reserved word. Might break code, that uses 'struct' as a variable or function name.

USE_NEW_INLINES should also be always on. 'function' will become a reserved word and might break code, where it is used a variable or function name. But other than that it should be compatible to older inlines. (It won't throw an error when outer variables are referenced.)
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0001222)
zesstra   
2009-06-18 05:10   
I agree for all three of them.
(0001226)
fufu   
2009-06-18 07:13   
I disagree with always enabling USE_ARRAY_CALLS (It makes code harder to read; foo->bar() may hide a loop when array calls are enabled. There's also the possibility of passing arrays instead of objects to functions to cause interesting effects. It's also another trap for beginners to fall into. And finally, writing the equivalent map_objects() call is not hard.)

I agree with enabling the other two features by default (unlike array calls, these are features that you have to use consciously - and finding code that contains a new keyword using grep isn't that hard).
(0001228)
zesstra   
2009-06-22 07:34   
What about NEW_CLEANUP? I think, we could make that non-optional as well.
(0001229)
Gnomi   
2009-06-23 05:17   
I agree, that NEW_CLEANUP can be made mandatory. Also LOG_NEW_CLEANUP code can be removed.

Then there are USE_AVL_FREELIST, MALLOC_ORDER_LARGE_FREELISTS and MALLOC_ORDER_SLAB_FREELISTS. Do we have something to measure memory fragmentation, so we can decide, whether they help or not?
(0001232)
zesstra   
2009-06-23 17:56   
Just to keep in mind a short discussion with Gnomi about evaluating the fragmentation one simple idea:

Eine einfache Moeglichkeit waere vermutlich, offline (wie GC) den heap komplett zu durchlaufen und dann ein Art Bitmap zu machen. Fuer jedes Wort ein Pixel und dann kennzeichnen, ob belegt (1) oder nicht (0) und dann graphisch darstellen. Das waer dann was fuer Menschen zum Angucken. Etwas in der Art wie hier: http://blog.pavlov.net/2007/11/10/memory-fragmentation/
Ich wuerde vermuten, dass das trotz der Einfachheit einen ernsthafen Hinweis gibt, ob diese Defines irgendeine Aenderung zum besseren bewirken und ob das signifikant genug ist, damit man ueberhaupt was sieht. Allerdings muesste man bei dem Vergleich IMHO immer die gleiche Sequenz von Lade-/Clone-/Destruct-Vorgaengen machen.

(Sorry for the german, I just too lazy right now. It is basically the same approach as described in the link.)
(0001283)
Coogan   
2009-09-20 07:36   
I'd also drop USE_LPC_NOSAVE (although an earlier report of mine was the reason for implementing that configuration switch) and make use of 'nosave' mandantory.
(0001284)
Coogan   
2009-09-20 07:47   
BTW: When looking at the settings files in a 3.4.x-archive, all muds are using alists. (The exception is the settings file of Traumland -- who is Traumland? Never heard, and even unknown for our inetd.)

From this point of usage, it would be better to change the alists-default to "yes" or, to clean up the code for the case #ifndef USE_ALISTS, and another switch would be gone.

Why should one support an option nobody uses?

(In 3.2.x, there is no such option yet and support of alists mandantory.)
(0001285)
invisible   
2009-09-20 09:17   
I can only speak for Beutelland, but we do not use alists although they are enabled. It simply is because we derived our settings-file from Silberland :-)

I guess it's the same for many other MUDs (just like almost every autoconf-script checks for a fortran compiler *g*)
(0001286)
Gnomi   
2009-09-20 11:48   
Those muds who don't mention alists in their settings file don't use alists (as it is deactivated by default). So Avalon, Beutelland, DT2, Gestrandet, Heaven7, Lethynna, Timewarp and UNItopia don't use them, too. (And speaking for UNItopia: We don't want them back.)
(0001973)
_xtian_   
2011-02-14 14:11   
So there seems to be a consensus regarding always enabling:

USE_STRUCTS
USE_NEW_INLINES
USE_LPC_NOSAVE
NEW_CLEANUP
 Also LOG_NEW_CLEANUP code can be removed.

And recent discussions reached the agreement to keep:
USE_ARRAY_CALLS


Also it has been proposed to enable
USE_ALISTS - but, personally, I am surprised that it is still in use and would have proposed to DISable it completely.


Also, read the comment from Gnomi: https://ldmud.eu/mantis/view.php?id=663#c1229 regarding memory-defines.
(0001974)
zesstra   
2011-02-14 14:19   
The first 5 mentioned in 0000663:0001973 are settled, I agree.

I suggest to discuss the ones without consensus separately and will create separate entries and link them to this issue (see above). Otherwise, this issue will get even more confusing than it is right now. ;-)
(0002254)
zesstra   
2015-05-10 20:18   
I believe, we are finished with this concerning 3.5.0.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
557 [LDMud 3.5] Compilation, Installation minor N/A 2008-07-16 16:04 2015-05-04 23:47
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: low OS Version: 10.5.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Remove conditional compilation of structs and new inlines
Description: From a discussion with Gnomi: Structs and new inline function seem to be stable. The #ifdef USE_STRUCT and #ifdef USE_NEW_INLINES should be removed in 3.5, making both non-optional and improve readibility of the driver code.
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0001496)
zesstra   
2009-10-06 05:19   
I would suggest to first define USE_STRUCT and USE_NEW_INLINES all the time and then remove the #ifdefs when we anyway have some business in a file...
(0001499)
zesstra   
2009-10-06 15:37   
I always enabled structs in r2761 and new inline closures in r2762 by always defining USE_STRUCTS and USE_NEW_INLINES in driver.h.
I removed the conditional compilation from func_spec, lex.c|h and prolang.y. (I hope, I got that bloody mixture of ifdef and ifndef right.)

Now, whoever stumbles upon these defines: please feel free to remove them. ;-)
(0002252)
zesstra   
2015-05-04 23:47   
USE_STRUCT and USE_NEW_INLINES were removed.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
661 [LDMud 3.6] General major N/A 2009-06-15 18:33 2015-04-30 00:03
Reporter: zesstra Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: confirmed Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version: 3.5.0  
Summary: Bytecode cleanup
Description: This is the master bug for everything related to bytecode cleanup in 3.5.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
606 [LDMud 3.6] General minor N/A 2009-02-08 09:55 2015-04-30 00:03
Reporter: zesstra Platform: x86_64  
Assigned To: OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: confirmed Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version: 3.5.0  
Summary: Bytecode cleanup: exchange macros by functions and use dedicated types
Description: 1) Currently, the bytecode is read and written by using macros like LOAD_LONG. These should be exchanged by static function in most cases.
2) Instead of using types like short, long (which are mostly assumed to be 2 and 4 bytes), prolang.y, closure.c and interpret.c should use dedicated types for a given purpose. These should be typedefed to suitable basic types, e.g. bc_offset_t (as type for offsets in the bytecode) may be typedefed to uint32_t. These types should then contain their own load_*/store_*/put_*/get_* functions.
3) Assumptions that long/short are 2/4 bytes long have to be removed or made clear by using *_uint32()/*_uint16() etc.
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
840 [LDMud 3.5] Compilation, Installation major always 2015-01-31 08:44 2015-02-01 18:51
Reporter: Leonidas Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.5.0  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Typo in sprintf.c leads to compile error
Description: sprintf.c: In Funktion »string_print_formatted«:
sprintf.c:2245:24: Fehler: verirrtes »\302« im Programm
                        else if ( signi || !isize)
                        ^
sprintf.c:2245:24: Fehler: verirrtes »\240« im Programm
<builtin>: recipe for target 'sprintf.o' failed
make: *** [sprintf.o] Error 1
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: 0001-erroneous-240-in-program.patch (940 bytes) 2015-01-31 08:44
http://ldmud.eu/file_download.php?file_id=288&type=bug
Notes
(0002244)
zesstra   
2015-02-01 18:51   
Danke schoen! Verdammtes unsichtbares Unicode, muss meinen vim mal beibringen, den kram anzuzeigen.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
719 [LDMud 3.5] LPC Compiler/Preprocessor minor always 2010-01-26 09:10 2014-02-24 00:03
Reporter: zesstra Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Disallow returning values from void functions
Description: Currently it is possible to return values != void from void functions:
void voidfun() {return (void)get_eval_cost();}

This should either be disallowed or the (void) cast should convert any value into 'void' (numerical: 0).
Gnomi and me tend to the second possibility (convert to 0).
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001704)
Sorcerer   
2010-01-26 09:46   
For the sake of consistency the second possibility will be the better one. On the other hand: is there any need for allowing a cast to void at all (just as a thought - though I still support the suggested solution 2)?
(0001707)
zesstra   
2010-01-26 11:32   
The only reason I can think of is backward compatibility. But a real application for casts to void... No, I don't know one.
mixed a = (void)nonvoidfun() currently works and I see no point in it.
Some people use
return (void)nonvoidfun();
in void functions. But I don't see any reason for doing this instead of
nonvoidfun(); return;
(0001748)
Coogan   
2010-03-03 17:52   
I also tend to cast any value to a numerical null instead of prohibiting the void cast.
(0001759)
zesstra   
2010-03-04 15:32   
Mhmm... Implementing the (void) cast as basically F_POP_VALUE+F_CONST0 is clearly better for backward compatibility. On the other hand, it is somewhat inconsistent to the other (type) casts, which change the value only when it is known at compile-time. Additionally, the (void) cast serves no serious purpose and 'void' is no real type.

I think, the lazy mudlib maintainer in me wins in this case. But maybe introduce the conversion and issue a warning at compile-time? Or probably better: make it an error in case of #pragma pedantic?
(0001765)
Bardioc   
2010-03-05 14:11   
I vote for the pedantic pragma :-)
(0001770)
Coogan   
2010-03-08 17:31   
In my previous note the lazy mudlib maintainer spoke, too.

From the programmers sight, I'd disallow casts to void. But part of pedantic?
It looks like I should begin to use that for the corelib. :)
(0001930)
zesstra   
2010-11-21 01:07   
Ok, there was no disagreement so far. Then my suggestion is: usually convert to numerical 0 but raise an error if pendantic is set.

If I am not mistaken, we should be able to do that solely at compile-time, if we dis-allow the assignment of void to variables (void as type is already forbidden), because than any non-empty return can be forbidden/changed to returning F_CONST0. We discuss the assignment issue in bug 0000718.
(0001932)
zesstra   
2010-11-21 01:43   
I just found out, the TYPE_VOID is incompatible to anything in check_rtt_compatibility() in the interpreter. Therefore returning anything from a void function will raise an error if the RTTC are active.
When we add the implicit conversion to zero without pedantic, this should be kept in mind.
(0002236)
zesstra   
2014-02-24 00:03   
Should be fixed with 0000721.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
718 [LDMud 3.5] LPC Compiler/Preprocessor minor always 2010-01-26 09:07 2014-02-24 00:03
Reporter: zesstra Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Disallow assignments of 'void' values to variables
Description: It should not be possible to assign void to variables, even to mixed, because it is not possible to declare a variable as being 'void':
mixed a = voidfun(); // works
void a = voidfun(); // error
(Or the other way: 'void' defines that a function returns nothing and you should not assign something which doesn't exist (the non-existing return value))
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001705)
Sorcerer   
2010-01-26 09:50   
Since an assignment <var> = voidfun(); in a program can only be one of two: an oversight or even an error by the programmer, I recommend throwing an error (type mismatch) in that case.
At least I cannot imagine any reason why someone should want to do this on purpose.
(0001706)
zesstra   
2010-01-26 11:28   
Yes, I would also like an error in that case.
BTW: I can't see any sense either in the following assignments, which are possible right now (even with #pragma strict_types,pedantic):
int a = (int)voidfun();
string a = (string)voidfun();
...
(0001708)
fufu   
2010-01-26 12:23   
One possible reason to do that, and I'm not saying that it is a good one, is that

  int a;
  a = (int)voidfun();

costs one eval-tick less than

  int a;

  voidfun();
  a = 0;

Historically, there was the idiom

  return (int)notify_fail("blah");

but notify_fail has been returning int for ages now. But people may still be doing this for other functions returning void.
(0001709)
zesstra   
2010-01-26 15:04   
Ok, so basically as an idiom for assigning 0 (surprise *g*).
Despite your not-recommendation, I have to comment from the viewpoint of someone maintaining domain code: This is ssoooooooooooooo ugly to read as someone who has to maintain the code later, that it is IMHO never justified for saving just one tick. (If I don't know voidfun(), I have to look that up first, instead of just seeing the assignment of a constant 0.)
(BTW: your example can of course be shorted to 'int a; voidfun()' without any assignment, but one can assume an assignment to a != 0 before. ;-) )

The same holds true for return (int)notify_fail("blah"); which is much more readable in the form of notify_fail("blah"); return 0;
(0001712)
sinnvoll   
2010-02-10 10:34   
In the moment there is Code like:

private int sitzobjekt_register_im_p()
{
   "/p/Registry/registry"->register(__FILE__);
}
private int sitzobjekt_dummy_p = sitzobjekt_register_im_p();

This collects all uses of a inherit.
There is space wasted for an integer.

If we had void-Variables, then Code could be executed in variable
initialisation time without wasting space.
(0001713)
zesstra   
2010-02-10 15:02   
I am not sure, what you are advocating for. Are you arguing that we should go in the other direction and deliberately introduce 'void' as type you could chose for variables?

Variables (or better: svalues) internally consume the same amount of space, no matter of the type. That holds true for 'void' as well. (Actually, any void is technically an int with the value 0.) Therefore size-wise and speed-wise it does not matter at all, if you use
private int sitzobjekt_dummy_p = sitzobjekt_register_im_p();
or a hypothetical
private void sitzobjekt_dummy_p = sitzobjekt_register_im_p();

If you want to save the variable, the better way is IMHO to include it in the H_CREATE* hooks and require all conforming programs (code-style issue) to call the inherited create hooks (there is a feature request for enforcing this technically, but that is rather low on priority...)
(0001931)
zesstra   
2010-11-21 01:37   
If there are not serious objections very soon, I will make TYPE_VOID incompatible to anything else in compatible_types() in the compiler.

BTW: Interestingly, TYPE_VOID is already incompatible to anything else in check_rtt_compatibility() in the interpreter.
(0001934)
zesstra   
2010-11-23 00:43   
Unassign until it is clear how we best proceed with 0000765.
(0002235)
zesstra   
2014-02-24 00:03   
Should be fixed with 0000721.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
765 [LDMud 3.5] LPC Compiler/Preprocessor minor N/A 2010-11-23 00:19 2014-02-24 00:03
Reporter: zesstra Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Disallow the processing of void values
Description: During the discussion about bug 0000718 we came to the conclusion, that it is not sufficient to disallow only assignments of void values to variables, but we need to prevent any processing of them in expressions as well, e.g.
(foo ? bar : void-fun)
voidfun + non-void-value
voidfun - non-void-value
fun(voidfun);
etc. pp.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001961)
Gnomi   
2011-01-25 16:52   
In the grammar there are only two things that have to be handled specially: function calls and comma expressions. So it might be a way to introduce two non-terminals voidexpr (maybe void) and nonvoidexpr (is not void). The problem is not to introduce ambiguities (as every voidexpr can be a nonvoidexpr, and every nonvoidexpr is alo a voidexpr). Perhaps we need some more non-terminals (a set classifying the origin (can or cannot be guaranteed non-void) and a set for the use (maybe void or must not be void)).
(0002234)
zesstra   
2014-02-24 00:03   
Should be fixed with 0000721.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
829 [LDMud] LPC Language tweak always 2014-01-09 13:32 2014-02-23 23:57
Reporter: sinnvoll Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: void *
Description: void * test ();

void * test()
{
}

Shouldn't void * produce an error or warning,
the probability is high, that someone made a typographical error.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002216)
Gnomi   
2014-01-14 00:06   
This will come with 0000721. There I already did prevent such a type.
(0002220)
Gnomi   
2014-02-23 00:29   
This is fixed in the current master branch. void is syntactically no longer treated as a regular type (it cannot be part of a union type or can be an array), it is just a notion that a function will not return a value.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
149 [LDMud 3.5] LPC Compiler/Preprocessor minor always 2004-11-26 20:20 2014-02-23 23:34
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.8 and before  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: Typetracking fails on arrays
Description: int *r; r = ({ "12" });

sollte zumindest unter strict_types einen Typfehler im Compiler liefern.
Fehlerstellen:
  - der Type von ({ "12" }) ist nicht bekannt
  - der Typ wird bei der Zuweisung nicht geprueft.

------

Given the hackishness of the typetracking in the LPC compiler, I don't know if it can be fixed.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001490)
zesstra   
2009-10-06 04:27   
I would be very nice to fix this. Fuchur, Gnomi can you estimate the feasibility? I don't know enough about the compiler right now. ;-)
(0002232)
zesstra   
2014-02-23 23:34   
This has been fixed with 0000721. At least the part of the compiler. Any checks at runtime will be added when with runtime type checks upon assignments.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
721 [LDMud 3.5] LPC Language feature always 2010-02-01 17:39 2014-02-23 23:28
Reporter: zesstra Platform:  
Assigned To: Gnomi OS:  
Priority: low OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version:  
Summary: RfC: Extended syntax for declaring arguments and variables holding multiple types
Description: Maybe this can't be resolved in any decent/elegant manner...

Checking of types (compile-time or runtime) can be of significant help to programmers.
Unfortunately, once you want to have two types for an argument, you have to use <mixed> which disables all checks. Some syntax like
string|string* strs;
for a variable/argument able to hold a string or an array of strings (but no other type) would help in this case.

This is the syntax we use in func_spec in the driver sources for defining the efuns. There may be syntaxes which are easier to implement in our compiler...
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002221)
Gnomi   
2014-02-23 00:29   
This is implemented, see tag 3.5.0.2. :-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
703 [LDMud 3.5] Implementation feature N/A 2009-11-05 17:13 2014-02-23 00:31
Reporter: zesstra Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Move data from the function header in the bytecode to a separate table in program_s
Description: The so-called function header preceding every function in the bytecode is currently just a defined sequence of entities and not structured at all.
Additionally, we don't really need that data in the bytecode. All we need there is the function index in the defining program.

So this data (name, return type, number of arguments, number of local vars should be moved into a suitable struct fun_hdr_s and tabled in the program_s struct.
Then function just have the function index (currently short) directly before the bytecode. funstart would be the first valid opcode of that function.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002217)
Gnomi   
2014-01-23 20:19   
I have implemented that in https://github.com/amotzkau/ldmud/tree/703-functionheader. I will not make a pull request for inclusion in the master branch at this time, but rather use it as a base for my work at 0000721 and merge them at the end together into the master.
(0002222)
Gnomi   
2014-02-23 00:31   
As the 0000721 branch was merged so was the implementation of this idea.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
811 [LDMud 3.3] LPC Compiler/Preprocessor feature N/A 2012-09-18 10:58 2012-12-12 20:16
Reporter: sinnvoll Platform:  
Assigned To: fufu OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.720  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.721  
    Target Version: 3.3.721  
Summary: predefined define __FUNCTION__ for the name of the function
Description: __FUNCTION__ could be replaced with the name of the current function.

example:

int set_value(int i)
{
   v=i;
   if(i) do_error(" Error in Function "+__FUNCTION__+" ");
}

output of set_value(1); :
 Error in Function set_value
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002150)
zesstra   
2012-09-18 22:25   
(Last edited: 2012-09-18 22:27)
Just in case you don't know the possibility: you can already get the current lfun name with debug_info(). Or you just use debug_info() to dump some more info in addition to the name.
You might argue that is consumes more ressources than necessary, but then errors should be the exception, I guess.

Depending on the error it might also be a good idea to dump/store the whole stacktrace to be able to trace the source of error. At least I made the experience, that the plain info "error in function xy" usually does not help me too much.

(0002151)
fufu   
2012-09-29 01:38   
I agree with Zesstra that a __FUNCTION__ predefine is of limited use. But it's not hard to implement if we want it:

https://github.com/Fuchur/ldmud/commit/07c3c3c35e6c6bf6fc11fd085f0b65b1f00c53f8
(0002152)
zesstra   
2012-09-29 16:19   
Yay, somebody submitted a patch. :-)
I don't have anything against it, so from my side feel free to apply it to the trunk.

(ok, now we only need to finally migrate our main repository to github...)
(0002172)
zesstra   
2012-12-08 23:09   
Fuchur,

do you want to take care of committing this? If not, re-assign to me.
I have a comment after all: I am not sure, if the name in inline closures should not be the auto-generated name for the inline, because technically it is another function...?

BTW: We moved the primary source repository now to github.com, so please either push your changes to https://github.com/ldmud/ldmud or file a pull request against it. :-)
(0002178)
fufu   
2012-12-12 16:24   
I'll push it later tonight.
(0002179)
fufu   
2012-12-12 20:15   
pushed as 6e0b4b85543c3af3ab5c7d30db2f3b12a9260466 (3.3 branch) and dae6067cf15017605b04ff85b77b0fd856e1756a (master branch)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
812 [LDMud 3.5] Runtime major N/A 2012-11-11 23:00 2012-12-04 17:01
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.5.0  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Data cleanup behaviour should be improved
Description: Currently the data cleanup behaviour is somehow flawed.
1)
The number of objects cleaned per backend cycle is dependent on the TIME_TO_CLEANUP (i.e. the time before calling cleanup()). This dependency does not make much sense. If you want to have calls to cleanup() only for objects which were not used for a long time, you choose a large TIME_TO_CLEANUP. But because the number of objects data-cleaned is 2*number_of_objects / time_to_cleanup, this leads to a very low number of objects cleaned per cycle.

2) The first X objects of the processed objects in a given backend cycle are data-cleaned. If all objects are processed in a cycle, always the same X objects are data-cleaned and the other never. (Unless the object list changes.)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002155)
zesstra   
2012-12-04 17:01   
I changed the default for the data cleanup time to 3600 s and made it configurable with configure_driver(). Additionally a bug was fixed during object creation (the time was initialized with the genereal cleanup time).
In 3.3 the default was changed to 10800 s (longer, because not configurable at run-time) and the mentioned bug during object creation was fixed.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
447 [LDMud 3.5] Implementation minor always 2006-03-01 15:17 2012-07-12 23:10
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Heartbeat interval should be configurable
Description: MudOS for example allows that.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000643)
zesstra   
2008-07-01 05:28   
I assume, the intention is to allow individual HB intervals for objects, as the global interval is already configurable? Might then be something for 3.5 if we have to change the HB processing in the backend cycle, maybe to something similar to the callout processing.
(0002137)
zesstra   
2012-06-09 12:04   
On the other hand: maybe it is sufficient to just use callouts for the objects with different timings? I am not sure if benefit is worth re-working the HB mechanism...?
(0002138)
lars   
2012-06-10 03:19   
Opinion from the peanut gallery (yes, it exists): IIRC, the difference between heartbeats and call_outs is that heartbeats are executed only to fill up current polling interval. Any heartbeat not fitting into the current polling interval is pushed with priority into the next one; allowing the game to degrade gracefully under load. call_outs on the other hand are executed at their trigger time, no matter how long it takes.

To truly replace heartbeats with call_outs, you'd have to implement a 'BEST_EFFORT_TIMING' kind of flag.

(Again, I might be completely wrong - I'm writing from memory here. And if that is indeed the case, let me know, and I'll shut up :) )
(0002139)
invisible   
2012-06-10 13:52   
Depends on how much work it would be. If it's easily done, configurable
heartbeat might be a nice feature. OTOH the time may better be invested into
a more generic, HB-independent timer/event-system.

I agree it is feasible to solve this with call_outs though (I did it for
RoleMUD's dynamic attribute system).

@lars: if per-object HB-rate exists I guess most people would use it under the assumption of a somewhat 'reliable' interval (if HB is generated on a best-effort basis, and might or might not occur at the desired interval, why make it configurable at all?)
(0002140)
lars   
2012-06-17 00:24   
Making heart_beat time intervals configurable would give you best of both worlds: one the one hand, call_outs at guaranteed configurable times, and on the other hand, heartbeats at load-aware best-effort configurable times (plus, heartbeats automatically reoccur, call_outs don't).

In theory both could be unified into the same efun, but I'd make that step 2.
(0002146)
Gnomi   
2012-07-12 23:10   
This feature can be implemented rather easily, because there is an object list sorted after their individual call schedules. (When using asynchronous heartbeats.) Two changes are required: Instead of storing the time of the last hb execution, store the time of the scheduled call. And instead of adding new objects to the end of the list insert it at the appropriate place for its schedule. (Bonus: When changing the interval, move the object to its new place.)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
168 [LDMud 3.5] Compilation, Installation feature always 2004-11-26 22:06 2011-11-22 21:38
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: feedback Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: 'Location' argument to set_environment()
Description: Short: modified set_environment()
From: Tatu P Saloranta <doomdark@cc.hut.fi>
Date: Fri, 18 Dec 1998 14:47:26 +0200 (EET)
Type: Feature
State: Unclassified

I just compiled LDMud, and noticed there were actually few other efuns
I had hacked into Amylaar GD... Some aren't probably useful for anyone
else out there, but others might be. Although I don't want to add yet
another dozen of esoteric efuns to GD, I think it'd be good to discuss
about possible useful new additions anyway. So, here's my list:

- 3rd (optional) argument to efun308() (ie. "set_environment()"). As the mudlib
  of the mud in question sorts the inventories (putting 'similar' items
  next to each other), it needs to be able to decide where in the linked
  list to put objects to. This is done by supplying an optional argument,
  the object after which the 'moved' object is to be put. Although
  in the perfect world inventory-handling probably should be completely
  done by objects (rooms, containers), there's no built-in linked list
  datatype, and array-handling in LPC introduces significant overhead...
  Thus driver-handled inventory handling still has its uses IMO. I won't
  include code here, but it's a trivial addition and I can mail the
  changes necessary if need be.

Note: Problem is the add_action()-Handling.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002003)
zesstra   
2011-02-19 22:35   
I don't like to add this. Very few people need something like this and it breaks the scheme, that the inventory (all_inventory()) is ordered according to insertion time into the environment (so the last object was added after all the ones before).
(0002021)
Gnomi   
2011-02-22 00:06   
Hmm, I don't have a use for it right now, but I think it's not a bad idea to give the mudlib more control over the inventory list.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
793 [LDMud 3.5] Implementation major N/A 2011-11-17 17:43 2011-11-22 00:15
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: New savefile format supporting double precision for floats
Description: 0000496 deals with a new float format with 'double' precision. This can be done independently of the savefile format. However, until we have a new savefile format supporting higher precision the new float format will be not as useful as it could be.

Idea: use standard sprintf/sscanf for writing/parsing float values and get rid of the two representations in the savefile.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002079)
Gnomi   
2011-11-18 14:38   
We're talking about sprintf("%a", double), right?
(0002080)
zesstra   
2011-11-18 15:46   
Ah, yes. Or %la, which is equivalent for sprintf, but not sscanf. Or strtod() should do the same conversion.
(0002083)
zesstra   
2011-11-22 00:15   
The new savefile format 2 for saving the new float format introduced in 0000496 is no available in the driver in the 3.5.x branch.
https://github.com/ldmud/ldmud/commit/95ad6fe1f9500d55e73db0f21d05c827a70a262d

Savefiles with the new format version can be read and written with any driver more current than that commit (independent of the architecture). However if the driver uses internally the traditional 48 bit float format, a loss of precision and range will occur.
If the driver uses the new float format from 0000496, but the values are saved in format version <2, there will be losses as well.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
496 [LDMud 3.5] Implementation feature N/A 2006-12-27 08:48 2011-11-22 00:11
Reporter: hkremss Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: major rework      
ETA: > 1 month Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: double precision floats
Description: As far as I can see from the source code, the only reason for the use of the 'special 48-Bit floating point' format was support of Classic Atari/Amiga platforms from good old MC68xxx days. While Atari seems to be dead, current Amigaish systems have gcc and full 64 bit double precision float support. Anyway support for Classic Atari/Amiga was dropped in 3.3, so why keeping it? I suggest to clean up svalue.h and the READ/SPLIT/STORE_DOUBLE macro stuff and use the 2 already existing 32 bit 'exponent' and 'mantissa' members to form a 'real double'. Shouldn't be too complicated. We could achieve higher math precision in LPC and probably get cleaner code as well.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000525)
zesstra   
2007-01-05 08:33   
Mhmm, I might be wrong, but the exponent is currently 16 bit, so there is no existing 32 bit 'exponent' member (which might be changed of course).

I wonder, if it would be nowadays feasible, to implement an alternative FLOAT_FORMAT and directly use 'double' as a member in the svalue (and discard u.mantissa and x.exponent in that case), to save some calculation when using floats and only split into mantissa and exponent for storage in save_svalue()/restore_svalue()? Any comments on that idea?
(0000526)
hkremss   
2007-01-06 11:36   
> Mhmm, I might be wrong

No, you're right. My mistake to assume, that ph_int is 32 bit. To use double as member in svalue would be the best way, but it would change the size of 'union u' and svalue_s. Don't know if this causes more trouble somewhere else...
(0000630)
zesstra   
2008-06-30 08:09   
This may be a candidate for 3.5.x.
It would be necessary to check if the increase in size for the svalue is a blocker. BTW: That gets (in my opinion) less important with increased use of LP64 (64 bit) platforms as p_int is then anyway as big as a double.
(0000631)
Gnomi   
2008-06-30 08:42   
For LP64 I would suggest using double directly, but for 32 bit systems I would rather not increase svalue_t and stick to the old format or use float, because in LPC we use floats seldom, but svalues are everywhere, so that would be an enormous waste of space.
(0000632)
zesstra   
2008-06-30 09:00   
FTR: That sounds reasonable to me. ;-)
(0000633)
zesstra   
2008-06-30 09:20   
Ok, again FTR: ;-)
We have to clean up some code before we can work on this, e.g. stuff like this one from interpret.c:

    CASE(F_FLOAT); /* --- float <mant> <exp> --- */
    {
        /* Push the float build from <mant> (4 bytes) and <exp> (2 bytes)
         * onto the stack. The binary format is the one determined
         * by STORE_DOUBLE in datatypes.h
         * TODO: This code makes heavy assumptions about data sizes and
         * TODO:: layout. E.g. there need not be a 16-Bit integral type
         * TODO:: available.
         * TODO: It should be rewritten to use the LOAD_ macros (but
         * TODO:: then the compiler needs to use them, too.
         */

Additionally, it may be an idea to use small inlineable (static) functions instead of defines. Would have to be tested for any runtime impact, but I would expect no difference with modern compilers.
(0001054)
fufu   
2009-04-17 17:59   
I see one problem with Gnomi's idea of making this change for LP64 only: It would change the rounding behaviour of LPC code between 32bit and 64bit versions of the driver, so the same code can have different results.

We'll have to decide whether that's acceptable, or perhaps we should provide a configue option for using the old 48 bit format on LP64 anyway.
(0002078)
zesstra   
2011-11-17 11:36   
Setting target version to 3.5.0.
Actually, since this is already another 5 years old and I expect a wide adoption of LP64 systems also fuer MUDs in the next 1-3 years, I personally don't care about the size increase. But Gnomi disagrees in this respect and wants to keep the old format for ILP32 systems.
So that would then be a third float format.

I think, I am in favor of accepting the different behaviour on the 2 architectures.

Independant of the float format used at runtime, I suggest to simplify the savefile format (version 3) and just use sprintf+sscanf for writing/parsing doubles in any case.
(0002082)
zesstra   
2011-11-22 00:11   
The new float format using native doubles to store LPC floats it now in the driver in the 3.5.x branch.
https://github.com/ldmud/ldmud/commit/95ad6fe1f9500d55e73db0f21d05c827a70a262d

The new format will be automatically activated on LP64 platforms, where the int already consumes 8 bytes in the svalues. It can be manually activated on other platforms as well, although the is currently no configure option for it.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
724 [LDMud 3.5] Compilation, Installation feature N/A 2010-02-12 09:35 2011-11-21 23:40
Reporter: fippo Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: JSON
Description: Someone recently asked me about that old patch (dec 2006) which contains efuns for integration of the JSON-C library (version 0.6 iirc) and why it is not included in the ldmud dist. I think I never even submitted it.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: json.patch (7,879 bytes) 2010-02-12 09:35
http://ldmud.eu/file_download.php?file_id=265&type=bug
Notes
(0001715)
zesstra   
2010-02-12 10:25   
Thanks Fippo. The patch applies mostly, with some changes in configure.in, but I did no further tests until now.
I think about adding the patch to ldmud-extensions first (repo for unofficial extensions/packages/user contributions for LDMud) and wait for comments from the user community.
(0001716)
Wildcat   
2010-02-12 11:07   
I was probably the one who mailed about it, I've been running it on Tsunami talking to a php webscript for about 6 weeks and no issues yet.
(0001717)
zesstra   
2010-02-12 15:39   
Ah. Ok. So, we are starting ldmud-extensions for contributions we are not yet sure about popularity or impact on the rest of the driver source. This can also be patches from/for specific muds or some ideas users want to play with, so that not everybody has to re-invent the wheel.
The idea is that we use a git repo with patches/packages at github, which everybody can clone and work on it (add patches, improve or test them etc).

As I said, I would start putting the patch there. Maybe somebody volounteers to write some documentation there... ;-)

FTR: Fippo, are you OK with the drivers 2-clause BSD license?
(0001722)
fippo   
2010-02-13 13:23   
zesstra: works for me - apart from the funny "no monetary gain" clause ,-)
(0001723)
zesstra   
2010-02-13 13:31   
Ok, great.
BTW: The monetary gain stuff is NOT part of the 2-clause BSD license. It concerns older parts of the drivers sources, but new contributions must not have that restriction.
The license we use since 2007 for new contributions to the driver (and preferably for ldmud-extensions) is this one here: http://github.com/zesstra/ldmud-extensions/blob/master/COPYING.template
(0001879)
zesstra   
2010-07-14 15:12   
Hate to ask, but is there already any documentation besides the .c? (Manpages)
(0001923)
zesstra   
2010-11-19 23:01   
I updated the patch to apply cleanly to the current trunk and added it to https://github.com/ldmud/ldmud-extensions.
If somebody adds some documentation and there are some more users to try/test it, I will add it to the main distribution.
(0002081)
zesstra   
2011-11-21 23:40   
Unfortunately, nobody seemed to interested to work on it.

However, I now spent some evenings on it and did some extensive changes concerning error handling, documentation, 64 bit support, struct support, mapping support and some other things. Especially the error handling was insufficient, because there were some places where objects could be leaked if there was an error in the recursion - especially bad because JSON objects are not garbage-collected. I also added a bunch of test cases.

The whole collection is in r3048 in the 3.5 branch (https://github.com/ldmud/ldmud/commit/a3121d77ea23777a31776b58ae7730b07e791ad3)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
234 [LDMud 3.5] Runtime feature N/A 2004-11-26 23:39 2011-03-01 18:41
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: feedback Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Faster callouts
Description: Short: Faster callouts
From: "Dale Perkins" <elric@lpmud.com>
Date: 00/11/16
Type: Feature
State: New


I will make the diff, shoudl I email it to you or set it somewhere you can
ftp it from?
I just finished changing it so it will work on the new ldmud-23dev238
driver, there are a couple
of warnings but they may be warnings that show up anyways when compiling on
freebsd, I'm not sure. The code for fast_call_out is a bit of a cludge, I
just copied new_call_out to new_fast_call_out
and in new_call_out multiplied the time by 10. I didn't do much (translate
as any) documentation so let me explain a few things that might appear odd.
of to add tenths of a second to the tv_sec time you times tv_sec by 10 then
add tv_usec/100,000 but then its too big, so i added another variable called
big_time which is 90,000,000 hmm its always that i could prolly just define
it as that and remove that computation. Anyways the variable current_time is
now 10ths of seconds since teh epoch - 90 million. I fixed the efun time()
to get secs again but I still need to fix timestamp (actually I just
realized that i didnt) timestamps say its 1993 ;) ahh the good ol days :) hm
find_call_out, I have no idea what to do here. fast_call_outs and call_outs
are all together and there is no real way to tell them apart so
find_call_out returns 10ths of seconds left till its called

As for machine load, well i have been using the 'top' command and it still
doesnt even register as 1%
of cpu (an AMD K6-200) while using a slightly modified 2.4.5 lib and I am
not sure of any otehr way to test its usage.

Ok, this email is a mess, never write email while under the influence of
cold medicine, although coding this way is kinda neat ;'p

Elric
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: p-010707.gz (3,267 bytes) 2004-11-27 01:12
http://ldmud.eu/file_download.php?file_id=29&type=bug
Notes
(0001422)
zesstra   
2009-10-02 10:04   
Ok, the implementation here seems to a bit chaotic. But I suggest to decide first, if there is need enough for call_outs with a 0.1s delay. I am sceptical.
(0001453)
Gnomi   
2009-10-05 09:18   
There is a discussion on this on lpmuds.net:
http://lpmuds.net/forum/index.php?topic=1004.0

I would not oppose this, but it's not a high priority for me.
(0001457)
zesstra   
2009-10-05 10:04   
I skimmed the linked thread and have some comments concerning the proposed combat use:
a) 1s delays are possible
b) anything less separated than 0.5s is basically simultaneous for me as player and even that is difficult to read, if there comes a bunch of text every 0.5s.
c) in case of 0.1s resolution between combat actions, combat gets chaotic if players have a latence of more than 0.1s second between them and the mud.
(0001459)
Gnomi   
2009-10-05 10:41   
I don't know whether I'd use subsecond call_outs in our MUD (because of these reasons). But when somebody else wants to use them it's his decision...
(0001461)
zesstra   
2009-10-05 11:16   
Well sure. Once it is there, certainly. But its your, Fuchurs or my task to code and maintain it. ;-) And that requires that at least the one of us who does it, is convinced of the idea and really wants to do it. I am just trying to estimate the usefulness for the majority of muds.

BTW: There are two things to this:
a) allow callouts with delays < 1s
b) process callouts more often. Example:
call_out("fun1",1); // time 0.0s
...
call_out("fun2",1); // time 0.4s
So then fun1 should be called at 1.0s, fun2 and 1.4s, but in practice they are called a 1s and 2s and the two don't have 0.4s delay between them but 1s.
(0002029)
Coogan   
2011-02-24 01:05   
To cite Zesstra from above:

c) in case of 0.1s resolution between combat actions, combat gets chaotic if players have a latence of more than 0.1s second between them and the mud.

In case of a huge combat action where several players or/and NPCs are involved the combat actions better shall be delayed so one does not miss the really important parts of the scrolling text.

For my opinion, I do not support callouts with fractions of seconds.
(0002046)
nik   
2011-03-01 18:41   
MMORPGs generally operate on sub-second resolution for everything and I agree that it is a tricky subject in combination with latency. So there might be little reasons to move lower than 1 second. It could be nice to have 1.5 seconds, though.

I can imagine some use for higher callout resolution:
- WoW-style haste modificators that apply cast time modifications in the percent range
- Adapting the combat round duration to your combat system design (maybe 2.5 seconds would be ideal...)
- Remove round-based combat entirely
- Periodic damage / healing with combat-round-independent timing
- Shorten the delay of a periodic event with each repetition (e.g. slowly enraging enemies which do something increasingly often).

It generally could give game designers more tools.

On the other hand, I personally do not see something like this in the short to middle term in our mud and it would require at least some (fairly mechanizable) checking of all legacy mudlib code.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
172 [LDMud] Networking feature N/A 2004-11-26 22:11 2011-02-24 10:58
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Inter-object communication (was: New efun: receive())
Description: Short: new efun receive()
From: Dave Setty <garpoz@locallink.net>
Date: Thu, 10 Dec 1998 02:03:04 -0500
Type: Feature
State: Unclassified

4) I don't know if this would be generally desirable or not, but I've
   also got a patch that removes the various comm efuns (write, say,
   tell_object, tell_room etc) and puts in the single efun
   send_message() (which is called from inside an interactive to send
   a message out). The idea is to give the lib more control over how
   messages are passed around, and get rid of the hardcoded applies
   catch_tell() and catch_msg(). The problem is, for compatibility
   there'd have to be a switch to support this stuff in the driver (or
   at least a lot of supplied simuls, which can be a problem itself).

This is what MudOS does, too, and quite a big change. Eventually,
it will come, but it is better to implement generic TCP support first.

Date: Fri, 8 Jan 1999 02:02:30 -0500 (EST)
From: ak853@cleveland.Freenet.Edu (Eric Blade)


    The fewer driver called applies, the better, IMHO. Similar to the
    message() efun in MudOS. If you ask me, it's a great idea. I think
    there should effectively b e, just tell_object(). Use send_message() as
    a simul, tell_object() tells just that object, and that object
    determines what to do with it. catch_tell() is still a fine name to use
    as an apply. SOmewhere or other, You almost have to have an apply, so
    the mudlib can figure out what to do with the message.

    hell, I giuess you don't even need send_message()...

    So you tell_object() a room. The room decides that it should send
    everything to everyone inside it. So, it figures out what is in the
    room and could possibly listen to what it's saying, and it in turn
    tell_object()s all the objects that should hear it. The player object
    has a catch_tell() which decides if that message is worth display to the
    user or not. And so on.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
201 [LDMud 3.5] Runtime feature N/A 2004-11-26 22:43 2011-02-24 10:56
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: feedback Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Can catch_msg() be removed?
Description: Short: Unused apply catch_msg()
Date: 990319
From: Coogan
Type: Feature
State: Unclassified

Can the catch_msg() functionality be removed?
Nobody seems to use it.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0002009)
zesstra   
2011-02-20 00:30   
I had a look in our mudlib and see about 15 objects from 5-6 wizards using it. While it is not nobody, it does not look like it is really needed, although tell_room() is faster than a corresponding foreach() over the inventory.
(0002012)
Sorcerer   
2011-02-20 16:21   
There are libs out there (e.g. one I worked a lot on some time back) that rely on catch_msg() for processing texts given to players (for those using UNIlib: it does essentially the same as the send_message-mechanism).
For that purpose, some time back (issue 354) even tell_object() was modified to conform to other functions like tell_room() calling catch_msg().

So I strongly vote against removing catch_msg().
(0002013)
Coogan   
2011-02-21 00:16   
I've got the feeling that implementing the symmetry by Lars in 0000354 only consolidated the use of an apply from the early years of the driver.

Wasn't the development in 3.5 thought as a major release, cleaning up code? ;-)
(0002016)
zesstra   
2011-02-21 10:15   
Oh, to prevent mis-understandings: my statement was only about the situation in MG, not the usage in general.
In general, I hope that people using catch_msg() in their mudlibs (or not) will speak up here. ;-)
(0002040)
zesstra   
2011-02-24 10:56   
BTW: We might also do the other way round: remove catch_tell(), call catch_msg() also for strings and let the mudlib dispatch string messages to catch_tell() or do whatever it likes.

An even bigger change is to remove all the write, say, tell_* stuff and their applies, add an efun solely for interactive objects to send a message to their network socket and let the mudlib deal completely with everything else. Or reduce it to tell_object() and one apply (e.g. if you tell_object() to a room, that room could decide to tell it to its contained objects).
This is discussed in 0000172, maybe I should link it as related here. ;-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
279 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-27 00:43 2011-02-24 01:00
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: feedback Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Tuple return values
Description: Short: Tuple return values
Date: Sat, 9 Feb 2002 22:04:28 +0100 (CET)
From: Markus Peter <warp@spin.de>
Type: Feature
State: New

Hallo

Mir ist heute etwas eingefallen, was evtl. ganz nett waere fuer den 3.3er
Driver, und zwar geht es um das Problem, dass eine Methode/Funktion evtl.
mal mehr als 1 Wert zurueckgeben will. Ein Objekt will man da oft nicht
verwenden weil zu ueberdimensioniert, Pass-by-reference ist als Interface
ebenfalls unschoen, also gibt man einen Array zurueck.

Benutzt man die Methode/Funktion sieht das dann meist so aus:
mixed tmp= function();
string str= tmp[0];
int i1= tmp[1];

etc. - nicht wirklich schoen.

Perl hat dafuer eine schoene Loesung gefunden - und zwar kann man dort
ein Konstrukt der Form ($var1,$var2,@rest)=function() machen, und der
erste Wert des Rueckgabearrays wird dann an var1 zugewiesen etc.

Eigentlich sollte es nichts geben, was es verbieten wuerde, ein Element
dieser Art auch in LPC einzufuehren, also z.b.:

({str,i1})= function();

Ich faend das fuer Klarheit des Ausdrucks des Codes und Kuerze eigentlich
ganz nett, (ausserdem krieg ich dann vielleicht mal zumindestens die
Perlprogrammierer unter meinen faulen Wizards zum arbeiten ;-), kann aber
natuerlich nicht beurteilen, wieviel Aufwand das konkret bedeutet, oder ob
sich die Sprache dann fuer deinen Geschmack zu weit von seinen C-Syntax
Wurzeln wegbewegt.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001559)
zesstra   
2009-10-27 08:42   
I think, one could just use a struct for this and save the hassle to build a new interface for function calls... Would be also much nicer with respect to types.
(0002028)
Coogan   
2011-02-24 01:00   
The use a struct for return values and to split it up afterwards is IMHO not really an improvement compared to the use of an array as return value. Type checking should also take place for the described construct like
int i;
string s;
mapping m;
({s,i,m}) = function(...)

In principle I like that idea, but I don't know any case where I would have used it in the last years.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
750 [LDMud 3.3] Runtime minor have not tried 2010-04-30 09:46 2011-02-23 23:22
Reporter: fufu Platform:  
Assigned To: fufu OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: pkg-mysql: "MySQL server has gone away" errors on long-lived db connections
Description: If a long-lived database connection goes idle for too long, executing statements on the handle will abort with a "MySQL server has gone away" error. This happens since mysql-5.0.3, which changed the default for db handles for automatic reconnects from on to off.

I'm proposing to restore the pre-mysql-5.0.3 behaviour by explicitely switching on reconnects using

my_bool true = MY_TRUE;
mysql_options(tmp->mysql_dat, MYSQL_OPT_RECONNECT, &true);

after the mysql_real_connect(...) call.

Are there any objections to this change?
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001862)
zesstra   
2010-04-30 17:35   
I don't think I object. Was there a special reason, why this default was changed by the MySQL guys?
(0001863)
fufu   
2010-05-02 03:35   
As far as I understand, the reason they changed it was that on reconnect, all session settings (as modified with the SET statement) and temporary tables are lost. Letting this happen silently is a bad default.

On the other hand, automatic reconnects are very convenient if you do not rely on such state.

I'll document the fact that reconnects may happen silently if/when I make this change.

As an alternative, we could provide a db_options function exposing this setting, so every MUD can deal with this matter as appropriate. But I'd only do this if anybody actually cares about session state.
(0001864)
zesstra   
2010-05-02 10:44   
Uh, that sounds really like a bad default in general.
Currently I don't really know if I would care about the session state, because we don't use pkg-mysql.
I could imagine creating temporary tables for data which should be discarded once the object gets destroyed, but then it sounds not like a good idea in the first place because of the possible disconnects and it is probably anyway better to keep it in the driver's memory.
So, I guess, I don't mind the silent loss of session state right now.
(0001866)
fufu   
2010-05-04 11:03   
committed as r2917 (3.5 branch) and r2918 (3.3 branch)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
739 [LDMud 3.3] Efuns minor always 2010-03-24 13:01 2011-02-23 23:22
Reporter: szalicil Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.719  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: convert_charset empty string
Description: convert_charset returns its third parameter(to_cs) when converting empty string
Tags:
Steps To Reproduce: convert_charset("","anything","somethingelse")
Additional Information:
Attached Files:
Notes
(0001835)
zesstra   
2010-04-26 17:00   
Thanks for your report, I will take care of this now.
(0001836)
zesstra   
2010-04-26 17:21   
Should be fixed by r2906 (3.3) and r2907 (3.5). :-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
712 [LDMud 3.3] Runtime crash have not tried 2010-01-17 15:43 2011-02-23 23:22
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version:  
Product Build: r2819 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: get_type_info(<closure>, 4) looses refcount to function name of <closures>
Description: I had some crashes in my homemud, illegal svalues ((free_svalue) Illegal svalue 0x102afe460 type 188909664) and a segmentation fault in save_string().

It occurred while moving test players automatically through the lib. I have core dumps for 2 different crashes (although I think they are related).

(I will post all data into 'Additional Information', so that they are not mailed around with every change of this issue.)

I can provoke the issue quite reliably, but right now I need the complete MG mublib for it.
The cores are both around 550 MB large. *sigh* Actually... I just notice: both core dumps have _exactly_ the same size: 557469696.
-r-------- 1 dsch dsch 557469696 18 Jan 16:36 core.27855
-r-------- 1 dsch dsch 557469696 18 Jan 20:32 core.31337
I don't believe in coindidence here...
Tags: crash, memory corruption, reference counter
Steps To Reproduce:
Additional Information: First crash:
===========
#0 0x00000001000d178d in dump_core () at simulate.c:587
587 *((char*)0) = 0/a;
(gdb) bt
#0 0x00000001000d178d in dump_core () at simulate.c:587
0000001 0x00000001000d16bf in fatal (fmt=Could not find the frame base for "fatal".
) at simulate.c:649
0000002 0x000000010004e578 in int_free_svalue (v=0x102afe460) at interpret.c:1129
0000003 0x000000010004e87f in free_svalue (v=0x102afe460) at interpret.c:1292
0000004 0x00000001000869aa in free_map_chain (m=0x10fa12268, mch=0x102afe458, no_data=false) at mapping.c:371
0000005 0x0000000100086910 in _free_mapping (m=0x10fa12268, no_data=false) at mapping.c:668
0000006 0x000000010004f6c6 in inl_transfer_svalue (dest=0x108bf2548, v=0x10016dcf0) at interpret.c:2036
0000007 0x0000000100059cfd in eval_instruction (first_instruction=0x1035175e4 "a\004\002?\003<&\b?\002", initial_sp=0x10016da60) at interpret.c:10214
0000008 0x000000010006d778 in apply_low (fun=0x102b3a4b8, ob=0x105920298, num_arg=4, b_ign_prot=false, allowRefs=false) at interpret.c:17052
0000009 0x000000010006de58 in int_apply (fun=0x102b3a4b8, ob=0x105920298, num_arg=4, b_ign_prot=false, b_use_default=true) at interpret.c:17246
0000010 0x0000000100068dc0 in eval_instruction (first_instruction=0x102f26704 "\b\t\002\017/k\001\031\002\017\022\002*x\t)b\036", initial_sp=0x10016d940) at interpret.c:16510
0000011 0x000000010006d778 in apply_low (fun=0x102c7ccc0, ob=0x104b48c70, num_arg=1, b_ign_prot=false, allowRefs=false) at interpret.c:17052
0000012 0x000000010006de58 in int_apply (fun=0x102c7ccc0, ob=0x104b48c70, num_arg=1, b_ign_prot=false, b_use_default=true) at interpret.c:17246
0000013 0x0000000100068dc0 in eval_instruction (first_instruction=0x102f07bec "a\005\v\036", initial_sp=0x10016d820) at interpret.c:16510
#14 0x000000010006d778 in apply_low (fun=0x102ae8520, ob=0x105920298, num_arg=2, b_ign_prot=false, allowRefs=false) at interpret.c:17052
#15 0x000000010006de58 in int_apply (fun=0x102ae8520, ob=0x105920298, num_arg=2, b_ign_prot=false, b_use_default=true) at interpret.c:17246
#16 0x0000000100068dc0 in eval_instruction (first_instruction=0x1058f453f "b\036\004\n\006\036", initial_sp=0x10016d6e0) at interpret.c:16510
#17 0x00000001000d10a0 in catch_instruction (flags=6, offset=15, i_sp=0x100bf3710, i_pc=0x1058f453f "b\036\004\n\006\036", i_fp=0x10016d650, reserve_cost=100000, i_context=0x0) at simulate.c:449
#18 0x0000000100058b17 in eval_instruction (first_instruction=0x1058f480c "a\001\002\022\n\016`?\026", initial_sp=0x10016d5f0) at interpret.c:9721
#19 0x000000010006facb in int_call_lambda (lsvp=0x10c3ec188, num_arg=1, allowRefs=false, external=true) at interpret.c:18143
#20 0x00000001000d8cd1 in execute_callback (cb=0x10c3ec188, nargs=0, keep=false, toplevel=true) at simulate.c:4067
#21 0x0000000100011bd0 in call_out () at call_out.c:441
#22 0x000000010000d500 in backend () at backend.c:733
#23 0x0000000100082ae3 in main (argc=2, argv=0x7fff5fbff850) at main.c:673

Last operations + LPC stack:
2010.01.18 20:32:26 (free_svalue) Illegal svalue 0x102afe460 type 188909664
2010.01.18 20:32:26 Current object was human:teutates
human:teutates std/thing/properties.c line 207
0x102db92bf: 107 branch_when_zero (1:132) line 207
0x102db9306: 98 save_arg_frame (0:131) line 236
0x102db9307: 125 2 push_local_variable_lvalue (1:132)
0x102db9309: 208 this_object (2:133)
0x102db930a: 10 3 cstring0 (3:134)
0x102db930c: 30 0 local (4:135)
0x102db930e: 42 + (5:136)
0x102db930f: 414 8 call_resolved (4:135)
0x102db9311: 99 restore_arg_frame (2:133)
0x102db9312: 107 402791939 branch_when_zero (1:132)
0x102db9317: 8 0 identifier (0:131) line 240
0x102db9319: 15 const0 (1:132)
0x102db931a: 61 index (2:133)
0x102db931b: 30 0 local (1:132)
0x102db931d: 61 index (2:133)
0x102db931e: 24 return (1:132)
human:teutates std/player/life.c line 666
0x103531712: 99 restore_arg_frame (23:128) line 666
0x103531713: 10 21 cstring0 (22:127) line 667
0x103531715: 98 save_arg_frame (23:128)
0x103531716: 10 21 cstring0 (24:129)
0x103531718: 111 call_function (25:130)
human:teutates std/thing/properties.c line 199
0x102db92ac: 97 513 clear_locals (0:133) line 199
0x102db92af: 208 this_object (0:133) line 203
0x102db92b0: 198 objectp (1:134)
0x102db92b1: 108 6401 branch_when_non_zero (1:134)
0x102db92b4: 8 0 identifier (0:133) line 207
0x102db92b6: 18 3 clit (1:134)
0x102db92b8: 61 index (2:135)
0x102db92b9: 30 0 local (1:134)
0x102db92bb: 61 index (2:135)
0x102db92bc: 125 1 push_local_variable_lvalue (1:134)
0x102db92be: 40 = (2:135)
0x102db92bf: 107 branch_when_zero (1:134)
0x102db9306: 98 save_arg_frame (0:133) line 236
0x102db9307: 125 2 push_local_variable_lvalue (1:134)
0x102db9309: 208 this_object (2:135)
0x102db930a: 10 3 cstring0 (3:136)
0x102db930c: 30 0 local (4:137)
0x102db930e: 42 + (5:138)
0x102db930f: 414 8 call_resolved (4:137)
0x102db9311: 99 restore_arg_frame (2:135)
0x102db9312: 107 402791939 branch_when_zero (1:134)
0x102db9317: 8 0 identifier (0:133) line 240
0x102db9319: 15 const0 (1:134)
0x102db931a: 61 index (2:135)
0x102db931b: 30 0 local (1:134)
0x102db931d: 61 index (2:135)
0x102db931e: 24 return (1:134)
human:teutates std/player/life.c line 667
0x10353171b: 99 restore_arg_frame (25:130) line 667
0x10353171c: 10 48 cstring0 (24:129) line 668
0x10353171e: 98 save_arg_frame (25:130)
0x10353171f: 10 48 cstring0 (26:131)
0x103531721: 111 call_function (27:132)
human:teutates std/thing/properties.c line 199
0x102db92ac: 97 513 clear_locals (0:135) line 199
0x102db92af: 208 this_object (0:135) line 203
0x102db92b0: 198 objectp (1:136)
0x102db92b1: 108 6401 branch_when_non_zero (1:136)
0x102db92b4: 8 0 identifier (0:135) line 207
0x102db92b6: 18 3 clit (1:136)
0x102db92b8: 61 index (2:137)
0x102db92b9: 30 0 local (1:136)
0x102db92bb: 61 index (2:137)
0x102db92bc: 125 1 push_local_variable_lvalue (1:136)
0x102db92be: 40 = (2:137)
0x102db92bf: 107 branch_when_zero (1:136)
0x102db9306: 98 save_arg_frame (0:135) line 236
0x102db9307: 125 2 push_local_variable_lvalue (1:136)
0x102db9309: 208 this_object (2:137)
0x102db930a: 10 3 cstring0 (3:138)
0x102db930c: 30 0 local (4:139)
0x102db930e: 42 + (5:140)
0x102db930f: 414 8 call_resolved (4:139)
0x102db9311: 99 restore_arg_frame (2:137)
0x102db9312: 107 402791939 branch_when_zero (1:136)
0x102db9317: 8 0 identifier (0:135) line 240
0x102db9319: 15 const0 (1:136)
0x102db931a: 61 index (2:137)
0x102db931b: 30 0 local (1:136)
0x102db931d: 61 index (2:137)
0x102db931e: 24 return (1:136)
human:teutates std/player/life.c line 668
0x103531724: 99 restore_arg_frame (27:132) line 668
0x103531725: 10 3 cstring0 (26:131) line 669
0x103531727: 98 save_arg_frame (27:132)
0x103531728: 10 3 cstring0 (28:133)
0x10353172a: 111 call_function (29:134)
human:teutates std/thing/properties.c line 199
0x102db92ac: 97 513 clear_locals (0:137) line 199
0x102db92af: 208 this_object (0:137) line 203
0x102db92b0: 198 objectp (1:138)
0x102db92b1: 108 6401 branch_when_non_zero (1:138)
0x102db92b4: 8 0 identifier (0:137) line 207
0x102db92b6: 18 3 clit (1:138)
0x102db92b8: 61 index (2:139)
0x102db92b9: 30 0 local (1:138)
0x102db92bb: 61 index (2:139)
0x102db92bc: 125 1 push_local_variable_lvalue (1:138)
0x102db92be: 40 = (2:139)
0x102db92bf: 107 branch_when_zero (1:138)
0x102db9306: 98 save_arg_frame (0:137) line 236
0x102db9307: 125 2 push_local_variable_lvalue (1:138)
0x102db9309: 208 this_object (2:139)
0x102db930a: 10 3 cstring0 (3:140)
0x102db930c: 30 0 local (4:141)
0x102db930e: 42 + (5:142)
0x102db930f: 414 8 call_resolved (4:141)
0x102db9311: 99 restore_arg_frame (2:139)
0x102db9312: 107 402791939 branch_when_zero (1:138)
0x102db9317: 8 0 identifier (0:137) line 240
0x102db9319: 15 const0 (1:138)
0x102db931a: 61 index (2:139)
0x102db931b: 30 0 local (1:138)
0x102db931d: 61 index (2:139)
0x102db931e: 24 return (1:138)
human:teutates std/player/life.c line 669
0x10353172d: 99 restore_arg_frame (29:134) line 669
0x10353172e: 170 269 m_caggregate (28:133) line 670
0x103531731: 111 call_function (3:108)
human:teutates std/thing/properties.c line 146
0x102db91fc: 97 514 clear_locals (0:111) line 146
0x102db91ff: 208 this_object (0:111) line 150
0x102db9200: 198 objectp (1:112)
0x102db9201: 108 6401 branch_when_non_zero (1:112)
0x102db9204: 8 0 identifier (0:111) line 154
0x102db9206: 16 const1 (1:112)
0x102db9207: 61 index (2:113)
0x102db9208: 30 0 local (1:112)
0x102db920a: 61 index (2:113)
0x102db920b: 14 number (1:112)
0x102db9214: 54 & (2:113)
0x102db9215: 107 branch_when_zero (1:112)
0x102db9219: 8 0 identifier (0:111) line 157
0x102db921b: 18 2 clit (1:112)
0x102db921d: 61 index (2:113)
0x102db921e: 30 0 local (1:112)
0x102db9220: 61 index (2:113)
0x102db9221: 125 2 push_local_variable_lvalue (1:112)
0x102db9223: 40 = (2:113)
0x102db9224: 107 branch_when_zero (1:112)
0x102db926f: 98 save_arg_frame (0:111) line 188
0x102db9270: 125 3 push_local_variable_lvalue (1:112)
0x102db9272: 208 this_object (2:113)
0x102db9273: 10 2 cstring0 (3:114)
0x102db9275: 30 0 local (4:115)
0x102db9277: 42 + (5:116)
0x102db9278: 30 1 local (4:115)
0x102db927a: 414 8 call_resolved (5:116)
0x102db927c: 99 restore_arg_frame (2:113)
0x102db927d: 107 402857475 branch_when_zero (1:112)
0x102db9282: 98 save_arg_frame (0:111) line 192
0x102db9283: 30 0 local (1:112)
0x102db9285: 30 1 local (2:113)
0x102db9287: 15 const0 (3:114)
0x102db9288: 192 extern_call (4:115)
0x102db9289: 111 call_function (5:116)
0x102db8fec: 208 this_object (0:117) line 73
0x102db8fed: 198 objectp (1:118)
0x102db8fee: 108 6401 branch_when_non_zero (1:118)
0x102db8ff1: 8 0 identifier (0:117) line 78
0x102db8ff3: 16 const1 (1:118)
0x102db8ff4: 61 index (2:119)
0x102db8ff5: 30 0 local (1:118)
0x102db8ff7: 61 index (2:119)
0x102db8ff8: 18 128 clit (1:118)
0x102db8ffa: 14 number (2:119)
0x102db9003: 55 | (3:120)
0x102db9004: 54 & (2:119)
0x102db9005: 38 && (1:118)
0x102db9010: 38 886091011 && (1:118) line 79
0x102db9015: 38 && (1:118) line 80
0x102db901d: 107 branch_when_zero (1:118)
0x102db9021: 8 0 identifier (0:117) line 84
0x102db9023: 16 const1 (1:118)
0x102db9024: 61 index (2:119)
0x102db9025: 30 0 local (1:118)
0x102db9027: 61 index (2:119)
0x102db9028: 14 number (1:118)
0x102db9031: 54 & (2:119)
0x102db9032: 38 && (1:118)
0x102db903f: 38 && (1:118) line 85
0x102db904d: 107 402789123 branch_when_zero (1:118)
0x102db9052: 30 2 local (0:117) line 89
0x102db9054: 16 const1 (1:118)
0x102db9055: 51 == (2:119)
0x102db9056: 39 5 || (1:118)
0x102db9058: 30 2 local (0:117)
0x102db905a: 18 4 clit (1:118)
0x102db905c: 51 == (2:119)
0x102db905d: 38 && (1:118)
0x102db906b: 38 && (1:118)
0x102db9076: 38 886091011 && (1:118) line 90
0x102db907b: 38 && (1:118) line 91
0x102db9083: 107 402854659 branch_when_zero (1:118)
0x102db9088: 30 2 local (0:117) line 94
0x102db908a: 28 switch (1:118)
0x102db914a: 30 1 local (0:117) line 127
0x102db914c: 108 branch_when_non_zero (1:118)
0x102db915c: 30 1 local (0:117) line 128
0x102db915e: 30 0 local (1:118)
0x102db9160: 8 0 identifier (2:119)
0x102db9162: 30 2 local (3:120)
0x102db9164: 126 push_indexed_lvalue (4:121)
0x102db9165: 130 index_lvalue (3:120)
0x102db9166: 41 (void)= (2:119) line 129
0x102db9167: 27 0 191 0 130 1 0 0
     338 ' CheckBPs' in 'd/erzmagier/zesstra/tools/libtester/libtester.c' ('d/erzmagier/zesstra/tools/libtester/libtester') line 224
   52892 ' bewege' in 'd/erzmagier/zesstra/tools/libtester/libtester.c' ('d/erzmagier/zesstra/tools/libtester/libtester') line 101
  152898 ' CATCH' in ('d/erzmagier/zesstra/tools/libtester/libtester')
  162795 ' move' in ' std/living/moving.c' (' human:teutates') line 393
  165263 ' NotifyMove' in ' std/player/moving.c' (' human:teutates') line 152
  165270 ' NotifyMove' in ' std/living/moving.c' (' human:teutates') line 158
  165768 ' InitAttack' in ' std/living/combat.c' (' human:teutates') line 2054
  165780 ' Attack2' in ' std/living/combat.c' ('d/gebirge/morgoth/drak/npc/baaz#474') line 572
  170777 ' Attack' in ' std/living/combat.c' ('d/gebirge/morgoth/drak/npc/baaz#474') line 870
  170885 ' Defend' in ' std/player/combat.c' (' human:teutates') line 157
  175178 ' Defend' in ' std/living/combat.c' (' human:teutates') line 1559
  175598 ' do_damage' in ' std/player/life.c' (' human:teutates') line 273
  176035 ' ' in ' std/player/life.c' (' human:teutates') line 670
  176071 ' SetProp' in 'std/thing/properties.c' (' human:teutates') line 192
  176120 ' Set' in 'std/thing/properties.c' (' human:teutates') line 129
2010.01.18 20:32:26 LDMud aborting on fatal error.
Floating point exception (core dumped)



Second crash:
============
#0 0x000000010009dd92 in save_string (src=0x102afe458) at object.c:5723
5723 c = *cp++;
(gdb) bt
#0 0x000000010009dd92 in save_string (src=0x102afe458) at object.c:5723
0000001 0x000000010009f3c4 in save_svalue (v=0x102c82490, delimiter=44 ',', writable=false) at object.c:6235
0000002 0x000000010009e2c3 in save_array (v=0x102c82460) at object.c:5838
0000003 0x000000010009f48d in save_svalue (v=0x102c5b9c0, delimiter=44 ',', writable=false) at object.c:6252
0000004 0x000000010009e2c3 in save_array (v=0x102c5b940) at object.c:5838
0000005 0x000000010009f48d in save_svalue (v=0x102b170d8, delimiter=44 ',', writable=false) at object.c:6252
0000006 0x000000010009df74 in save_mapping_filter (key=0x102b170c8, data=0x102b170e8, extra=0x1) at object.c:5763
0000007 0x00000001000890d9 in walk_mapping (m=0x102bafa50, func=0x10009df00 <save_mapping_filter>, extra=0x1) at mapping.c:2022
0000008 0x000000010009e060 in save_mapping (m=0x102bafa50) at object.c:5790
0000009 0x000000010009f6b1 in save_svalue (v=0x102b17490, delimiter=44 ',', writable=false) at object.c:6303
0000010 0x000000010009df74 in save_mapping_filter (key=0x102b17480, data=0x102b174a0, extra=0x1) at object.c:5763
0000011 0x00000001000890d9 in walk_mapping (m=0x102bafae0, func=0x10009df00 <save_mapping_filter>, extra=0x1) at mapping.c:2022
0000012 0x000000010009e060 in save_mapping (m=0x102bafae0) at object.c:5790
0000013 0x000000010009f6b1 in save_svalue (v=0x102b174c8, delimiter=44 ',', writable=false) at object.c:6303
#14 0x000000010009df74 in save_mapping_filter (key=0x102b174b8, data=0x102b174d8, extra=0x1) at object.c:5763
#15 0x00000001000890d9 in walk_mapping (m=0x102bb1868, func=0x10009df00 <save_mapping_filter>, extra=0x1) at mapping.c:2022
#16 0x000000010009e060 in save_mapping (m=0x102bb1868) at object.c:5790
#17 0x000000010009f6b1 in save_svalue (v=0x102bb81a8, delimiter=44 ',', writable=false) at object.c:6303
#18 0x000000010009df74 in save_mapping_filter (key=0x102bb8198, data=0x102bb81b8, extra=0x1) at object.c:5763
#19 0x00000001000890d9 in walk_mapping (m=0x102bb18b0, func=0x10009df00 <save_mapping_filter>, extra=0x1) at mapping.c:2022
#20 0x000000010009e060 in save_mapping (m=0x102bb18b0) at object.c:5790
#21 0x000000010009f6b1 in save_svalue (v=0x102b3f868, delimiter=10 '\n', writable=false) at object.c:6303
#22 0x00000001000a0547 in v_save_object (sp=0x10016d620, numarg=1) at object.c:6805
#23 0x0000000100056cc9 in eval_instruction (first_instruction=0x7fff5fbfccd0 "\a3\030?\002", initial_sp=0x10016d620) at interpret.c:8478
#24 0x00000001000705b0 in int_call_lambda (lsvp=0x10016d600, num_arg=2, allowRefs=false, external=true) at interpret.c:18423
#25 0x0000000100074b2d in v_funcall (sp=0x10016d620, num_arg=3) at interpret.c:20695
#26 0x0000000100056cc9 in eval_instruction (first_instruction=0x102c6730c "a\001\005\036", initial_sp=0x10016d5e0) at interpret.c:8478
#27 0x00000001000662ae in eval_instruction (first_instruction=0x102b434ac "\n'?-", initial_sp=0x10016d580) at interpret.c:15039
#28 0x000000010006d778 in apply_low (fun=0x102ae8670, ob=0x102a94e68, num_arg=0, b_ign_prot=false, allowRefs=false) at interpret.c:17052
#29 0x000000010006de58 in int_apply (fun=0x102ae8670, ob=0x102a94e68, num_arg=0, b_ign_prot=false, b_use_default=true) at interpret.c:17246
#30 0x000000010006e2c9 in sapply_int (fun=0x102ae8670, ob=0x102a94e68, num_arg=0, b_find_static=false, b_use_default=true) at interpret.c:17407
#31 0x00000001000d8d37 in execute_callback (cb=0x110a37d28, nargs=0, keep=false, toplevel=true) at simulate.c:4076
#32 0x0000000100011bd0 in call_out () at call_out.c:441
#33 0x000000010000d500 in backend () at backend.c:733
#34 0x0000000100082ae3 in main (argc=2, argv=0x7fff5fbff850) at main.c:673

This one was just a segmentation fault, no call to fatal(), no LPC stack trace...
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0001682)
zesstra   
2010-01-18 14:47   
Exchanged information about the crashes by 2 similar ones, because I have core dumps for them.
(0001692)
zesstra   
2010-01-23 11:54   
This bug was nasty, it showed itself in a variety of different effects (Crashes, not found functions, etc.), but finally Gnomi and me tracked it. It is present in 3.3. and 3.5, regardless of architecture.

get_type_info(<closure>, 4) returns the name of the function of lfun-closures. Unfortunately it does not increment the refcount of that string. This can lead to the premature free'ing of the string and its memory, while it is still in use. That situation usually leads to memory corruption and all kinds of undefined behaviour. It might also be possible to exploit that in other ways than just DoS.

I will prepare a fix soon.
(0001694)
zesstra   
2010-01-24 12:34   
Ok, issue fixed in r2826 (3.5) and r2824 (3.3).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
708 [LDMud 3.3] Runtime crash unable to reproduce 2009-12-14 10:50 2011-02-23 23:22
Reporter: zesstra Platform: x86_64  
Assigned To: Gnomi OS: MacOS X  
Priority: low OS Version: 10.5.x  
Status: resolved Product Version:  
Product Build: r2804 Resolution: duplicate  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: Illegal instruction encountered
Description: Today I got a crash due to an illegal instruction upon starting my homemud (see below). Unfortunately, I can't reproduce this issue so far and I don't have a core dump. :-(
I will just record the available data here in case this issue surfaces again.
Tags:
Steps To Reproduce:
Additional Information: Debuglog:
2009.12.14 13:43:01 LDMud 3.5.0 (Build $Revision$) (development)
2009.12.14 13:43:01 TLS: (OpenSSL) Keyfile 'key.pem', Certfile 'cert.pem'
2009.12.14 13:43:01 TLS: Error setting x509 keyfile:
2009.12.14 13:43:01 TLS: SSL error:02001002:system library:fopen:No such file or directory.
2009.12.14 13:43:01 TLS: SSL error:20074002:BIO routines:FILE_CTRL:system lib.
2009.12.14 13:43:01 TLS: SSL error:140B0002:SSL routines:SSL_CTX_use_PrivateKey_file:system lib.
2009.12.14 13:43:01 Hostname 'dhcp12.elan.ruhr-uni-bochum.de' address '134.147.139.170'
2009.12.14 13:43:01 UDP recv-socket requested for port: 4246
2009.12.14 13:43:21 LDMud ready for users.
2009.12.14 13:43:29 'illegal' instruction encountered.
2009.12.14 13:43:29 Current object was d/inseln/zesstra/vulkanweg/room/r1
2009.12.14 13:43:29 Dump of the call chain:
   38597 ' CloneTuerchen' in 'p/service/miril/advent/obj/adventmaster.c' ('p/service/miril/advent/obj/adventmaster') line 117
   57495 ' create' in 'd/inseln/zesstra/vulkanweg/room/r1.c' ('d/inseln/zesstra/vulkanweg/room/r1') line 56
   88294 ' AddItem' in 'std/container/items.c' ('d/inseln/zesstra/vulkanweg/room/r1') line 138
   88743 ' move' in ' std/living/moving.c' ('d/inseln/zesstra/vulkanweg/npc/winzer') line 358
   88783 ' move_object' in ' secure/simul_efun.c' (' secure/simul_efun') line 1337
   88784 #'move_object for 'd/inseln/zesstra/vulkanweg/npc/winzer.c' ('d/inseln/zesstra/vulkanweg/npc/winzer')
   88801 <lambda 0x100f28e09> in 'd/inseln/zesstra/vulkanweg/npc/winzer.c' ('d/inseln/zesstra/vulkanweg/npc/winzer') offset 31
   89083 ' init' in 'd/inseln/zesstra/vulkanweg/room/stdroom.c' ('d/inseln/zesstra/vulkanweg/room/r1') line 76

Last instructions:
2009.12.14 13:43:21 LDMud ready for users.
2009.12.14 13:43:29 'illegal' instruction encountered.
2009.12.14 13:43:29 Current object was d/inseln/zesstra/vulkanweg/room/r1
d/inseln/zesstra/vulkanweg/room/r1 std/room.c line 211
0x101afd07c: 99 restore_arg_frame (2: 48) line 211
0x101afd07d: 92 pop_value (1: 47)
0x101afd07e: 98 save_arg_frame (0: 46) line 212
0x101afd07f: 112 call_inherited (1: 47)
d/inseln/zesstra/vulkanweg/room/r1 std/room/commands.c line 25
0x101ac52a4: 98 save_arg_frame (0: 47) line 25
0x101ac52a5: 112 call_inherited (1: 48)
d/inseln/zesstra/vulkanweg/room/r1 std/thing/commands.c line 471
0x101ac74ac: 98 save_arg_frame (0: 48) line 471
0x101ac74ad: 10 21 cstring0 (1: 49)
0x101ac74af: 10 20 cstring0 (2: 50)
0x101ac74b1: 16 const1 (3: 51)
0x101ac74b2: 406 0 add_action (4: 52)
0x101ac74b4: 15 const0 (1: 49)
0x101ac74b5: 99 restore_arg_frame (2: 50)
0x101ac74b6: 92 pop_value (1: 49)
0x101ac74b7: 25 return0 (0: 48) line 472
d/inseln/zesstra/vulkanweg/room/r1 std/room/commands.c line 25
0x101ac52aa: 99 restore_arg_frame (2: 49) line 25
0x101ac52ab: 92 pop_value (1: 48)
0x101ac52ac: 98 save_arg_frame (0: 47) line 27
0x101ac52ad: 10 0 cstring0 (1: 48)
0x101ac52af: 10 1 cstring0 (2: 49)
0x101ac52b1: 406 0 add_action (3: 50)
0x101ac52b3: 15 const0 (1: 48)
0x101ac52b4: 99 restore_arg_frame (2: 49)
0x101ac52b5: 92 pop_value (1: 48)
0x101ac52b6: 98 save_arg_frame (0: 47) line 28
0x101ac52b7: 10 0 cstring0 (1: 48)
0x101ac52b9: 10 2 cstring0 (2: 49)
0x101ac52bb: 406 0 add_action (3: 50)
0x101ac52bd: 15 const0 (1: 48)
0x101ac52be: 99 restore_arg_frame (2: 49)
0x101ac52bf: 92 pop_value (1: 48)
0x101ac52c0: 98 save_arg_frame (0: 47) line 29
0x101ac52c1: 10 0 cstring0 (1: 48)
0x101ac52c3: 10 3 cstring0 (2: 49)
0x101ac52c5: 406 0 add_action (3: 50)
0x101ac52c7: 15 const0 (1: 48)
0x101ac52c8: 99 restore_arg_frame (2: 49)
0x101ac52c9: 92 pop_value (1: 48)
0x101ac52ca: 25 return0 (0: 47) line 30
d/inseln/zesstra/vulkanweg/room/r1 std/room.c line 212
0x101afd084: 99 restore_arg_frame (2: 48) line 212
0x101afd085: 92 pop_value (1: 47)
0x101afd086: 98 save_arg_frame (0: 46) line 213
0x101afd087: 112 call_inherited (1: 47)
d/inseln/zesstra/vulkanweg/room/r1 std/room/description.c line 38
0x101adfe14: 97 256 clear_locals (0: 48) line 38
0x101adfe17: 98 save_arg_frame (0: 48) line 43
0x101adfe18: 10 5 cstring0 (1: 49)
0x101adfe1a: 111 call_function (2: 50)
d/inseln/zesstra/vulkanweg/room/r1 std/thing/properties.c line 199
0x101aca0f4: 97 513 clear_locals (0: 53) line 199
0x101aca0f7: 208 this_object (0: 53) line 203
0x101aca0f8: 198 objectp (1: 54)
0x101aca0f9: 108 6401 branch_when_non_zero (1: 54)
0x101aca0fc: 8 0 identifier (0: 53) line 207
0x101aca0fe: 18 3 clit (1: 54)
0x101aca100: 61 index (2: 55)
0x101aca101: 30 0 local (1: 54)
0x101aca103: 61 index (2: 55)
0x101aca104: 125 1 push_local_variable_lvalue (1: 54)
0x101aca106: 40 = (2: 55)
0x101aca107: 107 branch_when_zero (1: 54)
0x101aca14e: 98 save_arg_frame (0: 53) line 236
0x101aca14f: 125 2 push_local_variable_lvalue (1: 54)
0x101aca151: 208 this_object (2: 55)
0x101aca152: 10 3 cstring0 (3: 56)
0x101aca154: 30 0 local (4: 57)
0x101aca156: 42 + (5: 58)
0x101aca157: 414 8 call_resolved (4: 57)
0x101aca159: 99 restore_arg_frame (2: 55)
0x101aca15a: 107 402791939 branch_when_zero (1: 54)
0x101aca15f: 8 0 identifier (0: 53) line 240
0x101aca161: 15 const0 (1: 54)
0x101aca162: 61 index (2: 55)
0x101aca163: 30 0 local (1: 54)
0x101aca165: 61 index (2: 55)
0x101aca166: 24 return (1: 54)
d/inseln/zesstra/vulkanweg/room/r1 std/room/description.c line 43
0x101adfe1d: 99 restore_arg_frame (2: 50) line 43
0x101adfe1e: 125 0 push_local_variable_lvalue (1: 49)
0x101adfe20: 40 = (2: 50)
0x101adfe21: 38 3 && (1: 49)
0x101adfe23: 30 0 local (0: 48)
0x101adfe25: 202 sizeof (1: 49)
0x101adfe26: 39 7 || (1: 49)
0x101adfe28: 98 save_arg_frame (0: 48) line 44
0x101adfe29: 10 6 cstring0 (1: 49)
0x101adfe2b: 111 call_function (2: 50)
d/inseln/zesstra/vulkanweg/room/r1 std/thing/properties.c line 199
0x101aca0f4: 97 513 clear_locals (0: 53) line 199
0x101aca0f7: 208 this_object (0: 53) line 203
0x101aca0f8: 198 objectp (1: 54)
0x101aca0f9: 108 6401 branch_when_non_zero (1: 54)
0x101aca0fc: 8 0 identifier (0: 53) line 207
0x101aca0fe: 18 3 clit (1: 54)
0x101aca100: 61 index (2: 55)
0x101aca101: 30 0 local (1: 54)
0x101aca103: 61 index (2: 55)
0x101aca104: 125 1 push_local_variable_lvalue (1: 54)
0x101aca106: 40 = (2: 55)
0x101aca107: 107 branch_when_zero (1: 54)
0x101aca14e: 98 save_arg_frame (0: 53) line 236
0x101aca14f: 125 2 push_local_variable_lvalue (1: 54)
0x101aca151: 208 this_object (2: 55)
0x101aca152: 10 3 cstring0 (3: 56)
0x101aca154: 30 0 local (4: 57)
0x101aca156: 42 + (5: 58)
0x101aca157: 414 8 call_resolved (4: 57)
0x101aca159: 99 restore_arg_frame (2: 55)
0x101aca15a: 107 402791939 branch_when_zero (1: 54)
0x101aca15f: 8 0 identifier (0: 53) line 240
0x101aca161: 15 const0 (1: 54)
0x101aca162: 61 index (2: 55)
0x101aca163: 30 0 local (1: 54)
0x101aca165: 61 index (2: 55)
0x101aca166: 24 return (1: 54)
d/inseln/zesstra/vulkanweg/room/r1 std/room/description.c line 44
0x101adfe2e: 99 restore_arg_frame (2: 50) line 44
0x101adfe2f: 38 && (1: 49)
0x101adfe37: 107 branch_when_zero (1: 49) line 45
0x101adfe4b: 25 return0 (0: 48) line 47
d/inseln/zesstra/vulkanweg/room/r1 std/room.c line 213
0x101afd08c: 99 restore_arg_frame (2: 48) line 213
0x101afd08d: 92 pop_value (1: 47)
0x101afd08e: 98 save_arg_frame (0: 46) line 214
0x101afd08f: 112 call_inherited (1: 47)
d/inseln/zesstra/vulkanweg/room/r1 std/room/doors.c line 86
0x101ae8e3c: 97 1024 clear_locals (0: 51) line 86
0x101ae8e3f: 98 save_arg_frame (0: 51) line 90
0x101ae8e40: 10 0 cstring0 (1: 52)
0x101ae8e42: 111 call_function (2: 53)
d/inseln/zesstra/vulkanweg/room/r1 std/thing/properties.c line 199
0x101aca0f4: 97 513 clear_locals (0: 56) line 199
0x101aca0f7: 208 this_object (0: 56) line 203
0x101aca0f8: 198 objectp (1: 57)
0x101aca0f9: 108 6401 branch_when_non_zero (1: 57)
0x101aca0fc: 8 0 identifier (0: 56) line 207
0x101aca0fe: 18 3 clit (1: 57)
0x101aca100: 61 index (2: 58)
0x101aca101: 30 0 local (1: 57)
0x101aca103: 61 index (2: 58)
0x101aca104: 125 1 push_local_variable_lvalue (1: 57)
0x101aca106: 40 = (2: 58)
0x101aca107: 107 branch_when_zero (1: 57)
0x101aca14e: 98 save_arg_frame (0: 56) line 236
0x101aca14f: 125 2 push_local_variable_lvalue (1: 57)
0x101aca151: 208 this_object (2: 58)
0x101aca152: 10 3 cstring0 (3: 59)
0x101aca154: 30 0 local (4: 60)
0x101aca156: 42 + (5: 61)
0x101aca157: 414 8 call_resolved (4: 60)
0x101aca159: 99 restore_arg_frame (2: 58)
0x101aca15a: 107 402791939 branch_when_zero (1: 57)
0x101aca15f: 8 0 identifier (0: 56) line 240
0x101aca161: 15 const0 (1: 57)
0x101aca162: 61 index (2: 58)
0x101aca163: 30 0 local (1: 57)
0x101aca165: 61 index (2: 58)
0x101aca166: 24 return (1: 57)
d/inseln/zesstra/vulkanweg/room/r1 std/room/doors.c line 90
0x101ae8e45: 99 restore_arg_frame (2: 53) line 90
0x101ae8e46: 125 0 push_local_variable_lvalue (1: 52)
0x101ae8e48: 40 = (2: 53)
0x101ae8e49: 199 pointerp (1: 52)
0x101ae8e4a: 108 1 branch_when_non_zero (1: 52)
0x101ae8e4c: 25 return0 (0: 51)
d/inseln/zesstra/vulkanweg/room/r1 std/room.c line 214
0x101afd094: 99 restore_arg_frame (2: 48) line 214
0x101afd095: 92 pop_value (1: 47)
0x101afd096: 98 save_arg_frame (0: 46) line 215
0x101afd097: 209 this_player (1: 47)
0x101afd098: 421 15 environment (2: 48)
0x101afd09a: 99 restore_arg_frame (2: 48)
0x101afd09b: 208 this_object (1: 47)
0x101afd09c: 52 != (2: 48)
0x101afd09d: 107 6401 branch_when_zero (1: 47)
0x101afd0a0: 98 save_arg_frame (0: 46) line 216
0x101afd0a1: 10 23 cstring0 (1: 47)
0x101afd0a3: 10 24 cstring0 (2: 48)
0x101afd0a5: 406 0 add_action (3: 49)
0x101afd0a7: 15 const0 (1: 47)
0x101afd0a8: 99 restore_arg_frame (2: 48)
0x101afd0a9: 92 pop_value (1: 47)
0x101afd0aa: 98 save_arg_frame (0: 46) line 217
0x101afd0ab: 10 23 cstring0 (1: 47)
0x101afd0ad: 10 25 cstring0 (2: 48)
0x101afd0af: 406 0 add_action (3: 49)
0x101afd0b1: 15 const0 (1: 47)
0x101afd0b2: 99 restore_arg_frame (2: 48)
0x101afd0b3: 92 pop_value (1: 47)
0x101afd0b4: 98 save_arg_frame (0: 46) line 218
0x101afd0b5: 10 23 cstring0 (1: 47)
0x101afd0b7: 10 26 cstring0 (2: 48)
0x101afd0b9: 406 0 add_action (3: 49)
0x101afd0bb: 15 const0 (1: 47)
0x101afd0bc: 99 restore_arg_frame (2: 48)
0x101afd0bd: 92 pop_value (1: 47)
0x101afd0be: 98 save_arg_frame (0: 46) line 219
0x101afd0bf: 10 23 cstring0 (1: 47)
0x101afd0c1: 10 27 cstring0 (2: 48)
0x101afd0c3: 406 0 add_action (3: 49)
0x101afd0c5: 15 const0 (1: 47)
0x101afd0c6: 99 restore_arg_frame (2: 48)
0x101afd0c7: 92 pop_value (1: 47)
0x101afd0c8: 25 return0 (0: 46) line 220
d/inseln/zesstra/vulkanweg/room/r1 d/inseln/zesstra/vulkanweg/room/stdroom.c line 70
0x104b50b1a: 99 restore_arg_frame (2: 47) line 70
0x104b50b1b: 92 pop_value (1: 46)
0x104b50b1c: 209 this_player (0: 45) line 72
0x104b50b1d: 294 60 query_once_interactive (1: 46)
0x104b50b1f: 107 branch_when_zero (1: 46)
0x104b50b3b: 0 0 0 0 0 0 0 0
[... stacktrace, see above ...]
2009.12.14 13:43:29 LDMud aborting on fatal error.
Floating point exception
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files: instrs.h (23,307 bytes) 2009-12-15 09:53
http://ldmud.eu/file_download.php?file_id=263&type=bug
Notes
(0001650)
zesstra   
2009-12-14 11:00   
BTW: Line 76 in d/inseln/zesstra/vulkanweg/room/stdroom.c is not in init(), but the beginning of the subsequent function reset():

68 void init() {
69
70 ::init();
71 //Master informieren, wenn this_player Spieler ist
72 if (query_once_interactive(TP))
73 VWMASTER->player_contact(TP);
74 }
75
76 void reset() {

Interestingly, if I am not mistaken, the thing to be executed should be a callother instead of that group of zeroes, similar to an 'illegal instruction' reported by Batmud in 3.3.x.
(0001651)
zesstra   
2009-12-15 09:48   
(Last edited: 2009-12-15 10:09)
The bytecode of init() should apparantly look like this:

init() and beginning of reset() in /d/inseln/zesstra/vulkanweg/room/stdroom.c
0x0000000106af7440 10 13 2c 01 01 00 00 00 c3 00 03 00 96 05 01 00
0x0000000106af7450 00 00 00 00 00 00 00 00 00 00 00 00 62 70 00 00
0x0000000106af7460 bb 00 63 5c d1 03 3c 6b 09 62 0a 11 0a 12 d1 bd
                                         ^ branch_when_zero
0x0000000106af7470 63 5c 19 00 00 00 00 00 50 15 2c 01 01 00 00 00
                          ^ end of init() (F_RETURN0)
0x0000000106af7480 f1 00 03 00 bf 5f ff 7f 00 00 00 00 00 00 00 00

(Copied after compilation of init() and reset(), but before the program was completed.)

(0001665)
Gnomi   
2009-12-22 10:17   
Very likely the same cause as 0000709, bugfix committed as r2809.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
692 [LDMud 3.3] Documentation text have not tried 2009-10-15 17:51 2011-02-23 23:22
Reporter: Coogan Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.719  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: improve some efun manpages
Description: when looking over some efun manpages, the following mistakes caught my eye, which are packed into a diff ready to apply against /doc/efun in trunk (and most probably also to trunk of 3.5)

* some typos in text
* exchanged german words (e.g. BESCHREIBUNG) by english ones (DESCRIPTION)
* correction of include statements: some manpages say e.g. "include <functionlist.h>", some "include <sys/functionlist.h>" -- corrected to <functionlist.h>
* section type EXAMPLE (whereas EXAMPLES is written in the majority of docs) have been corrected to EXAMPLES
* fixed the width and section indentation for some manpages
* minor changes
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: diff-doc-efun-en.patch (197,133 bytes) 2009-10-19 17:04
http://ldmud.eu/file_download.php?file_id=258&type=bug
diff-doc-efun-de.patch (399,246 bytes) 2009-10-19 17:05
http://ldmud.eu/file_download.php?file_id=259&type=bug
Notes
(0001526)
zesstra   
2009-10-17 06:41   
Thanks, I will take care of this soon.
I think, <sys/...> is deliberate, but I actually like <...> more, because mudlibs can put their header wherever they like and usually they use the include dir hook to enable access by <...> to them. So you have to delete the sys/ part when you copy the include statement from the manpage (and I sometimes forgot that).
(0001527)
zesstra   
2009-10-17 06:42   
Ah, one question: I assume you used at least partly grep/sed, could you just repeat that part for the german manpages as well in this case?
(0001536)
Coogan   
2009-10-19 17:04   
Forget the previously provided patches and use the new ones instead.
Both should apply cleanly to r2766.
(0001544)
zesstra   
2009-10-21 14:21   
Fixed in r2772 (trunk-3.3) and r2773 (trunk). Thanks Coogan. :-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
689 [LDMud 3.3] Runtime crash random 2009-10-05 14:44 2011-02-23 23:22
Reporter: Bardioc Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: Crash: Mapping entry didn't hash to the same spot.
Description: The driver (Version 3.5.0-2573) crashes with "Mapping entry didn't hash to the same spot.". Curently this is only reproducible within our mudlib, all "small" examples work as expected.

The following piece of code contains the bug in the marked line:

public mixed * mkset(mixed * arr)
{
    check(arr, IS_ARRAY);

    if (sizeof(arr) < 2)
    {
        return arr;
    }

    mapping set = mkmapping(arr);

    // walk through all entries in the array and if found in the mapping, remove it from there, if
    // not found in the mapping, remove it from the array
    for (int i = 0; i < sizeof(arr); i++)
    {
        if (member(set, arr[i]))
        {
            m_delete(set, arr[i]); <---- THE GAME CRASHES HERE
        }
        else
        {
            arr[i..i] = ({});

            --i;
        }
    }

    return arr;
}

The stack trace is:

2009.10.05 18:33:12 LDMud ready for users.
2009.10.05 18:54:56 Mapping entry didn't hash to the same spot.
2009.10.05 18:54:56 Current object was kernel/simul_efun
kernel/simul_efun kernel/simul_efuns/lpc.c line 1231
0x843a33f: 16 const1 (2: 65) line 1231
0x843a340: 42 + (3: 66)
0x843a341: 186 no_warn_deprecated (2: 65)
0x843a342: 61 index (2: 65)
0x843a343: 199 pointerp (1: 64)
0x843a344: 38 && (1: 64)
0x843a352: 38 && (1: 64) line 1232
0x843a39e: 107 branch_when_zero (1: 64) line 1234
0x843a3bc: 30 0 local (0: 63) line 1240
0x843a3be: 30 3 local (1: 64)
0x843a3c0: 186 no_warn_deprecated (2: 65)
0x843a3c1: 61 index (2: 65)
0x843a3c2: 30 0 local (1: 64)
0x843a3c4: 30 3 local (2: 65)
0x843a3c6: 16 const1 (3: 66)
0x843a3c7: 42 + (4: 67)
0x843a3c8: 186 no_warn_deprecated (3: 66)
0x843a3c9: 61 index (3: 66)
0x843a3ca: 168 2 aggregate (2: 65)
0x843a3cd: 168 1 aggregate (1: 64)
0x843a3d0: 125 2 push_local_variable_lvalue (1: 64)
0x843a3d2: 78 (void)+= (2: 65)
0x843a3d3: 18 2 clit (0: 63) line 1229
0x843a3d5: 125 3 push_local_variable_lvalue (1: 64)
0x843a3d7: 78 (void)+= (2: 65)
0x843a3d8: 30 3 local (0: 63)
0x843a3da: 30 0 local (1: 64)
0x843a3dc: 202 sizeof (2: 65)
0x843a3dd: 49 < (2: 65)
0x843a3de: 110 164 bbranch_when_non_zero (1: 64)
0x843a3e0: 97 259 clear_locals (0: 63) line 1245
0x843a3e3: 125 3 push_local_variable_lvalue (0: 63)
0x843a3e5: 30 2 local (1: 64)
0x843a3e7: 177 foreach (2: 65)
0x843a7ac: 180 foreach_next (0: 67) line 1457
0x843a3eb: 97 1028 clear_locals (0: 67) line 1250
0x843a3ee: 18 2 clit (0: 67)
0x843a3f0: 16 const1 (1: 68)
0x843a3f1: 18 3 clit (2: 69)
0x843a3f3: 18 3 clit (3: 70)
0x843a3f5: 18 4 clit (4: 71)
0x843a3f7: 18 4 clit (5: 72)
0x843a3f9: 18 5 clit (6: 73)
0x843a3fb: 18 5 clit (7: 74)
0x843a3fd: 18 7 clit (8: 75)
0x843a3ff: 18 6 clit (9: 76)
0x843a401: 18 8 clit (10: 77)
0x843a403: 18 7 clit (11: 78)
0x843a405: 18 6 clit (12: 79)
0x843a407: 18 8 clit (13: 80)
0x843a409: 18 11 clit (14: 81)
0x843a40b: 18 9 clit (15: 82)
0x843a40d: 170 264 m_caggregate (16: 83)
0x843a410: 30 3 local (1: 68)
0x843a412: 15 const0 (2: 69)
0x843a413: 186 no_warn_deprecated (3: 70)
0x843a414: 61 index (3: 70)
0x843a415: 211 typeof (2: 69)
0x843a416: 186 no_warn_deprecated (2: 69)
0x843a417: 61 index (2: 69)
0x843a418: 125 4 push_local_variable_lvalue (1: 68)
0x843a41a: 41 (void)= (2: 69)
0x843a41b: 30 3 local (0: 67) line 1254
0x843a41d: 16 const1 (1: 68)
0x843a41e: 186 no_warn_deprecated (2: 69)
0x843a41f: 61 index (2: 69)
0x843a420: 125 5 push_local_variable_lvalue (1: 68)
0x843a422: 41 (void)= (2: 69)
0x843a423: 30 5 local (0: 67) line 1255
0x843a425: 199 pointerp (1: 68)
0x843a426: 108 8 branch_when_non_zero (1: 68)
0x843a428: 30 5 local (0: 67) line 1257
0x843a42a: 168 1 aggregate (1: 68)
0x843a42d: 125 5 push_local_variable_lvalue (1: 68)
0x843a42f: 41 (void)= (2: 69)
0x843a430: 15 const0 (0: 67) line 1260
0x843a431: 125 6 push_local_variable_lvalue (1: 68)
0x843a433: 41 (void)= (2: 69)
0x843a434: 168 0 aggregate (0: 67) line 1261
0x843a437: 125 7 push_local_variable_lvalue (1: 68)
0x843a439: 41 (void)= (2: 69)
0x843a43a: 97 264 clear_locals (0: 67) line 1264
0x843a43d: 15 const0 (0: 67)
0x843a43e: 125 8 push_local_variable_lvalue (1: 68)
0x843a440: 41 (void)= (2: 69)
0x843a441: 103 lbranch (0: 67)
0x843a774: 30 8 local (0: 67)
0x843a776: 30 5 local (1: 68)
0x843a778: 202 sizeof (2: 69)
0x843a779: 49 < (2: 69)
0x843a77a: 105 lbranch_when_non_zero (1: 68)
0x843a444: 30 5 local (0: 67) line 1268
0x843a446: 30 8 local (1: 68)
0x843a448: 186 no_warn_deprecated (2: 69)
0x843a449: 61 index (2: 69)
0x843a44a: 199 pointerp (1: 68)
0x843a44b: 104 lbranch_when_zero (1: 68)
0x843a64f: 30 5 local (0: 67) line 1364
0x843a651: 30 8 local (1: 68)
0x843a653: 186 no_warn_deprecated (2: 69)
0x843a654: 61 index (2: 69)
0x843a655: 18 11 clit (1: 68)
0x843a657: 51 == (2: 69) line 1367
0x843a658: 107 branch_when_zero (1: 68)
0x843a663: 30 5 local (0: 67) line 1372
0x843a665: 30 8 local (1: 68)
0x843a667: 186 no_warn_deprecated (2: 69)
0x843a668: 61 index (2: 69)
0x843a669: 30 4 local (1: 68)
0x843a66b: 51 == (2: 69) line 1374
0x843a66c: 107 106 branch_when_zero (1: 68)
0x843a66e: 30 4 local (0: 67)
0x843a670: 16 const1 (1: 68)
0x843a671: 52 != (2: 69)
0x843a672: 38 5 && (1: 68)
0x843a674: 30 4 local (0: 67)
0x843a676: 18 6 clit (1: 68)
0x843a678: 52 != (2: 69) line 1377
0x843a679: 107 82 branch_when_zero (1: 68)
0x843a67b: 30 3 local (0: 67)
0x843a67d: 15 const0 (1: 68)
0x843a67e: 186 no_warn_deprecated (2: 69)
0x843a67f: 61 index (2: 69)
0x843a680: 15 const0 (1: 68)
0x843a681: 51 == (2: 69) line 1379
0x843a682: 107 branch_when_zero (1: 68)
0x843a6c2: 15 const0 (0: 67) line 1385
0x843a6c3: 125 6 push_local_variable_lvalue (1: 68) line 1387
0x843a6c5: 41 (void)= (2: 69)
0x843a6c6: 102 fbranch (0: 67)
0x843a77d: 30 6 local (0: 67) line 1444
0x843a77f: 107 branch_when_zero (1: 68)
0x843a7a9: 125 1 push_local_variable_lvalue (0: 67) line 1456
0x843a7ab: 32 ++ (1: 68)
0x843a7ac: 180 964 foreach_next (0: 67) line 1457
0x843a7af: 181 foreach_end (0: 67)
0x843a7b0: 25 return0 (0: 63) line 1458
0x843a7f6: 99 restore_arg_frame (2: 53) line 1512
0x843a7f7: 92 pop_value (1: 52)
0x843a7f8: 30 0 local (0: 51) line 1514
0x843a7fa: 202 sizeof (1: 52)
0x843a7fb: 18 2 clit (1: 52)
0x843a7fd: 49 < (2: 53)
0x843a7fe: 107 402660867 branch_when_zero (1: 52)
0x843a803: 97 257 clear_locals (0: 51) line 1519
0x843a806: 98 save_arg_frame (0: 51)
0x843a807: 30 0 local (1: 52)
0x843a809: 451 40 mkmapping (2: 53)
0x843a80b: 99 restore_arg_frame (2: 53)
0x843a80c: 125 1 push_local_variable_lvalue (1: 52)
0x843a80e: 41 (void)= (2: 53)
0x843a80f: 97 258 clear_locals (0: 51) line 1523
0x843a812: 15 const0 (0: 51)
0x843a813: 125 2 push_local_variable_lvalue (1: 52)
0x843a815: 41 (void)= (2: 53)
0x843a816: 106 branch (0: 51)
0x843a845: 30 2 local (0: 51)
0x843a847: 30 0 local (1: 52)
0x843a849: 202 sizeof (2: 53)
0x843a84a: 49 < (2: 53)
0x843a84b: 110 bbranch_when_non_zero (1: 52)
0x843a818: 98 save_arg_frame (0: 51) line 1525
0x843a819: 30 1 local (1: 52)
0x843a81b: 30 0 local (2: 53)
0x843a81d: 30 2 local (3: 54)
0x843a81f: 186 no_warn_deprecated (4: 55)
0x843a820: 61 index (4: 55)
0x843a821: 449 38 member (3: 54)
0x843a823: 99 restore_arg_frame (2: 53)
0x843a824: 107 13 branch_when_zero (1: 52)
0x843a826: 30 1 local (0: 51) line 1527
0x843a828: 30 0 local (1: 52)
0x843a82a: 30 2 local (2: 53)
0x843a82c: 186 no_warn_deprecated (3: 54)
0x843a82d: 61 index (3: 54)
0x843a82e: 366 23 m_delete (2: 53)
0x843a830: 92 pop_value (1: 52)
0x843a831: 106 branch (0: 51) line 1529
0x843a842: 125 2 push_local_variable_lvalue (0: 51) line 1523
0x843a844: 32 ++ (1: 52)
0x843a845: 30 2 local (0: 51)
0x843a847: 30 0 local (1: 52)
0x843a849: 202 sizeof (2: 53)
0x843a84a: 49 < (2: 53)
0x843a84b: 110 bbranch_when_non_zero (1: 52)
0x843a818: 98 save_arg_frame (0: 51) line 1525
0x843a819: 30 1 local (1: 52)
0x843a81b: 30 0 local (2: 53)
0x843a81d: 30 2 local (3: 54)
0x843a81f: 186 no_warn_deprecated (4: 55)
0x843a820: 61 index (4: 55)
0x843a821: 449 38 member (3: 54)
0x843a823: 99 restore_arg_frame (2: 53)
0x843a824: 107 13 branch_when_zero (1: 52)
0x843a826: 30 1 local (0: 51) line 1527
0x843a828: 30 0 local (1: 52)
0x843a82a: 30 2 local (2: 53)
0x843a82c: 186 no_warn_deprecated (3: 54)
0x843a82d: 61 index (3: 54)
0x843a82e: 366 m_delete (2: 53)
0x843a830: 92 106 15 168 0 0 30 2
' heart_beat' in ' class/npc/npc.c' ('domains/skeleton/npc/hobgoblin#254') line 288
' heart_beat' in 'class/living/living.c' ('domains/skeleton/npc/hobgoblin#254') line 472
'heart_beat_addon' in 'class/living/modules/combat.c' ('domains/skeleton/npc/hobgoblin#254') line 5409
' do_attack' in 'class/living/modules/combat.c' ('domains/skeleton/npc/hobgoblin#254') line 4707
' damage' in 'class/living/living.c' ('class/interactive/interactive#190') line 1019
' damage' in 'class/living/modules/body.c' ('class/interactive/interactive#190') line 2242
' inform' in 'kernel/simul_efuns/lpc.c' (' kernel/simul_efun') line 918
' mkset' in 'kernel/simul_efuns/lpc.c' (' kernel/simul_efun') line 1527
2009.10.05 18:54:56 LDMud aborting on fatal error.

Program received signal SIGSEGV, Segmentation fault.
fatal (fmt=0x81131fc "Mapping entry didn't hash to the same spot.\n") at simulate.c:587
587 *((char*)0) = 0/a;

I tracked down the array that has been send to this method, that makes the game crash. However, if one recreates an array like this, the game works as expected:

({ /* 0000001, size: 12 */
  /class/interactive/interactive#105,
  0,
  /domains/skeleton/npc/hobgoblin#295,
  /class/container/base/bag#114,
  /class/item/base/flintstones#113,
  /class/item/base/money#112,
  /class/item/base/torch#111,
  /domains/adventurers/obj/amulet#110,
  /domains/human/town/obj/sells/ferry_ticket_time#108,
  /domains/human/town/obj/sells/ferry_ticket_time#109,
  /domains/system/startup_item/cleric_robe#107,
  /domains/system/startup_item/staff#106
})

As soon as possible I will add a smaller example that reproduces the problem. For now, maybe someone has an idea. The bug does not occur in the 3.3.x driver.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: bug689.diff (1,581 bytes) 2009-10-07 03:20
http://ldmud.eu/file_download.php?file_id=254&type=bug
Notes
(0001468)
Bardioc   
2009-10-05 16:12   
Testcase that reproduces the problem (maybe not at first try, but at second or third)

public mixed * _mkset(mixed * arr)
{
    if (sizeof(arr) < 2)
    {
        return arr;
    }

    mapping set = mkmapping(arr);

    // walk through all entries in the array and if found in the mapping, remove it from there, if
    // not found in the mapping, remove it from the array
    for (int i = 0; i < sizeof(arr); i++)
    {
        if (member(set, arr[i]))
        {
            m_delete(set, arr[i]);
        }
        else
        {
            arr[i..i] = ({});

            --i;
        }
    }

    return arr;
}

public void test()
{
    object * x = ({});

    for (int i = 0; i < 50; i++)
    {
        for (int j = 0; j < 25; j++)
        {
            x += ({ clone_object("/class/item/base/torch") });
        }

        destruct(x[random(25)]);

        _mkset(x);
    }
}

simply call test() multiple times, it crashes at the m_delete() in _mkset()
(0001508)
Gnomi   
2009-10-07 03:37   
I attached a patch that fixes this (the patch is already committed for 3.5 as r2765 and will be committed for 3.3 after review).

The problem was that the destructed object was replaced by zero after its hash was calculated and thus the hash wouldn't fit anymore.
(0001616)
Gnomi   
2009-11-10 15:19   
Committed as r2804.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
685 [LDMud 3.3] Documentation text always 2009-10-03 09:40 2011-02-23 23:22
Reporter: Coogan Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: manpage of get_dir() lacks hint for differences in compat mode
Description: Unlike other manpages like object_name() or program_name(), the manpage of get_dir() does NOT contain a hint that the returned directory paths have the leading slash stripped in compat mode.

Please add a hint according to the other manpages, that one can easily grep through /doc/efun for "COMPAT" to see which efuns have a different behaviour.

This issue affects all current versions of LDMUD.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001474)
zesstra   
2009-10-05 18:07   
I added a note in r2759 and r2760 for 3.3. and 3.5.

Concerning other manpages: the best would be to create a bug with a list of manpages which miss that information (or even better would be a patch *g*).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
670 [LDMud 3.3] Networking minor always 2009-08-21 09:26 2011-02-23 23:22
Reporter: _xtian_ Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: [patch] new telopts for inofficial mud protocols
Description: This patch passes the telnet options negotiating through to the mudlib for the following protocols:

ATCP
102: unnamed MUSHclient/Aardwolf protocol
ZMP
MSSP (mud server status protocol)

References:
-----------

ATCP:
Achaea Telnet Client Protocol: From the iron realms, rather popular, for passing messages between client and server. There exist a lot of plugins for this. zMUD/CMUD support.
http://www.ironrealms.com/rapture/manual/files/FeatATCP-txt.html

ZMP:
Zenith Mud Protocol: Not widely used, but well designed. Possible to extend the protocol in your own namespace/package.
http://zmp.sourcemud.org/spec.shtml

102/MUSHclient protocol:
As yet unnamed, conceived by Mushclient maker and Aardwolf administrator. Approximately same as the above, built-in into MUSHclient.
http://www.gammon.com.au/scripts/showrelnote.php?version=4.31&productid=0

MSSP:
Mud Server Status Protocol:
Very young, for a bot that will collect data (number of users, uptime, etc) on your MUD.
http://tintin.sourceforge.net/mssp/
Tags:
Steps To Reproduce:
Additional Information: Since it seems as yet to be unnamed, I gave the 102 protocol the name TELOPT_MUSHCLIENT.
Attached Files: new_telopts.patch (2,358 bytes) 2009-08-21 09:26
http://ldmud.eu/file_download.php?file_id=248&type=bug
bug670.diff (9,529 bytes) 2009-10-12 06:03
http://ldmud.eu/file_download.php?file_id=255&type=bug
Notes
(0001249)
zesstra   
2009-09-04 11:15   
While I don't really like the MSSP-telnet variant (because I think many muds don't want to deal with the PITA of telnet negotiations), I think it is a good idea to pass the stuff to the mudlib.
Gnomi commented something about passing all unknown (to the driver) telnet options to the mudlib, which is probably the way to go...
(0001274)
_xtian_   
2009-09-17 17:49   
agreed. But in the meantime ... could you please apply this? ;) Thanks.
(0001276)
zesstra   
2009-09-18 04:30   
I have no knowledge/experiences with the details of telnet negotiations and I am currently in no mood to change this. So I am not fit to take care of this issue and somebody else has to take over.
(0001277)
Gnomi   
2009-09-18 04:53   
It shouldn't be too hard to pass all unknown telnet options to the mudlib. So I won't apply the patch but implement that instead.
(0001517)
Gnomi   
2009-10-12 06:07   
I attached a patch for 3.3 and committed it as r2767 for 3.5.

The patch adds defines in telnet.h for telnet options that were mentioned in this bug report, and passes to the mudlib all telnet negotations that are not handled by the driver.
(0001617)
Gnomi   
2009-11-10 15:26   
Committed as r2805.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
607 [LDMud 3.3] Runtime minor N/A 2009-02-12 17:33 2011-02-23 23:22
Reporter: peng Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: check_alarm triggers because alarm is off
Description: In FinalFrontier the driver has ramdomly problems with the alarm call. approx. 3-5 times a day the alarm is off and the check_alarm-fun in backend.c has to restart it. This causes 16 sec. without HB in the mud, which disturbes the players while fighting and such.
Tags:
Steps To Reproduce:
Additional Information: In a driver-version which replaced the alarm()-calls with setitimer(), the prob doesn't occurred any longer.
Additional debug in check_alarm() shows, that the alarm is of and not just delayed.
Attached Files: setitimer-backend.c.patch (2,602 bytes) 2009-02-13 11:08
http://ldmud.eu/file_download.php?file_id=197&type=bug
Notes
(0000950)
peng   
2009-02-13 11:11   
This is the before mentioned patch for setitimer. It just replaces the alarm-call in the startup with setitimer with auto-restart, so this is basically the same as restarting the alarm in catch_alarm instead of the way down in the backend cycle. The changes in check_alarm are straight forward, but check_alarm never triggered with this version.
(0000952)
zesstra   
2009-02-13 17:17   
Exchanging alarm() by setitimer() seems to me a reasonable idea, because it is simpler (at least in theory). But we should nevertheless find out, whats going wrong there.
So far nobody else reported such problems, but you can reproduce it on two different machines (as far as I understood). So we may try to find similarities between them which are otherwise rare. If you can think of anything which is common for your 2 systems or sets them apart from other systems, that would be great of course... ;-)
Could you give us information about hard- and software of the 2 machines? e.g. platform, versions of kernel, glibc, other libaries the driver uses, maybe 'uname -a', driver settings (config.h, machine.h). Is there a (basic) public variant of the mudlib you use which we may use? Or if not, can you test a different mudlib? ;-)

Other than that it seems we would have to scatter a bunch of debug messages with the current status of alarm() all over the code in comm.c/backend.c or does anyone think of a simpler approach?
(0001160)
zesstra   
2009-05-26 05:48   
Gnomi and me just discussed, that we both don't like to change code in response to a problem if we don't know the root cause of the problem. And because we have no information which might help us to reproduce the issue and we did not experience anything like this, I am inclined to close this as 'unable to reproduce'. If you have any further information which might help, please provide them.
(0001743)
zesstra   
2010-02-19 16:45   
I reworked the signal handling between r2872 - r2882 (3.5) and among other things I switched the alarm timer to ITIMER_REAL.
However, this series of changes is in 3.5. for the time being, because it is in sum a larger change and I would not apply it to 3.3.x without a longer test phase.
(0001802)
zesstra   
2010-03-14 18:25   
Just taking this for the time being - until I am confident enough for porting this to 3.3.x
(0001876)
zesstra   
2010-07-13 18:04   
I backported my patches for migration to sigaction() + setitimer() and the better sychronization between host and mud-internal time from 3.5 in r2923-r2926.
It is a pity that we could not reproduce the issue here, but I hope that will solve it then and sigaction() and setitimer() are anyway more convenient. Please report back if not.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
501 [LDMud 3.3] Efuns minor always 2007-02-21 12:44 2011-02-23 23:22
Reporter: szalicil Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: get_dir("/",GETDIR_PATH)
Description: get_dir("/",GETDIR_PATH) returns filenames without the leading slash
[returns ({"tmp"})]
(get_dir("/anyfolder/",GETDIR_PATH) correctly returns paths starting with /
[returns ({"/tmp/somefile"})]
)
Tags:
Steps To Reproduce: #include <sys/files.h>
get_dir("/",GETDIR_PATH)
Additional Information:
Attached Files:
Notes
(0000527)
peng   
2007-02-22 13:12   
Please don't change this without option for enabling the original behaviour. Most muds take care of this and a change will break existing code.
(0001396)
Gnomi   
2009-10-01 17:30   
I don't understand this. Why would you expect GETDIR_PATH to return the names without "/"? Isn't that what GETDIR_NAMES is for?
(0001436)
Coogan   
2009-10-03 09:43   
In compat mode, get_dir(path, GETDIR_PATH) returns the path names without the leading slash. The behaviour that get_dir("/", GETDIR_PATH) works in native mode similar to compat mode, is a bug in my opinion. I personally expect get_dir() to return always paths with a leading slash.
(0001437)
Coogan   
2009-10-03 09:59   
... when compiled in native mode! (forgot that part in my last note)
(0001442)
zesstra   
2009-10-03 18:39   
I committed a fix for this in r2751 on trunk. "/" is prepended in plain mode also for the listing of the mudlib root directory, if paths are requested by GETDIR_PATH.
Now the interesting question: should I apply this for trunk-3.3 as well?
(0001443)
Coogan   
2009-10-03 18:47   
I'd say, yes. When I see issue 0000684, it could happen that the mudlib itself will strip that fixed slash again.

Also apply a patch for 3.2, please!
(0001473)
zesstra   
2009-10-05 17:58   
It is IMHO obvious, that this is a bug. And I think, it should be fixed. So I made a note in HISTORY and applied it in 3.3 as well in r2758.
I think, fixing it in 3.2 it currently not really necessary. 3.2 is anyway obsolete and I know only Coogan/Tubmus who still use the branch. And they use compat mode and will there be not affected by any patch.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
224 [LDMud 3.3] Efuns feature N/A 2004-11-26 23:28 2011-02-23 23:22
Reporter: lars Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.8 and before  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: sort() should be able to sort in-place
Description: Short: sort_array(&arr) sorts in-place
From: Freaky
Date: 000405
Type: Feature
State: New

While sort_array(arr) sorts a copy of the array, sort_array(&arr)
might sort the arr in place. This would allow the wizard to chose
whatever is best.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001383)
zesstra   
2009-09-30 18:21   
I don't know the details the implemenation of sort(). But if that implicitly has to create a copy of the array (new array, which it populates instead of exchaning entries), then there is no sorting in place. Does anybody know without reading the code? ;-)
(0001385)
Gnomi   
2009-10-01 02:22   
Internally our sort algorithm sorts in-place, but it creates a copy of the array first, so that the original array is not modified. So this feature request is not a big deal.
(0001498)
zesstra   
2009-10-06 13:45   
Mhmm. v_sort_array() makes only a copy of arrays which have more than one reference.
But these arrays with more than one ref are the interesting case. If we change them, that might produce very interesting and by no means obvious bugs. I am not sure we can assume that every caller knows, with whom he may share an array.
(0001507)
Gnomi   
2009-10-07 02:29   
I don't think, that is a problem. When doing a[1]=10 you either know who you are sharing the array with or you don't care. Nevertheless you change the array a for everybody who has a reference to it. A sort_array(&a) would only do the same.
(0001547)
zesstra   
2009-10-22 16:36   
I committed a patch for the reference support in r2776 and r2777.
Does anybody think it necessary to support protected ranges? E.g. sort_array(&(arr[3..5]),...)?
(0001549)
Gnomi   
2009-10-24 06:18   
Yes, I think that protected ranges should be supported. &(arr[3..5]) should behave similar to &arr in LPC. But I don't know whether this should be done in 3.3 or 3.5 (I can do that in the lvalue branch in 3.5).
(0001550)
zesstra   
2009-10-24 06:30   
Ok, then I would suggest to do it there. After your rework of the lvalues the code will have to be changed anyway and actually, I don't think it is the most important thing to support it now, although it is more consistent.
The details about the protected lvalues are still a bit fuzzy to me, but I think, we would have to move the definition of struct protected_range_lvalue from interpret.c to interpret.h, because we have to get index1,index2 from the protector struct. Anyway, you have more knowledge about the details there.
(0001551)
zesstra   
2009-10-25 10:17   
With the protected ranges separated into 0000694, which is dependent of Gnomis lvalue work, I will close this one, makes a better changelog for 3.3.720. ;-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
645 [LDMud 3.3] LPC Language minor always 2009-06-01 06:15 2011-02-23 23:02
Reporter: _xtian_ Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.3.717  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version: 3.3.721  
Summary: casting structs (to 'inherited struct') does nothing
Description: LPC and the mysteries of casting ...

struct a {};
struct b (a) {
  int test;
};

printf("%O", (struct a) () );

... shows that the cast "(struct a)" on the struct "()" does nothing: It keeps the struct type, even preserving the additional element test.

to_struct() is also useless for this and I will make another entry for that.

So there is no way to cast one struct to another struct of different type, even if these are related.
Tags:
Steps To Reproduce:
Additional Information: Note that:

to_struct( mkmapping( () ), (<a>) );

does work as expected. (But it would work on every two struct definitions that have common element names and thus has not a bit of typesafety, which is one of the good reasons to use structs in the first place)
Attached Files:
Notes
(0001175)
zesstra   
2009-06-01 07:34   
Well...
(type) often does nothing. ;-)
e.g.
closure cl=function void (int i) {int b=(int)i; printf("%O\n",b);};
funcall(cl, 4.5);
prints 4.5 instead of 4.
A similar issue is described in 0000072.
Casting in LPC mostly assures the compiler "I know, that the value coming now is of type x" and is mostly useless, if you actually want to convert something.
(0001180)
Gnomi   
2009-06-01 08:57   
Declarative castings are done with ({int}). (int)x should cast x into an integer unless the compiler knows that x already is an integer. In xtian's example the compiler knows that the value is of struct b and therefore should insert something like to_struct. But currently ignores any typecasts to struct, even (<struct a>)10 is legal.
(0001183)
_xtian_   
2009-06-02 10:01   
This should probably also work (think typedef):

struct d {
  // ... any elements ...
};
struct e (d) {
 // empty!
};

... = (struct d) (<e>);

As above this does nothing. But since e doesnt add new elements to d, it is clear what the cast should do: It only needs to change the struct type.
(0001184)
zesstra   
2009-06-02 10:33   
Structs may be a special case, that they are never converted, while other types are converted if the compiler already knows their value. But it does not change much in respect to the usability of casts.

Actually, I would even like to either fix the casts to insert to_*() in all cases or remove them altogether, because the inconsistency is really bad for most wizards. We usually give the recommendation to never use (type) but always to_type().
(0001185)
_xtian_   
2009-06-02 11:19   
Then there could still be a declarative cast for the last example. Atm ({ }) casts only work for a very selected few types. It could work for this last case, since it is trivial.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
588 [LDMud 3.3] LPC Compiler/Preprocessor minor always 2008-12-18 10:12 2011-02-23 23:02
Reporter: _xtian_ Platform: x64  
Assigned To: OS: linux  
Priority: normal OS Version: debian/lenny  
Status: confirmed Product Version: 3.3  
Product Build: 3.3.717 Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version: 3.3.721  
Summary: function declaration after definition
Description: The following code doesnt compile with the error:
"Redeclaration of function bla."

---
void bla()
{

}

void bla();
---

LPC does not like declarations after the definition.
It seems to me that the redeclaration should be valid if it is identical to the definition.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000977)
zesstra   
2009-03-04 17:14   
On the other hand, I don't think it is a problem, if the declaration after the definition is an error.

Gnomi, Fuchur, does anyone of you want to 'discuss' with the compiler? ;-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
545 [LDMud 3.3] Implementation major N/A 2008-07-02 05:48 2011-02-23 23:02
Reporter: zesstra Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.3  
Product Build: Resolution: open  
Projection: none      
ETA: > 1 month Fixed in Version:  
    Target Version: 3.3.721  
Summary: Usages of alloca() have to be checked for possible stack overflow
Description: The driver contains some 69 calls to alloca(). They actually check if a NULL pointer is returned. Unfortunately, usual alloca() implementations don't return a NULL pointer upon stack overflow, they just move the stack pointer by the desired size and return it, no matter if the new pointer points to some area outside the stack.
If alloca() is used for allocating memory for user supplied data, this can enable users to cause a crash or worse.
We have to change such usages of alloca() and should not use it for anything else than to allocate small chunks of memory (e.g. <200 bytes).
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000750)
zesstra   
2008-07-18 16:08   
BTW: All alloca() seem to have a check like if (!buf) errorf("out of stack memory"); following, as these will never be executed we should just remove them (or does anybody know a system where alloca() actually checks something as does not just increase the stack pointer?).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
320 [LDMud 3.3] LPC Language feature N/A 2004-12-06 10:05 2011-02-23 23:02
Reporter: _xtian_ Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: 3.3 Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version: 3.3.721  
Summary: efun to remove double elements in array
Description: An Efun to remove double (triple, ...) elements in an array, without the need to go throug m_indices(mkmapping( my_array ));

example (let's call it "mkset"):

mkset( ({1,2,3,1}) ) == ({1,2,3})
Tags: ldmud-extensions
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000967)
zesstra   
2009-03-03 16:06   
Mhmmm. The questions is: how would we implement it internally? If it boils down to do m_indices(mkmapping( my_array )), is then an efun needed or may be just an sefun?
(0001006)
_xtian_   
2009-03-26 06:04   
First it would be nice to have this in the LPC language since this is a common operation - just, so that everybody (in different MUDs) uses the same vocabulary.

Second, and Im not familiar with the ldmud internal implementational details, what I thought of was the overhead in the LPC implementation - especially for very large Arrays.

But the stronger argument is the first one.
(0001022)
zesstra   
2009-04-13 14:49   
I did some preliminary tests in my homemud concerning the costs of m_indices(mkmapping)).
Starting point was an array with x elements which are initialised to random(y), so that after unification the array (and the intermediate mapping) size should be y.

Array size (x) | Unique elements (y) | Ticks | Evaltime
   10000 | 10 | 7 | <1 ms
   100000 | 10 | 7 | 0000005:0000010 ms
   1000000 | 10 | 7 | 0000068:0000070 ms

Same procedure with random(ARRAY_SIZE/10):
Array size (x) | Unique elements (y) | Ticks | Evaltime
   10000 | 1000 | 7 | 0000001:0000001 ms
   100000 | 10000 | 7 | 0000007:0000015 ms
   1000000 | 100000 | 7 | 0000364:0000340 ms

I would say, if your arrays are not bigger than 100k elements and if you don't unify one very often, the current approach is reasonably fast.

Possibilities:
a) create a default sefun using mkmapping() and m_indices() and recommending
   to use it.
b) make an efun mkset() to be a plain alias for m_indices(mkmapping(a)).
c) create mkset() and optimize a little bit for the use case (mkmapping()
   can deal with structs and create mappings with values, which is not needed
   here. But I guess, we won't save much.
d) don't use an intermediate mapping but something else (e.g. a plain hash
   table), which saves some overhead.

Of course, the amount of work increases from a to d. ;-) Any comments/preferences?
(0001023)
zesstra   
2009-04-13 14:51   
Gna. Sometimes I hate auto-magic-replace-stuff. Ok, the table again without any ~ characters:
Array size (x) | Unique elements (y) | Ticks | Evaltime
   10000 | 10 | 7 | <1 ms
   100000 | 10 | 7 | 10 ms
   1000000 | 10 | 7 | 70 ms

Same procedure with random(ARRAY_SIZE/10):
Array size (x) | Unique elements (y) | Ticks | Evaltime
   10000 | 1000 | 7 | 1 ms
   100000 | 10000 | 7 | 15 ms
   1000000 | 100000 | 7 | 340 ms
(0001024)
bubbs   
2009-04-13 16:51   
I don't think m_indices(mkmapping(arr)) give a satisfactory answer, since it does not maintain the order of the original array.
(0001049)
zesstra   
2009-04-16 16:11   
Ok, until now there wasn't a requirement to maintain the order of the array by Xtian. (Which is strictly speaking not even possible, if we remove elements from the array.)
Spontaneous thought: as long as you (can) sort the array, maintaining the order is not really important. But if that is impossible and you need the elements in the order you added them to the array, then probably you prevent the addition of double elements in the first place.
(0001589)
Coogan   
2009-11-02 19:10   
This requirement sounds like a kind of unique_array() in its simplest form without any arguments:
unique_array(({1,2,3,2,1}) --> ({1,2,3})

unique_array() could be extended as described here and accept arrays of some kinds (int*, object*, string*) to strip away multiple elements, returning a simple array.
(0001590)
zesstra   
2009-11-03 05:51   
Just to be clear: despite what the name suggests: this efun does not remove multiple elements from the result array, it just groups them together according to the value of the evaluated function/closure.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
632 [LDMud 3.3] Implementation minor always 2009-04-29 05:49 2011-02-23 00:00
Reporter: Gnomi Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: won't fix  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Initializers shouldn't reference the initialized variable
Description: From 0000631:

Sorcerer wrote:

  funcall(function int () {
            return funcall(function int () : int i=i {
              return i;
            });
          });

throws an error

Gnomi wrote:
The last one is a different problem, similar to the following:

  int x = 1; // global variable

  int fun()
  {
    int x = x;

    return x;
  }

fun() will return 0, because the initializer (= x) references the local variable not the global one. The same happens when initializing the context variable int i = i, the parser initializes the context variable i with itself but at that time the context doesn't exist yet, so an error is thrown.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: bug632.diff (2,276 bytes) 2009-04-29 07:52
http://ldmud.eu/file_download.php?file_id=227&type=bug
Notes
(0001068)
Gnomi   
2009-04-29 07:58   
I attached a patch that postpones the declaration of a variable until the initializer was parsed. But the following situation needs special treatment:

  int a = 2;

  return funcall(
    function int() : int b = a; int c = b
    {
      return c;
    });
(0001069)
Gnomi   
2009-04-30 04:07   
(Last edited: 2009-04-30 04:09)
In C and Java 'int x = x;' references the local variable. So in C you get an undefined result, Java shows a warning "The assignment to variable x has no effect" and an error "The local variable x may not have been initialized".

Do we want to keep that behavior? (The posted patch implements another behavior.)

(0001072)
Sorcerer   
2009-05-04 06:12   
I strongly support keeping the C/Java-style behavior. In my above example, if you want to use i in the inline closure, you should simply use it from the implicit context.
Declaring somthing like 'int x = x;' can easily lead to confusions which variable is accessed at which point in the code.
Especially for unexperienced programmers (which is the main-clientele of LPC) this will make things more difficult than they have to be.
So I opt for at least issuing a warning if someone uses these constructs (an error with pragma pedantic) or even an error in either case.
(0001081)
Gnomi   
2009-05-05 15:56   
Okay, I changed my mind and agree with Sorcerer.
So I'll close this bug.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
695 [LDMud 3.3] LPC Compiler/Preprocessor minor always 2009-10-27 11:13 2011-02-23 00:00
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: Missing base struct if base struct is empty.
Description: In case of an empty base struct:
struct a_s {
};

struct b_s (a_s) {
    int m;
};

the compiler fails to set the .base pointer in the struct type of b_s. While that does not have any immediate consequences, I think, even empty base structs should be recorded as base structs.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001563)
zesstra   
2009-10-27 11:40   
add_struct_member() sets pdef->type->base, when called with from_struct!=NULL. And that is (of course) only be done when there are members from the base struct from_struct to add...

Is there a reason not to set ->base in current_struct within opt_base_struct: (near line 6422 in prolang.y) instead of add_struct_member()?
(0001580)
zesstra   
2009-11-01 18:29   
I applied a patch doing this in r2788 for trunk. If that works, 3.3 should IMHO receive it as well.
(0001697)
zesstra   
2010-01-24 13:20   
Fixed in r2828 for 3.3.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
288 [LDMud 3.5] Efuns feature N/A 2004-11-27 00:53 2011-02-20 02:01
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: New efun this_function()
Description: Short: Efun this_function()
From: "Wolf Dieter Dallinger" <wolf.dieter@dallinger.de>
Date: Sun, 31 Mar 2002 13:57:53 +0200
Type: Feature
State: New

This is a multi-part message in MIME format.

------=_NextPart_000_0005_01C1D8BC.0D668B80
Content-Type: text/plain;
    charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Hi, Lars!

Ich will einen Call-Out starten, der etwas macht und dann erneut =
gestartet wird. Das geht mit einer Lfun problemlos:

    void fun()
    {
        add_count(-1);
        call_out("fun", 3600);
    }

    call_out("fun", 3600);

Schoen waere es, wenn man das auch mit einer Inline-Closure machen =
koennte. Dazu braeuchte man aber wohl eine Funktion this_function(), die =
eine Closure auf die entsprechende Lfun liefert:

    call_out((:
        add_count(-1);
        call_out(this_function(), 3600);
        :), 3600);

Allgemein:

-------------------------------------------------------------------------=
------
SYNOPSIS
        closure this_function()

BESCHREIBUNG
        Liefert einen Funktionszeiger (Closure) auf die Lfun oder die
        Lambda-Funktion, die gerade abgearbeitet wird.

BEISPIELE
        Call-Outs, die sich selber neu starten:

            call_out((:
                tue_irgendwas();
                call_out(this_function(), 60);
                :), 60);

            call_out(lambda(0, ({
                #',,
                ({ #'tue_irgendwas }),
                ({ #'call_out, ({ #'this_function }), 60 }),
                })));

        Einen Funktionszeiger irgendwo eintragen, der sich automatisch =
nach
        einmaligem Aufruf wieder austraegt:

            add_closure((:
                tue_irgendwas();
                delete_closure(this_function());
                :));

SIEHE AUCH
        closures(LPC)
-------------------------------------------------------------------------=
------

Ich wuerde mich ueber ein this_function() freuen.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
507 [LDMud 3.5] LPC Language minor N/A 2007-08-06 07:56 2011-02-20 02:00
Reporter: sinnvoll Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: An efun " this_closure() ", that returns in a closure a pointer to the closure.
Description: It would be nice to have an efun this_closure(), that returns in a closure a pointer to the closure.

add_controller("notify_move",
               function void ()
               {
                  write("Write this only for exact one move.");
                  delete_controller("notify_move",this_closure());
               }
);

You could code something like this:

closure cl;

add_controller("notify_move",
               cl=function void ()
                  {
                     write("Write this only for exact one move.");
                     delete_controller("notify_move",cl);
                  }
);

But that has the disadvantage of a recursive data structure.
The memory might not be freed, if the closure is no longer used,
because the reference count can't be nulled because of the self reference.
   
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
289 [LDMud 3.5] Runtime feature N/A 2004-11-27 00:54 2011-02-20 02:00
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Input hook
Description: Short: Hook for input_to()
Date: Sun, 31 Mar 2002 15:40:53 +0200 (CEST)
From: Markus Peter <warp@spin.de>
Type: Feature
State: New

Hallo

Ich haette mal wieder eine Idee fuer ein Feature was mit input_to
zusammenhaengt (naja - vielleicht waers langsam besser ich override
input_to in der simulefun statt den Driver immer weiter zu belasten...)

Ich hab in mein MUD support fuer MCP eingebaut. MCP sieht vor, dass alle
Zeilen die mit $#" und $#$ gestartet werden besonders behandelt werden.
Das funktioniert soweit auch so gut, falls der MCP client nicht gerade auf
die Idee kommt, Zeilen dieser Art zu senden, waehrend gerade ein input_to
laeuft. Es gibt jetzt prinzipiell 2 Moeglichkeiten, wie ich das Problem
reparieren kann: Entweder ich bau in der Lib mein komplett eigenes input
System oder man baut evtl. einen Hook, der es mir erlaubt, an jeden Input
ranzukommen, bevor er in das "normale" Input System kommt. Der Hook waer
dem H_MODIFY_COMMAND hook recht aehnlich (string => kommando wird ersetzt,
0 use unchanged, andere zahl - ignorieren) aber eben mit dem unterschied,
dass auch input_to Eingaben darueber laufen.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
290 [LDMud 3.5] Runtime feature N/A 2004-11-27 00:54 2011-02-20 01:20
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Better isolate error calls
Description: Short: Better isolate the error routine calls
From: Lars
Date: 2002-04-20
Type: Feature
State: New

In the calls to the error routines, give the interpreter its own resource environment (at least for the first-level call) to avoid dominoe too-long-evals.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
626 [LDMud 3.3] Portability minor N/A 2009-04-16 04:59 2011-02-19 18:26
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: assigned Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Remove special code for obsolete systems/platforms
Description: The driver contains some special code for systems like OS2, EMX, AMIGA, Ultrix, SunOS4 and some others.
As these system are long dead and we anyway don't know if the driver would still run on them, I suggest to remove the code.
I prepared patches for the removal of:
- OS2
- EMX
- AMIGA
- BEOS
- SunOS4
- Ultrix
- MSDOS-leftovers

I will add a series of patches this evening to do this, please comment on the plan and/or patches.

Additionally we might discuss to remove:
- MSDOS filesystems semantics (MSDOS_FS)
- 'mips' which works around an (very) old Irix kernel bug in comm.h
- 'sgi' and '_MODERN_C' which add a prototype for crypt() in port.h which should be not needed for POSIX compliant systems nowadays.
- The semantics of 'sun' is not clear to me. I am tempted to assume 'sun' will be defined on older versions of SunOS while newer ones use 'solaris'. In that case, we could remove it.
- Does anybody know if current Solaris has still a getrusage with t.tv_nsec in microseconds rather than nanoseconds?
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: 0003-Removed-checks-for-OS2-__EMX_.patch (5,093 bytes) 2009-04-16 14:21
http://ldmud.eu/file_download.php?file_id=211&type=bug
0004-Removed-check-for-define-MSDOS.patch (593 bytes) 2009-04-16 14:22
http://ldmud.eu/file_download.php?file_id=212&type=bug
0005-Removed-checks-for-__BEOS__.patch (7,610 bytes) 2009-04-16 14:22
http://ldmud.eu/file_download.php?file_id=213&type=bug
0006-Removed-checks-for-AMIGA.patch (6,827 bytes) 2009-04-16 14:23
http://ldmud.eu/file_download.php?file_id=214&type=bug
0010-Removed-MSDOS-filesystem-semantics.patch (8,734 bytes) 2009-04-16 14:24
http://ldmud.eu/file_download.php?file_id=215&type=bug
0011-Removed-checks-for-SunOS4.patch (2,772 bytes) 2009-04-16 14:24
http://ldmud.eu/file_download.php?file_id=216&type=bug
0012-Removed-support-for-Ultrix.patch (1,260 bytes) 2009-04-16 14:24
http://ldmud.eu/file_download.php?file_id=217&type=bug
0007-Removed-work-around-for-a-compiler-bug-in-gcc-2.7.2.patch (2,800 bytes) 2009-04-16 14:29
http://ldmud.eu/file_download.php?file_id=218&type=bug
0008-Removed-a-check-for-gcc-2.7.patch (730 bytes) 2009-04-16 14:29
http://ldmud.eu/file_download.php?file_id=219&type=bug
0009-Removed-work-around-for-compiler-bug-with-gcc-3.2.patch (1,706 bytes) 2009-04-16 14:29
http://ldmud.eu/file_download.php?file_id=220&type=bug
Notes
(0001047)
zesstra   
2009-04-16 14:29   
I attached a first series of patches removing special code for obsolete systems.
Patch 10 is one that removes the MSDOS filesystem sematics. I included it, but that is highly preliminary as we have to decide first, if we want this.

Patches 7, 8 and 9 are a little bit different, because they remove work-arounds for old compiler bugs. I included them here for simplicity, but if you like, we can transfer them to a new issue.
(0001085)
zesstra   
2009-05-06 16:28   
Ok, patches were applied in revisions 2566 - 2573.
The patches for the old compiler (work-arounds) were combined into r2570.
The MSDOS filesystem semantics were removed in r2573.
(0001086)
zesstra   
2009-05-06 16:48   
Some other things to check may be:
_MODERN_C
sgi
sun
sparc
CYGWIN
MSWIN
__CYGWIN32__
POSIX
_GNU_SOURCE
solaris
__hpux__

Not so much as in 'not supported' but as in 'check if (work-around) is still needed'... I will have a more detailed look, what these defines actually do.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
749 [LDMud 3.3] LPC Compiler/Preprocessor feature N/A 2005-01-11 10:59 2011-02-19 18:25
Reporter: _xtian_ Platform:  
Assigned To: zesstra OS:  
Priority: low OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: backport deprecated modifier to 3.3.x ("obsolete" modifier)
Description: An "obsolete" modifier for lfuns, sefuns which throws a compilation/runtime warning if the so marked function is called (compiled function call as well as as call_others at runtime).

This is another item, that would help handling big libs with a lot of historical accumulated nonesense.
Tags:
Steps To Reproduce:
Additional Information: note that this behaviour can be simulated by explicitely notifying wizards, writing into a bug-database, etc.
But I would favour an easy, fast, standarized way to handle this.
Attached Files:
Notes
(0001841)
_xtian_   
2005-01-11 11:16   
ah, and it could help MUDs prepare their switch to 3.3 by masking the efuns that are to vanish with an "obsolete" sefun
(0001842)
_xtian_   
2005-01-19 06:15   
come to think about it "deprecated" probably wouldn't sound that harsh.
(0001843)
zesstra   
2010-02-12 19:14   
Oh, BTW: I like that idea (Although it might be difficult to find a bit for that flag in the function header.) We have plenty of old nonsense floating around... I am surprised that I did not comment earlier.
(0001844)
Coogan   
2010-03-03 18:00   
Years ago, I wrapped each obsoleted efun by an sefun of the same name, giving a warning each time it was used. In the second stage, the sefun throws an error, pointing to the particular successor function.
This way it's quite comfortable to switch to a more recent driver version with "vanished" efuns.
(0001845)
zesstra   
2010-03-03 18:11   
Yes, that works good for efuns. But for them we have such a mechanism in the driver source which we also use (e.g. cat(), tail() in 3.3.x).

But in this case (lfuns, sefuns) it does not really work. You might define sefuns for obsolete lfuns, but you will have difficulties to defer from the sefun to private/protected lfuns. And if it triggers a warning on each call you might be flooded with scroll.
Additionally it does not catch call_others. You might define a call_other sefun and check on each call. But that introduces a signifcant slowdown for each call_other...
I think, the driver would be better suited, because it can do a lot things at compile-time and the remaining (call_other) much more efficient.
(0001846)
Bardioc   
2010-03-05 14:15   
I would love to have this modifier! Even though EverLIB is not old, parts of the domains are, and this would help alot!
(0001847)
zesstra   
2010-03-07 12:02   
I worked on this a bit. It is not committed to the driver sources yet, because I would like to have some comments first.
I added a modifier 'deprecated' for functions (in theory it could be extended to variables at some point), which will set TYPE_MOD_DEPRECATED in the function flags. Upon calling such a function (intra-object + sefuns) the compiler will issue a warning at compile-time. Callothers and lfun closure evaluations will cause a warning at runtime (this could trigger a huge number of warnings, be warned).

There are still two caveats to be solved:
1) the warning in case of lfun closures will not include the correct line number + defining program (the correct solution would be to check before pushing a new control stack frame, but therefore I need a possibility to get the function flags indepedent of setup_new_frame1()).
2) If you call a not-defined function and this will be defined later by inheritance/cross-definition the compiler will miss any deprecated modifier, because the call was generated when the flag was unknown.

You can find the changeset at: http://github.com/zesstra/ldmud-dev/compare/deprecated_mod and the deprecated_mod branch is at http://github.com/zesstra/ldmud-dev/tree/deprecated_mod. Comments welcome.
(0001848)
zesstra   
2010-03-10 16:29   
BTW: Should it be possible to 'loose' the deprecated flags by redefining the function in inheritees?
Pro: I deprecate a specific function (e.g core lib) and don't care about redefined function as long as they don't call me.
Contra: Maybe I want to deprecate an interface as a whole, not only the function I define myself...
(0001849)
_xtian_   
2010-03-10 17:22   
We would use "deprecated" if we want to change or eliminate parts of APIs. In that case we don't even want another user to keep on redefining that function - which he surely only did redefine in the first place to extend the inherited API.

In that case redefining the function will not work any more as expected and the user should be notified of this.

So: Pro: "deprecated" should not go away.
(0001850)
_xtian_   
2010-03-10 17:29   
Concerning 2) (external declarations of functions):
In uni-libs, at least if we haven't diverged that much, we use external declarations quite a bit for the core living and player objects (the code is deployed over several inherits), so this limitation might be a bit hindering.

Could a work-around be to issue a warning if the compiler encounters a redefinition where not all declarations are "deprecated"?
(0001851)
Gnomi   
2010-03-11 04:55   
I disagree. I might have a program with a function fun() that is perfectly valid and will stay. And just because some other program had a fun() that is now deprecated, this doesn't make my fun() invalid or deprecated as well, just because both programs were inherited together in another program. And I'd rather not differentiate between redefining a function and cross-defining it to another inherited program (because it's basically the same and moving a function to an inherited program should be a valid refactoring step, so it should behave similarly).

In other words, the deprecated flag should warn whenever the removal of that function declaration with this flag alters the behavior at the point of the warning (might not compile anymore or might call a function that was hidden until now). And when a deprecated function is redefined by a non-deprecated function the removal of the deprecated function changes nothing for the caller (which still calls the non-deprecated one), so no warning there.
(0001852)
zesstra   
2010-03-11 05:33   
Right, so to summarize the two different wishes:
a) Gnomi wishes to deprecate functions
b) Xtian wishes to deprecate interfaces

Unfortunately both are mutually exclusive. Gnomi offered the opinion, that we probably can't do b) consistently. One issue is, that we can't prevent somebody from implementing a deprecated interface himself and not inheriting the original program defining the interface at all. Although that is IMHO very rare (might in theory be excluded by code-style conventions).

Actually I could probably use both a) and b) independently in our lib... ;-) Usually I would deprecate functions. But there are some exceptions. e.g. we have an interface do_wear() which is obsolete and we do things differently now. If a wizard redefined do_wear() and did not call ::do_wear() there would be no warning, but his do_wear() will a) do the wrong things to wear a piece of clothing or b) his object will completely miss when a player wears the object (e.g fail to enforce restrictions).

So far, I guess you would have to use first deprecated, then a deprecated+nomask empty function to deprecate interfaces.
(0001853)
_xtian_   
2010-03-11 14:01   
Yes, my wish (point b) can actually be realized by using "deprecated" (as Gnomi argued) and "nomask", or even the "warn_nomask" (http://mantis.bearnip.com/view.php?id=734) idea.

Please note, that we once proposed a "required" modifier which guaranteed that a inherited function would call ::fun() (http://mantis.bearnip.com/view.php?id=352). All these suggestions come from the frustrating experiences of maintaining an API over decades and inexperienced programmers, btw so all have real used cases. (yes, I remember that "required" still had some difficulties)
(0001854)
zesstra   
2010-03-11 14:26   
Yes, I fully share that frustration, we also have our share of ancient APIs and wizards who just copy a function from the core lib and the copy is never maintained anymore, gets no updates or bugfixes, until some ugly enough bug happens. (BTW: that suggestion about 'required' is still here in Mantis. Although I guess, we can't make it happen until we have a compiler which can analyze the execution flow. :-()
(0001855)
zesstra   
2010-03-14 10:54   
Ah, concerning the issue with the cross-defined functions: IMHO it not so big as it seems.
If you have a (matching) prototype with deprecated, the driver will warn. If you don't have a prototype, AFAIK you can only call the function if the calling function is compiled without type testing (it has no function type, which is not allowed with anything other than weak_types.
If you don't call a function without prototype yourself, that leaves call_other and symbol_function at runtime. And at runtime, the flags from the cross-defined functions are available (and would contain the deprecated flag).
(0001856)
zesstra   
2010-03-14 11:40   
Updated my test branch for this: the flag is now checked upon creation of closures, not at evaluation time (symbol_function, compiler (#'fun, #'::fun)).
(0001857)
zesstra   
2010-03-21 12:25   
I added checks for usages of deprecated global variables and committed my patch series to the trunk of 3.5. for testing.
(0001858)
zesstra   
2010-04-29 14:10   
Cloned the issue to LDMud-3.3. I think, we might backport in due time (so, after some months of maturing in 3.5.x). What do you think?
(0001997)
zesstra   
2011-02-19 18:25   
I backported the deprecated into 3.3/trunk as of r3004.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
61 [LDMud 3.5] LPC Compiler/Preprocessor feature N/A 2004-05-18 21:31 2011-02-14 17:46
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: 'use' directive to replace most uses of prototypes.
Description: Sometimes it is desirable to let a module "/std/module/room" use functions from a different module "/std/module/props" with directly inheriting it. The traditional solution is to use prototypes, which can make debugging more difficult.

A directive

  use "/std/module/props";

could import all function declarations from "/std/module/props" as if defined by prototypes. Possible extended uses:

- The imported declarations would be flagged with their origination, so that any collision by another 'use' or explicite prototype could be detected.
- The name of "/std/module/props" could be stored in the program, so if at runtime an unresolved crossreference is detected, the compiler could give hints as to what could be missing. This can't be done at load time as in this case "/std/module/room" is necessarily incomplete, yet is loaded during the inheritance handling.

Other names for 'use' could be used, as long as they are different enough to 'inherit'. This excludes 'import', but 'require' could work (it has slightly different implied semantics, though).
Tags:
Steps To Reproduce:
Additional Information: Bardioc suggested a version of

extern <prototype> by "<module>";

which could be added for ad-hoc uses. The attached file implements the grammar for these.
Attached Files: bardioc.diff (1,466 bytes) 2004-05-18 21:31
http://ldmud.eu/file_download.php?file_id=4&type=bug
Notes
(0000865)
zesstra   
2009-01-08 07:25   
Ok, I can imagine quite a number of applications for this as well. The one drawback I see: using #include and prototypes you can select specific prototypes to be declared, which might be good idea, if you need only a few out of hundreds. But as you don't have to use this feature...
I guess we have anyway some stuff to do in the compiler, so moving to 3.5. We can decide then if we want to implement it.
(0000872)
Gnomi   
2009-01-08 08:30   
Doesn't this try to solve the same problem that virtual inherits were supposed to solve? Assuming that virtual inherits work why not virtual inherit "/std/module/props" instead of 'use' it?
(0000874)
zesstra   
2009-01-08 09:17   
Mhmm. Yes, you probably can solve these problems with virtual inherits.
With use or include you get a compilable, but mostly not executable object only for inheriting it (which is often completely fine).
With the virtual inherits it seems to be a much more complicated process for compiling and for resolving the functions and there are limitations like 'in case of replace_program() a program containing virtually inherited variables must be inherit first'.
And I might be wrong, but I have something in memory about merging or resolving the wrong variables and functions in complex trees. Some time ago we had 3-4 objects virtually inheriting and we had problems re-loading them and part of the ineritance tree without errors, so we fell back to the 'include the right prototypes' method (Im sorry, at that time I was not involved here, so I did not report that.) Or maybe it is a documentation issue which causes my disfavor.
I don't know if there is any difference in memory consumption or execution time between both methods.
(0000893)
Bardioc   
2009-01-15 15:04   
The memory problem (double variables) is exactly the problem that we wanted to address with this. If you mess up the virtual inheritance, you end up with an o-file that includes multiple values for the same variable.

Consider this example:

A <- B <- C
A <- D <- C

So both B and D inherit A.
If you do NOT virtually inherit A in B and D, you get twice the variables of A, thus a method call in B that modifies the variables of A will not be reflected by a query method in D that queries the variables of A.

Hope that I made my point clear here.

You are right, prototyps are completely fine, but if you change the fucntion definition you have to adapt all prototypes, thats why the extern definition came to my mind.
(0000905)
_xtian_   
2009-01-16 13:22   
I would support this.

Slightly offtopic: Is there a way to get "use" to include struct definitions into multiple files without directly inheriting the file defining the struct?
(as a sort of virtual inheritance for struct definitions).

Sharing struct definitions in a complex inheritance tree requires the definition to be inheritted multiple times.
(0000934)
Bardioc   
2009-01-19 12:12   
xtian as far as I know, and I talked about this with Lars structs are compile time structures that are program-based, thus if you define a structure foo in file a.c and in file b.c, they are NOT the same at run time, leading sometimes to weird errors like
   struct foo #33434 vs. struct foo #343434

To actually make "use" working for structures the need to be shared among programs, and the defining program would need to be reloaded in case it is gone. I'm not sure how much work this involves.
(0000935)
_xtian_   
2009-01-20 06:52   
Structs are shared by defining them in a common inherit in LPC. The same diagram as above applies, where A defines the struct:

A <- B <- C
A <- D <- C

B and D can exchange data typecast as their shared struct over function calls (type-safe btw).
But C needs to have the same inherit (A) twice.
(0000936)
Bardioc   
2009-01-21 13:25   
The problem is not the data typecast, but mainly the access to struct members ... the only thing a "use" for structs would be useful in your way is that a function prototyp will not lead to a compile error ... but in case a method uses the struct and accesses a member, the full definition is necessary to validate the member exists (and I would not want to pass on this).

I doubt that the only knowledge about the struct's name is useful, so I would vote for a maybe changed structure handling that introduces an own global namespace for structs rather than a program-based approach like it is now.
(0001399)
zesstra   
2009-10-02 05:02   
Gnomi suggest quite a time ago, that we should think of improving virtual inherits as an alternative. So I will relate some issues of virtual inherits with this issue to have an idea, what we should think of in this case.
(0001986)
zesstra   
2011-02-14 17:46   
As a comment: it still sounds easier to me to implement a 'use' which just imports all the public and protected/static functions as prototypes into the newly compiled program than 'fixing' the virtual inheritance. Not only in terms of code, but also conceptually.
That said, I would be happy to have both. One method results in a usable/cloneable object, the other just compiles, is smaller and can be used for inheritance...

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
754 [LDMud 3.5] Runtime major always 2010-07-20 15:28 2011-02-13 22:38
Reporter: Sorcerer Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: RTTC: error message during function argument checks does not handle lvalue correctly
Description: [Original title: RTTC does not recognize mixed when initialized with some specific type]

Once a mixed variable is initialized with a specific type, an RTTC-error is thrown if I try to pass it by reference as another type.

To reproduce:

mixed data;
data=1;
funcall(function int (string test) { test="a"; },&data);

This will yield:
Bad arg 1 to __inline_w_sorcerer_LPC_zst_c_17_#0000(): got 'lvalue', expected 'mapping'.

If I leave data uninitialized prior to the funcall or initialize it with a string (so the types match), no error will be thrown.

One might argue whether this is a bug (mixed not recognized as mixed) or a feature (initialized mixed treated like the type it was initialized with). I rather consider it a bug since if I really decide to make a variable mixed (which I do only rarely) I want it to be a true wildcard with respect to its type.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001881)
Gnomi   
2010-07-20 16:05   
The error message is somewhat misleading, it should be "got 'number', expected 'string'." and this is imho entirely correct.

The error message has nothing to do with the type the variable was declared with. The error message is about the call of a function that expects a string as its first parameter and gets a number (or a reference to a number, which is treated the same).
(0001882)
zesstra   
2010-07-20 16:20   
I agree with Gnomi and think this error is essentially correct besides the wrong error message.
The other way around would be an error of course (data being a string and test being mixed has to work).
If you leave data uninitialized, it has the value 0 which is an element of any type and can therefore be assigned to any type, including strings.
(0001883)
Sorcerer   
2010-07-20 17:08   
Ok, reading your views I agree, too. In the specific (historic) piece of code I came across this construct, the mixed was always only used to store an additional value set in the called function.
But, of course, the function might also read from the variable and in that case it does matter what the current type is.

So, please disregard my original request and only keep Gnomi's suggestion to replace lvalue by the actual type.
(0001884)
zesstra   
2010-07-21 17:03   
BTW: Are you sure you get 'mapping' as being expected? If I try this at home 'string' is expected - as it should be.
I know the cause for the 'lvalue' in the error message but I really don't know why it should expect a mapping.
(0001885)
zesstra   
2010-07-21 17:55   
I believe this is fixed by r2929 - if your driver does not expect a mapping.
(0001886)
Sorcerer   
2010-07-22 02:38   
'string' is correct - I copy&pasted the error message from another testcase by accident. So you can close this bug as fixed. Thanks!
(0001887)
Sorcerer   
2010-07-22 02:39   
'string' is correct - I copy&pasted the error message from another testcase by accident. So you can close this bug as fixed. Thanks!
(0001889)
zesstra   
2010-07-22 03:54   
Thank you :-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
680 [LDMud 3.5] Compilation, Installation minor always 2009-09-20 12:06 2011-02-13 22:38
Reporter: zesstra Platform: i686  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Defective determination of SBRK_OK
Description: sbrk/brk() are mostly deprecated in the newer POSIX standards and on MacOS, brk() ist not available and sbrk() only simulates a 4MB (AFAIR) large heap.
Unfortunately, our check for sbrk() succeeds (because it is possible to get some memory) and the resulting driver would be non-functional, because it can only allocate about 4MB of memory.
This does not show up, because on MacOS we are not able to replace the system malloc. In that case, SBRK_OK is automatically disabled again.
But there may be systems, where our SBRK_OK malfunctions and it is possible to replace the system malloc. Therefore we should repair our autoconf check somehow.

I can only think of allocating more memory during the test. But how much? For MacOS it would be > 4MB. But is that good enough? Can anyone think of a better check?

Note: On most systems, the fallback from SBRK_OK is to use mmap(). In that case, we can still replace malloc(). If mmap() is also not available, malloc ist used and can obviously not be replaced any longer.
Tags:
Steps To Reproduce:
Additional Information: An older mail, I write about this (sorry for the german):

ich habe gerade nochmal ueber meine Crashes und moegliche Fixes gegruebelt und
dabei ist mir folgendes aufgefallen:
Irgendwie laufen unsere Tests fuer SBRK_OK & Co nicht so richtig gut.
Erstmal Begriffsbestimmung:
SBRK_OK: (s)brk() nutzbar. Momentan wird SBRK_OK auch zusaetzlich im Sinne von
"malloc() ist durch Definition eines eigenen malloc() ersetzbar" benutzt.
HAVE_MMAP: mmap() verfuegbar
MALLOC_SBRK: sbrk oder mmap nutzen, falls verfuegbar, REPLACE_MALLOC
aktivieren und den Systemallokator ersetzen. Standardmaessig definiert.

Unser configure-Test testet nun in erster Linie die letztgenannte
Teilbedingung von SBRK_OK.
Auf MacOS ist der Allokator nicht so simpel zu ersetzen und der Test schaltet
SBRK_OK auf MacOS folglich auch aus. Der Test auf funktionsfaehiges sbrk ist
jedoch in diesem Falle Mist, weil MacOS ein Minimal-sbrk hat, mit welchem man
die Breakadresse um einige Kilobyte verschieben kann. Unser Testprogramm
braucht nicht viel und wuerde daher SBRK_OK setzen, wenn das Ersetzen
funktionieren wuerde. Wuerde jedoch in keinem lauffaehigen Driver enden.

HAVE_MMAP ist auf fast allen Systemen verfuegbar, MALLOC_SBRK ist
standardmaessig gesetzt, d.h. es wird bei !SBRK_OK fast immer versucht, den
System-Allokator zu ersetzen, auch wenn das eigentlich nicht mit unserer
Methode geht. Folge sind moegliche Crashes (strdup alloziert per
Systemallokator, Speicher wird ueber Aufruf unseres free() freigegeben).

Das ganze Problem resultiert eigentlich aus a) unzureichenden Tests und b) der
semantischen Vermischung von "brk ist verfuegbar" und "malloc ersetzbar" in
SBRK_OK.
Ich waer dafuer
1) SBRK_OK nur bei wirklich nutzbarem brk() zu setzen und dafuer nur noch
diese Bedeutung haben zu lassen und
2) MALLOC_SBRK nur dann zu aktivieren, wenn malloc ersetzbar ist.

D.h. fuer MALLOC_SBRK koennte man im wesentlichen den Test nehmen, den wir
gerade in configure fuer SBRK_OK haben. Fragt sich aber, wie man feststellt,
ob brk() wirklich funktionsfaehig ist. Einfach blind zu versuchen, mehr
Speicher als bisher via brk() zu allozieren scheint mir irgendwie so toll auch
nicht zu sein.
System Description Homemud / Entwicklungssystem (32 bit)
Darwin Kernel Version 10.6.0: Wed Nov 10 18:13:17 PST 2010; root:xnu-1504.9.26~3/RELEASE_I386 i386
Attached Files:
Notes
(0001287)
zesstra   
2009-09-20 17:14   
OK, I started work on cleaning this up a little bit (nothing is applied yet):

1) configure contains a (preliminary) check for a working sbrk/brk, which tries to allocate 50MB with sbrk/brk. If successful, SBRK_OK is defined.

2) configure contains a check for a replaceable malloc. This is very similar to the old check for SBRK_OK. If malloc seems to be replaceable, MALLOC_REPLACEABLE is defined.

So, now we have:
SBRK_OK: allocating with sbrk/brk() works (machine.h)
MALLOC_REPLACEABLE: malloc is replaceable (machine.h)
HAVE_MMAP: mmap() is available (machine.h)
These three are completely independent of each other.
MALLOC_SBRK: the user requested to use sbrk if available (default, config.h)
REPLACE_MALLOC: the system malloc is to be replaced by our own functions (slaballoc.c, smalloc.c)

I changed some precompiler logic in the allocators to make use of this. So the logic is now as follows:

1) the allocators checks first if MALLOC_SBRK is requested. If yes, SBRK_OK and MALLOC_REPLACEABLE must be defined as well. If yes, REPLACE_MALLOC is set. Otherwise, MALLOC_SBRK is undefined and sbrk ist not used.
2) If HAVE_MMAP and MALLOC_REPLACEABLE are defined, mmap() is used instead of sbrk() and REPLACE_MALLOC is defined.
3) If HAVE_MMAP is defined, but not MALLOC_REPLACEABLE, mmap() is used, but we don't attempt to replace malloc. With mmap(), this is possible, because we don't interfere with any system allocator using sbrk, brk or mmap.

4) the allocators then don't check only for SBRK_OK anymore, but for MALLOC_SBRK (which is only defined, if requested and the prerequisites are met).
(0001290)
zesstra   
2009-09-21 18:16   
I applied some experimental patches as r2748-2750, which implement the described behaviour in 0000680:0001287 (at least I hope so).
I will keep this issue open for a while, because this stuff should be tested on several platforms. And there are probably improvements possible.
(0001872)
zesstra   
2010-07-13 16:10   
Ok, I consider this resolved in 3.5.x for now.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
608 [LDMud 3.5] Implementation minor sometimes 2009-02-15 08:59 2011-02-13 22:38
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: low OS Version: 10.5.x  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Overflows in statistics / counters in swap.c
Description: The swapper seems to contain overflows as well:

  7411 prog blocks swapped, 45819336 bytes
  3766 prog blocks unswapped,19679133 bytes
 60528 var blocks swapped, 38290588 bytes
 29675 free blocks in swap, 84621272 bytes
Swapfile size: 188669244 bytes
Total reused space: -1064819224 bytes

Swap: searches: 14219180 average search length: 86.5
Free: searches: 14208976 average search length: -130.3
Overhead: 101380 blocks using 811040 bytes.
Mode: non-compact - Freespace recycling: on
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0001189)
zesstra   
2009-06-03 16:04   
Resolved in r2626.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
552 [LDMud 3.5] Implementation minor N/A 2008-07-09 18:27 2011-02-13 22:38
Reporter: zesstra Platform: i686  
Assigned To: zesstra OS: GNU/Linux  
Priority: low OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Name clash between our ptmalloc and glibc ptmalloc
Description: Gnomi investigated today a curious crash and found the root cause: the driver as well as the glibc implement ptmalloc (it is nowadays the default memory allocator of glibc). Unfortunately, the names of variables and functions are the same in both. This can be a problem, if it is not possible to replace the system malloc by our own (->SBRK_OK). See also 0000550.
We should discuss, how to clean up our ptmalloc stuff:
a) rename variables and functions of our built-in ptmalloc
b) update built-in ptmalloc and rename variables and functions
c) detect if the host's libc is an up-to-date glibc and fallback to use the ptmalloc of glibc, which is essentially a fallback to the sysmalloc allocator in the driver, I guess?
d) drop ptmalloc altogether?
e) leave it as it is
f) ?

With the patch from 0000550, the problem should have no immediate effect on users because driver.h enforces SBRK_OK if ptmalloc is used as allocator, because the driver won't work otherwise.
Tags:
Steps To Reproduce:
Additional Information:
System Description MorgenGrauen server
Debian Etch.
Attached Files:
Notes
(0000711)
zortek   
2008-07-10 00:42   
My choice of ptmalloc was based upon the premise that it is threadsafe (traditionally scaling well in performance) and supports garbage collection. Additionally, while it has not yet proven itself, I was also trying to consider heap usage to head off potential scaling issues (but to be honest, I'm not certain that the "anonymous page" strategy is a valid argument anymore).

With the assurance from our efforts re> 0000550 and Gnomi's investigation, I'd support deprecating ptmalloc and let it die on the vine.

However, my advocacy of dropping ptmalloc might myopically disregard a legacy community.

Is there some additional reasoning for either maintaining or rev'ing the built-in? Where is the greatest return for the investment of time required? Can action on this be deferred to 3.5?
(0000716)
fufu   
2008-07-10 08:50   
Ok, I had a chat with Gawain (the original contributor of the pthreads comm code and the ptmalloc code) about this.

To summarize:
- xptmalloc is a threadsafe allocator with (single threaded) GC support. The latter point is the main difference between ptmalloc and sysmalloc, if the system's malloc is threadsafe.
- currently, the driver only allocates and frees memory from a single thread, so thread safety of the allocator isn't much of a concern.
- in fact, the comm.c code uses the system's malloc for buffers nowadays.
- in the long run, we should detangle the GC code from the allocator code.

So I think we can safely deprecate the ptmalloc stuff, and probably drop it for 3.5.
(0000975)
zesstra   
2009-03-04 17:06   
I suggest to keep it 'as-is' for 3.3 and decide at the beginning of 3.5, if we want to keep or drop it. BTW: To decouple the GC from the allocator code would be nice.
Transferring to 3.5 for now.
(0001263)
zesstra   
2009-09-12 06:33   
Now that we are working on 3.5: do we want to drop xptmalloc? I vote for yes.

(For decoupling the GC from the allocator we should create a new issue.)
(0001278)
zesstra   
2009-09-18 07:22   
I no last minute objections, I will remove xptmalloc tomorrow.
(0001281)
zesstra   
2009-09-20 05:47   
ptmalloc was removed in r2746.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
521 [LDMud 3.5] Runtime minor always 2007-10-18 09:23 2011-02-13 22:38
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Overflows in string statistics
Description: Sorry for yet another overflow in the statistics. ;-)

String handler:
--------------- Strings Bytes (Data+Overhead)
Total asked for 7786294 281646482 (149279484+132366998)
Total allocated 729111 51079496 ( 38422465+ 12657031)
 - tabled 616083 43650345 ( 32914790+ 10735555)
 - untabled 113028 7429151 ( 5507675+ 1921476)

Space required vs. 'regular C' string implementation: 5% with, 25% without
overhead.
Searches by address: 161432956 - found: 161432956 (100.0%) - avg length: 1.094
Searches by content: 881756876 - found: 4118127974 (467.0%) - avg length: 0.679
Hash chains used: 65529 of 65536 (100.0%)
Distinct strings added: 162049039 - deleted: 161432956
Collisions: 161224279 (99.5% added)
Equality tests: 2628322655 total, 2946161777 by table (112.1%), 638101843 by
hash (24.3%)
Comparisons: 1917844876 total, 2810187620 by table (146.5%)
Table lookups for existence: 513163480, 109167934 by table (21.3%), 403995546 by content (78.7%)

As you see, there are at least 3 overflows (searches, equality tests and comparisons). Additionally the comparison to C strings seems to be flawed (space required should be less without overhead).
The counters are already p_uint so we probably would have to go the way suggested in 0000520 for solving it (giga-searches etc.).

BTW: This is probably an issue to nearly all the statistics counters for heavily used operations in larger muds, e.g. outgoing traffic in network i/o as well, which is limited to 4GB. (Our uptime is only 24 days until now.)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000589)
zesstra   
2008-01-26 16:47   
Mhmm, wouldn't it be the simplest solution to change these counters (I think, a few more overflowed in the meantime in Morgengrauen) to int64/int64_t/long long? I think, that is less complicated and less expensive at runtime than introducing corresponding giga counters...
Is there any serious disadvantage I do not see at the moment?
(0000738)
zesstra   
2008-07-16 18:57   
I am not sure how to handle this. Actually, I would like to just change these counters to a larger int. That should be mp_uint, but as long as mp_uint is the same size as p_uint, it won't help on ILP32 platforms. That would only change on ILP32 platforms, if we change mp_uint to uintmax_t, which we can't until 0000556 ist resolved.
So, we could wait with this bug until we solved 0000556 and uintmax_t or ulong long or uint64_t on systems which have one. Or we introduce that Gigacounter strategy, but that is more complicated...
(0000739)
Gnomi   
2008-07-17 02:24   
I would use (unsigned) long long int. We need a new typedef in port.h for that, so it can be used also on ILP32 platforms.
(0000740)
Gnomi   
2008-07-17 02:28   
Erm, right, that means waiting for 0000556.
(0001188)
zesstra   
2009-06-03 14:12   
Ok, I will introduce a new typedef statcounter_t with corresponding modifiers for printf in port.h and change all the heavily used stat counters to this type.
(0001190)
zesstra   
2009-06-03 16:04   
Resolved in r2626.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
518 [LDMud 3.5] Implementation feature N/A 2007-09-23 14:16 2011-02-13 22:38
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Support for longer (double-word) string hashes and larger string tables
Description: The string hashes (whash_t) are currently an unsigned short (16 bits, a word). Thus the string table is limited to about 65k hash chains.
I wondered if it would beneficial for muds with much more tabled string than that (MorgenGrauen has now about 463916, but the uptime is still short), to increase the hash length of string hashes to 32 bits (double-word, p_uint). Of course, the actual hash table length will be smaller than 2^32 entries. ;-)
The disadvantage is an increase of used memory per string (16 bits) and some for the string table (calculation of the hash isn't an issue here).
The hash function D.J. Bernstein uses in his CDB is reportedly very fast and efficient. Therefore I just decided to give it a try this afternoon.

The attached patch introduces a new compile-time switch USE_DWHASH. Only if set, the larger hashes and the DJB hash function will be used.
* new typedef: p_uint dwhash_t
* 2 new hash functions: dwhashmem2() and dwashstr(). dwhashmem2() is aliased to dwhasmem() by a define.

If USE_DWHASH is defined:
* changes the hash in string_s to dwhash_t
* changes the hash calculation and returning function to dwhash_t and to use dwhashmem(), dwashstr() in mstrings.c|h
* likewise changes to otable.h|c, lex.c (lex.c is not strictly necessary, as the identifer table is anyway much shorter than 2^16, but is hasn't any impact on the hash calculation speed.)

I haven't done more than initial tests yet.
I compared the pure calculation speed of the old and new hash functions and found, that the new one is actually a tiny bit faster. (all done with the same string)
1000000 dwhashstr():
real 0m0.499s
user 0m0.486s
sys 0m0.006s

1000000 whashstr():
real 0m0.570s
user 0m0.556s
sys 0m0.006s

1000000 chashstr():
real 0m0.578s
user 0m0.571s
sys 0m0.005s

In a freshly started homemud (with 131072 entries in the string table) the average search length by content decreased from about 1.5 to 1.2, the amount of used hash chains obviously increases (about 40%). Memory consumption increased by a few hundred kb, but this number is crude.

This patch a just an experiment and I may well have missed some points in the code, obviously it shouldn't be used in a real mud right now. But if anybody would like to do some tests with it concerning performance and stability or has some comments and ideas, I would be happy.
Tags:
Steps To Reproduce:
Additional Information: http://cr.yp.to/cdb/cdb.txt
http://en.wikipedia.org/wiki/Constant_Data_Base
http://www.mathematik.uni-ulm.de/sai/ws02/oodb/slides/physindex-03.html
Attached Files: dwhash.diff (11,022 bytes) 2007-09-23 14:17
http://ldmud.eu/file_download.php?file_id=111&type=bug
0014-Dump-tables-strings-upon-shutdown.patch (2,113 bytes) 2009-06-04 03:47
http://ldmud.eu/file_download.php?file_id=245&type=bug
Notes
(0000640)
Gnomi   
2008-07-01 05:09   
Just to add a number: In UNItopia we currently have 713974 tabled and 165125 untabled strings (after an uptime of 106 days). So we have 100% collisions and a bigger table would be appropriate. It would cost 2MB, so it would not hurt, but also not be taken lightly.

Is that a candidate for 3.5?
(0000645)
zesstra   
2008-07-01 07:37   
It is similar in Morgengrauen: 681094 tabled strings, 130178 untabled, uptime: 137 days.
I would like to try this in 3.5. I will also have to keep a 32-vs-64-bit issue here in mind, because my initial patch uses p_uint for storing the hash value, this should be changed.
(0001174)
zesstra   
2009-06-01 04:48   
I started working on updating my old patch and did some more research about the CDB hash function. According to http://burtleburtle.net/bob/hash/doobs.html it works especially well for short keys (5 characters mixed case english words have no collisions), but on other cases, it has its problems.
From the same page I conclude, that there are 2-3 alternatives:
* Paul Hsieh's hash (also on http://www.azillionmonkeys.com/qed/hash.html)
* Bob Jenkins hash (lookup3.c)
* Murmurhash (also on http://murmurhash.googlepages.com/)

From these, lookup3.c seems to be the strongest one, Paul Hsiehs' SuperfastHast has a small performance gain, but has funnels of 3 bits into 2. MurmurHash is the fastest. Bob Jenkins mentions, it is weaker than lookup3, but he doesn't eloborate on details.
I would probably favor Bob Jenkins hash function - the downside is a more complicated code.
(0001186)
zesstra   
2009-06-02 16:57   
Ok, I experimentally used Bob Jenkins lookup3 hash function.

Some speed comparison:
(Test case: Hashing the string "Also ich oute mich mal jetzt als Wurstseher, der von einer Quest oefters nur 90% (oder so) selber rauskriegt." 10000000 times.)

Old hash, non-optimized
real 0m7.806s
user 0m7.745s
sys 0m0.028s

New hash, non-optimized
real 0m4.066s
user 0m4.041s
sys 0m0.014s

Old hash, -O3
real 0m2.880s
user 0m2.857s
sys 0m0.010s

New hash, -O3
real 0m1.181s
user 0m1.156s
sys 0m0.008s

So far, so good. Now remains to find out, if the strength of Jenkins hash concerning collisions is really as high as promised... ;-)
(0001187)
zesstra   
2009-06-02 18:01   
Ok, one more: MurmurHash2.
Murmur, -O0
real 0m3.418s
user 0m3.394s
sys 0m0.013s

Murmur, -O3
real 0m0.602s
user 0m0.594s
sys 0m0.005s

Looks quite impressive. That is a factor of 5 compared to our current hash. ;-)

I found some additional information about the strength of the hashes:
http://murmurhash.googlepages.com/statistics
http://murmurhash.googlepages.com/avalanche
http://home.comcast.net/~bretm/hash/
(0001191)
zesstra   
2009-06-03 17:45   
Ok, I did some tests concerning the hash quality of the three hashes: Pearsons (the old one), Jenkins, Murmur. I used a dictionary containning 51248 distinct english words.
Explanation of the output below: I used a hash table for storing the strings, but used only 20 of 32 bits of the hash for the table. Therefore, the number of table collisions (hash chains with a length > 1) is significantly larger than the number of real hash collisions, but nonetheless interesting for the application in the driver I think.

1) Jenkins
51248 Strings added, 48887 hash chains created.
2361 table collisions occurred
1 real hash collisions
Average hash chain length: 1.0483
Collisions:
6bd5a61c - torsion; 6bd5a61c - Heineken


2) Murmur
51248 Strings added, 48781 hash chains created.
2467 table collisions occurred
1 real hash collisions
Average hash chain length: 1.0506
Collisions:
fc95820d - ope; fc95820d - dodger


There is not much difference concerning the number of real collisions, but Jenkins hash seems to be slightly better distributed, the are less table collisions, more hash chains used and the average hash chain length is smaller.

For comparison the old hash:
51248 Strings added, 25888 hash chains created.
25360 table collisions occurred
15276 real hash collisions
Average hash chain length: 1.7175
Collisions:

I spare the output of 15276 collision. ;-)
(0001193)
zesstra   
2009-06-04 03:52   
I would like to do some real world tests with strings used in several muds. The idea is to dump all tabled strings upon shutdown into a file. I attached a patch to do this.
Obviously, it is probably a bad idea to apply that patch to live muds, but if you have a test mud, I would be happy if would try it.

Sending me the string dump may be a potential danger, because the strings may contain private/confidential information (decide yourself). For this case, I will later attach a collection of small test programs for testing a few hashes, so you can test locally on you string collection.
(0001197)
_xtian_   
2009-06-10 05:42   
Do you need this patch/test applied against a specific version? (also: there ist no tarball available for the 3,3.719 release, yet)
(0001198)
zesstra   
2009-06-11 05:21   
The patch was build for the head of the trunk, but it should apply cleanly on the head of 3.3 and 3.3.719 as well.
Yes, the release was tagged, but not yet published to the homepage.
(0001227)
zesstra   
2009-06-22 04:24   
I did some tests with a collection of 738875 unique strings from MorgenGrauen yesterday. The results are shown below for different hash table sizes. Pearson is our old hash function.
Seems like the difference between Jenkins and Murmur is not significant, but Murmur ist faster (see 0000518:0001186 and 0000518:0001187).

Columns of the tables:
Chain -> no. of chains created.
Table Collisions -> no. of collision in the table
Coll -> no. of real hash collisions
S -> length of shortest hash chain
LC -> length of longest hash chain
Avg. len -> average hash chain length.

16bit
  Hash |Chain|T-Coll|Coll |S|LC|Avg. len
"Pearson" |65530|673345|673343|1|30|11,2754
"Murmur" |65531|673344|71 |1|28|11,2752
"Jenkins3"|65534|673341|72 |1|28|11,2747

17bit
  Hash |Chain|T-Coll|Coll |S|LC|Avg. len
"Pearson" |65532 |673343|673343|1|30|11,2750
"Murmur" |130597|608278|71 |1|18|5,6577
"Jenkins3"|130593|608282|72 |1|28|5,6578

18bit
  Hash |Chain|T-Coll|Coll |S|LC|Avg. len
"Pearson" |65532 |673343|673343|1|30|11,2750
"Murmur" |246585|492290|71 |1|14|2,9964
"Jenkins3"|246383|492492|72 |1|14|2,9989

19bit
  Hash |Chain|T-Coll|Coll |S|LC|Avg. len
"Pearson" |65532 |673343|673343|1|30|11,2750
"Murmur" |396070|342805|71 |1|10|1,8655
"Jenkins3"|396078|342797|72 |1|10|1,8655

20bit
  Hash |Chain|T-Coll|Coll |S|LC|Avg. len
"Pearson" |65532 |673343|673343|1|30|11,2750
"Murmur" |529885|208990|71 |1|7|1,3944
"Jenkins3"|530800|208075|72 |1|8|1,3920
(0001264)
zesstra   
2009-09-13 10:50   
Ok, some tests with strings from Avalon were similar to the ones with the string from MG. I replaced now the Jenkins Hash by Appleby's Murmurhash2. This concludes the issue for now.
One thing left: the hash function in its current from doesn't care about alignment. Or rather: it assumes, it can read a uint32_t from any pointer it gets. If that causes problems, we have to introduce a second variant and check for alignment problems with autoconf.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
274 [LDMud 3.5] Implementation feature N/A 2004-11-27 00:26 2011-02-13 22:38
Reporter: lars Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.8 and before  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Reaction to signals
Description: Short: Signal handling
Date: Fri, 21 Dec 2001 16:16:21 -0700
From: Daniel Podlejski <underley@underley.eu.org>
Type: Feature
State: New

> Lars Duening wrote:
> [...]
> : > : Neat idea! But I'll modify it a bit: the signal handler will reset
> : > : the SIGTERM to the default behaviour, so if the driver is really
> : > : wedged, the second SIGTERM will just abort the program.
> : >
> : > Fine.
> : > But on most unices durning halt/reboot scripts send SIGTERM and after
> : > few secounds - SIGKILL.
> :
> : *nod* I mean that more for more convenient commandline use than
> : anything else.
>
> Right. So you also should add SIGINT handling, similar to your SIGTERM
> handling.

Currently, the shutdown handling is defined for SIGHUP.

Look up the meanings of SIGINT, SIGQUIT and SIGTERM and add
appropriate handlers. Maybe SIGINT should still break immediately.

Date: Mon, 17 Dec 2001 13:14:58 -0700

Lars Duening wrote:
[...]
: > : Neat idea! But I'll modify it a bit: the signal handler will
reset
: > : the SIGTERM to the default behaviour, so if the driver is
really
: > : wedged, the second SIGTERM will just abort the program.
: >
: > Fine.
: > But on most unices durning halt/reboot scripts send SIGTERM and
after
: > few secounds - SIGKILL.
:
: *nod* I mean that more for more convenient commandline use than
: anything else.

Right. So you also should add SIGINT handling, similar to your
SIGTERM
handling.

--
Daniel Podlejski <underley@underley.eu.org>
   ... Promised myself I wouldn't weep
   One more promise I couldn't keep ...
------- End of forwarded message -------
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001637)
_xtian_   
2009-11-20 06:38   
I will second this ... On my home machine I use SIGINT quite a lot and it would be nice if the mudlib could respond to it.
(0001667)
zesstra   
2009-12-22 11:13   
Ah, what was the idea, or let me rephrase: What should the driver do upon receiving SIGINT?
(0001668)
Gnomi   
2009-12-22 11:27   
Call a driver hook?
(0001741)
zesstra   
2010-02-17 19:18   
Im anyway working on the signal handling right now, so I will take this one.

SIGKILL can't be handled/caught. On SIGTERM I would argue to handle it just like SIGHUP (controlled shutdown), because in most cases there will be a SIGKILL a few seconds later.
We should make a list which other signals we would like to receive in the mudlib.
Concerning SIGHUP, SIGUSR2 and SIGUSR2 we might call the driver hook and fall back to our current behaviour if it returns 0 or is not defined.
(0001742)
zesstra   
2010-02-19 16:42   
I reworked the signal handling between r2872 - r2882 (3.5) and included this.
SIGHUP, SIGINT, SIGUSR1 and SIGUSR2 are now deferred to the mudlib master. If it handles them (by returning !=0 in handle_external_signal()), the driver takes not further action, otherwise falls back to the current reaction.

SIGTERM is deferred to the mudlib, but can't be handled. After handle_external_signal() returns, the driver begins with a graceful shutdown.
(0001874)
zesstra   
2010-07-13 17:06   
Ok, improved the handling of SIGTERM+SIGINT in r2922 a bit. I consider this then resolved if noone objects.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
228 [LDMud 3.5] Efuns feature N/A 2004-11-26 23:31 2011-02-13 22:38
Reporter: lars Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.8 and before  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Remove efun tail() (was: cat(), tail() should take limits)
Description: Short: Expand cat() and tail() to take limits
From: Cendor
Date: 000421
Type: Feature
State: New

Modify cat() and tail() to take the number of lines to be printed
(in cat() this also means getting rid of the cut-off).
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001300)
zesstra   
2009-09-26 19:32   
Well, at least cat is now history. So is half of this issue. Question: do we kill tail() as well as cat()?
(0001336)
Gnomi   
2009-09-29 12:53   
I'd vote for killing tail() as well.
(0001352)
Coogan   
2009-09-29 17:06   
agreed to kill it, too.
(0001357)
zesstra   
2009-09-30 15:55   
Ok, I will mark the efun as deprecated in 3.3, remove it in 3.5 and supply as reference implementation of tail() as sefun.

(0001545)
zesstra   
2009-10-21 16:49   
Marked tail() as deprecated in r2775 and removed in r2774 (trunk, 3.5.x).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
597 [LDMud 3.5] Portability minor N/A 2009-01-16 15:05 2011-01-11 20:58
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: low OS Version: 10.5.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Change hash in ident_s to whash_t instead of short
Description: The hash in ident_s in lex.h should be of type whash_t and all users should use consistently whash_t. On the one hand because it is more portable. Additionally halft of the value range is lost because we don't need the sign. (whash_t is currently also short, but unsigned.)
So... Check all users of ident_s structures. ;-)
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0001951)
zesstra   
2011-01-11 20:58   
Uh. It seems, I did this some time ago but forgot to resolve this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
678 [LDMud 3.3] Compilation, Installation major N/A 2009-09-19 16:27 2011-01-11 09:13
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: immediate OS Version:  
Status: resolved Product Version: 3.3.719  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: Unreliable source of entropy for initializing the openssl PRNG
Description: I just had a look at tls_global_init() in pkg-openssl.c. The PRNG from openssl is initialized by using the following data:
        data1.uname_1 = uname(&data1.uname);
        data1.uname_2 = errno; /* Let's hope that uname fails randomly :-) */

        data1.uid = getuid();
        data1.euid = geteuid();
        data1.gid = getgid();
        data1.egid = getegid();

        RAND_seed((const void *)&data1, sizeof data1);

        data2.pid = getpid();
        data2.time = time(NULL);
        data2.stack = (void *)&data2;

        RAND_seed((const void *)&data2, sizeof data2);

This seems to me not a particularly good way to do this. data1.uid, data1.euid, data1.gid, data1.egid are constant and may be known. data2.stack, data1.uname_1 and data1.uname_2 are probably constant as well and maybe also guessable. data2.time can be easily guessed, even by players. So there remains the PID and data1.uname. One could hope, that in .uname is enough trailing, more or less random, garbage, but is that assumption right?

From three gdb sessions:
(gdb) print data1.uname
$1 = {sysname = "Linux", '\0' <repeats 59 times>,
  nodename = "mg\000ne)", '\0' <repeats 58 times>,
  release = "2.6.18-6-686", '\0' <repeats 52 times>,
  version = "0000001 SMP Tue Jun 17 21:31:27 UTC 2008", '\0' <repeats 29 times>,
  machine = "i686", '\0' <repeats 60 times>,
  __domainname = "(none)", '\0' <repeats 58 times>}

(gdb) print data1.uname
$1 = {sysname = "Linux", '\0' <repeats 59 times>,
  nodename = "mg\000ne)", '\0' <repeats 58 times>,
  release = "2.6.18-6-686", '\0' <repeats 52 times>,
  version = "0000001 SMP Tue Jun 17 21:31:27 UTC 2008", '\0' <repeats 29 times>,
  machine = "i686", '\0' <repeats 60 times>,
  __domainname = "(none)", '\0' <repeats 58 times>}

(gdb) print data1.uname
$1 = {sysname = "Linux", '\0' <repeats 59 times>,
  nodename = "mg\000ne)", '\0' <repeats 58 times>,
  release = "2.6.18-6-686", '\0' <repeats 52 times>,
  version = "0000001 SMP Tue Jun 17 21:31:27 UTC 2008", '\0' <repeats 29 times>,
  machine = "i686", '\0' <repeats 60 times>,
  __domainname = "(none)", '\0' <repeats 58 times>}

Seems not.

Am I just not seeing something? If not, we should change this ASAP.

Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001288)
zesstra   
2009-09-21 15:41   
OK, the situation is a follows:

1) we add very little entropy to the state.
2) on platform with /dev/urandom, /dev/random, /dev/srandom OpenSSL implicitly uses /dev/urandom (with /dev/(s)random as fallback) to add 32 bytes of entropy to its state.
3) OpenSSL implicitly adds uid, pid and time to its state, so our addition of these three is redundant and does not help.

So, we are somehow OK (although 32 bytes seem not very much to me) on Linux & Co (MacOS included). On Windows OpenSSL is said to use something called CryptoAPI to find entropy which it adds automatically, but I don't know that for sure.
On some platforms (but which, is the question now), using TLS currently sucks!

There is one big nasty problem: OpenSSL warns and refuses to work, if there too little entropy in its state. BUT: It gathers the amount of entropy from RAND_add(buf, len, entropy), so it is user-supplied. Even worse: the RAND_seed() we use, is just an alias to RAND_add(buf, len, len), so it assumes every byte contains 8 bit of entropy. This is abviously wrong (nearly always), but especially in case of our very weak source of entropy. So by seeding the PRNG in this way, we disable OpenSSL's safeguard, because it always thinks, it has enough entropy. And on platforms with strong source of entropy which OpenSSL uses automatically, this puts our users at risk.

So, I see several possibilities:
1) Find a better source of entropy. This would be great and solve all our problems. But it is also very difficult to do so. (suggestions?)
2) Use RAND_add(buf, len, 0.0) in our initialization. This adds our very little entropy, but it won't cause OpenSSL to falsely think, it has enough, even if it has no other source. So it will fail, which is good.
3) Remove seeding/adding to OpenSSL's entropy pool altogether. Same as 2), it will fail, if there is no other strong source of entropy.

Opinions?

BTW: Maybe we should write a short comment about this on ldmud-talk...? Just in case, somebody uses LDMud+OpenSSL for TLS on a vulnerable platform?
(0001289)
zesstra   
2009-09-21 17:55   
Newer versions of OpenSSL use besides /dev/urandom, /dev/random and /dev/srandom also the sockets of the EGD (entroy gathering daemon).
After a short discusson with Gnomi and Coogan I think, I will implement option 3, check the seed status during tls_global_init() and disable TLS, if OpenSSL didn't get enough entropy automagically.
On platforms where this happens, we can deal on demand with the bug reports.
At least in this way, there should not be a false sense of security.
(0001291)
zesstra   
2009-09-22 15:48   
Another request for comments:
RAND_poll() is the function OpenSSL has for automagically get entropy from /dev/random & EGD. It can also be called by applications. I thought about calling that every i TLS connections (e.g. 50), to add some fresh entropy to the mix. RAND_poll waits for maximal 10ms for each device (so 30ms) and stops once it got 32 bytes. And the non-blocking urandom is tried first. So I think, the impact would not be significant.
What do you think?

BTW: As far as I understand, if you create a symmetric key with 128 bits, it would be best to use 128 bit of real entropy for this. In practice we are safe with less I guess. OpenSSL uses a PRNG which it seeds with 32 bytes (ideally 256 bits). Now, the question is: should you add new entropy after generating two 128bit long symmetric keys...?
(0001514)
zesstra   
2009-10-07 09:29   
Gnomi and I discussed last week shortly about the possibility of DOS by many new connections to cause the driver to poll /dev/*random very often per second. Although you will need about 30*50 new TLS connections per second for the given example, we might introduce a time limit for adding entropy (e.g. not more often than every 300 seconds). Or forget it whole. But with uptimes of hundreds of days, I would feel more comfortable to add some entropy in between.

I had a look at postfix TLS documentation. They state, the initial entropy of 32 bytes (256 bits) is sufficient for at 128 or 168 bit session key. They add entropy from the external random device by default every random(3600) s, add the time of day everytime somebody uses tlsmgr and update it periodically with TLS session cache entries (don't know about that period).
(0001948)
zesstra   
2011-01-11 00:23   
I now introduced the following:
a) for each new connection the gettimeofday() is added to the entropy pool of OpenSSL before the TLS connection is initialized.
b) the first connection after PRNG_RESEED_PERIOD/2 + random(PRNG_RESEED_PERIOD) seconds since the last call to RAND_poll causes additionally a call to RAND_poll() from OpenSSL, which will use a system-dependent source of strong entropy to add fresh entropy to its pool.
PRNG_RESEED_PERIOD defaults to 1800. For now, it is a compile-time constant.
(0001949)
zesstra   
2011-01-11 09:13   
Ok, then this is fixed for 3.3 and 3.5.
If there platforms where RAND_poll() does not work properly or there are other problems, please file a report.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
605 [LDMud 3.5] LPC Compiler/Preprocessor feature N/A 2009-02-06 12:21 2010-11-20 20:00
Reporter: sinnvoll Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Ideas for the preprocessor (start-end-tag-defines, foreach-loop)
Description: I often use a master-object to store data,
with many specialized set/query-functions, all with the same structure.
You could simplify that.

Some Ideas for that:
At first I need the ##-glue-operator for defines,
but this is part of an other idea in the database.
I want to show this idea in short form, to build onto it.
I hope it motivates to implement the ##-glue-operator.

The following code does not do, what you might think:

#define SET_QUERY(typ,name) \
type a; \
void set_name(type a) { name=a; } \
type query_name() { return name; }

The valid standard-c-syntax is:

#define SET_QUERY(typ,name) \
type a; \
void set_##name(type a) { name=a; } \
type query_##name() { return name; }

without glue-operator you could simplified the underlying structure,
but not so effective:

#define SET_QUERY(typ,name,setname,queryname) \
type a; \
void setname(type a) { name=a; } \
type queryname() { return name; }

The following new ideas I propose for the preprocessor:

For better readibility, to do multiline defines in an easy fashion:

#define_start SET_QUERY(typ,name)
type a;
void set_##name(type a) { name=a; }
type query_##name() { return name; }
#define_end

compared to now:

#define SET_QUERY(typ,name) \
type a; \
void set_##name(type a) { name=a; } \
type query_##name() { return name; }

now you have to look out for missing \ oder blanks following the \

on the other side to process a list of uniform data
a loop-construct seems useful

#foreach (a,b) ((string,name),(string,id),(int,plural)) SET_QUERY(a,b)

or:

#foreach (a,b) "%s %s\n" "filename" SET_QUERY(a,b)

with a file 'filename':
string name
string gender
int plural

You could store the shared structure of files with the same or related interface
i.e. the interfaces can differ in securing of the set-function
( private function, test of valid_caller)
or one object with only set-functions and the other only query_functions

a currently usable alternative is:

items.inc:
ITEM(string,name)
ITEM(string,gender)
ITEM(int,plural)

It is possible to utilize this include-file in the form:

#define ITEM(a,b) SET(a,b)
#include "items.inc"
#undef ITEM(a,b)
#define ITEM(a,b) QUERY(a,b)
#include "items.inc"
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000947)
zesstra   
2009-02-08 10:05   
Ok, as a first comment: I don't like precompiler magic like this very much and would definitely not accept it in domains I am responsible for. ;-) I tend to keep as many defines out of the code as possible with exceptions of constants. So personally I am not very interested in such features.
(0001131)
lynx   
2009-05-22 03:57   
The ##feature looks sweet, but I'm not sure if we need so much lex sugar.

Looking at the actual use for this being '#foreach (a,b) "%s %s\n" "filename" SET_QUERY(a,b)' why don't you just generate a file to be #included, which has all the necessary LPC code generated by a previous LPC program?
(0001156)
Gnomi   
2009-05-25 17:18   
Programmatically generated LPC code is not the way I would like to go or encourage others to go. But I'm in favor of the ## operator.
(0001157)
Gnomi   
2009-05-26 03:50   
But I think this should go to 3.5.
(0001158)
Sorcerer   
2009-05-26 04:52   
Like zesstra, I am not a friend of too many precompiler directives in code I have to read (or even maintain). This being a personal taste, there is also one "non-personal" argument against those extensions:
LPC is a programming language that aims at a clientele that is not too familiar with programming (many start with LPC as their first "real" programming language). For those I think the extensive use of the precompiler will add one more burden when learning how to implement their ideas in LPC-code.
(0001928)
zesstra   
2010-11-20 20:00   
Sorcerers point is even more valid for new wizards who try to assume responsibility for a region/domain. So even if they don't use that stuff, they have to know it because somebody else might have used them.
I admit, I have a warped perception here because of too many wizards trying to obfuscate their code with precompiler stuff.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
764 [ProFTPD-mod_mud] General feature N/A 2010-11-16 17:16 2010-11-16 17:16
Reporter: zesstra Platform: i686  
Assigned To: OS: GNU/Linux  
Priority: normal OS Version: 4.0  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Module should have a configuration option for the location of home directories
Description: The home directories of wizard are different in different Muds (/players/ in MG-like MUDs, /w/ in Unitopia-like MUDs).
Instead of changing the source of the module it should be configurable.
Tags:
Steps To Reproduce:
Additional Information:
System Description MorgenGrauen server
Debian Etch.
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
759 [LDMud 3.2] Runtime crash unable to reproduce 2010-09-30 19:02 2010-10-16 12:27
Reporter: Coogan Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.16  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: segmentation fault
Description: In Tubmud I had a crasher today, the first since over a year.
Unfortunately, after an uptime of almost one year I had to recompile the driver because of lib updates which meanwhile took place. At recompiling I accidentally switched from 3.2-dev.724 to 3.2.16, so I don't know if this crasher is the same as it has been fixed in 0000622.
Tags:
Steps To Reproduce:
Additional Information: The backtrace of gdb says:

Core was generated by `/home/tubmud/mudbin/driver -Mkernel/master -DTUBMUD=1 -D__START_TIME__="_S_T_20'.
Program terminated with signal 11, Segmentation fault.
[New process 21901]
#0 large_free (ptr=0xaf50428 "ìž\003\n\001\001\006R\001\006q")
    at smalloc.c:2096
2096 *(ptr+size-1) = size; /* copy the size information */
(gdb) bt
#\0 large_free (ptr=0xaf50428 "ìž\003\n\001\001\006R\001\006q")
    at smalloc.c:2096
#\1 0x080dc0dc in xfree (ptr=0xaf50428) at smalloc.c:1245
#\2 0x080dd063 in rexalloc_traced (p=0xaf47a88, size=8192) at smalloc.c:3051
#\3 0x080b4b6c in realloc_mem_block (mbp=0x812c200, size=-1895365628)
    at prolang.y:911
#\4 0x080bcdd8 in yyparse () at lang.y:7316
#\5 0x080c3d3a in compile_file (fd=15) at prolang.y:12838
#\6 0x080cc258 in load_object (lname=<value optimized out>, create_super=0,
    depth=0, chain=0x0) at simulate.c:1876
#\7 0x080cc953 in lookfor_object (
    str=0xa19d5c0 "domains/glandon/npc/voittout", bLoad=1) at simulate.c:2289
#\8 0x08082fe8 in eval_instruction (first_instruction=0x97f2823 "\033",
    initial_sp=0x81056b8) at interpret.c:16704
#\9 0x0809ad02 in apply_low (fun=0x96cdd2c "reset", ob=0x9e2b654, num_arg=1,
    b_ign_prot=0) at interpret.c:21684
#\10 0x08089bb2 in eval_instruction (
    first_instruction=0xbfbcb157 "\204\003\026", initial_sp=0x81056b8)
    at interpret.c:15753
#\11 0x08081c85 in call_lambda (lsvp=0x81056a0, num_arg=3) at interpret.c:22774
#\12 0x0808d6f8 in eval_instruction (
    first_instruction=0x96dcc13 "R\003\003\016\002(\a\b\2350X\v|\024\204ð",
    initial_sp=0x8105698) at interpret.c:15929
#\13 0x0809ad02 in apply_low (fun=0x9515c84 "call_other", ob=0x807b6f5,
    num_arg=3, b_ign_prot=0) at interpret.c:21684
#\14 0x0809afa9 in call_simul_efun (code=<value optimized out>, ob=0x8f070404,
    num_arg=3) at interpret.c:22879
#\15 0x08082202 in call_lambda (lsvp=0x8105668, num_arg=3) at interpret.c:22805
#\16 0x0808d6f8 in eval_instruction (
    first_instruction=0xae81203 "\016\020\0044^\021GN\\ ",
    initial_sp=0x81055b8) at interpret.c:15929
#\17 0x08081f18 in call_lambda (lsvp=0x81055b0, num_arg=1) at interpret.c:22424
#\18 0x0808d6f8 in eval_instruction (first_instruction=0xae845b7 "\\\024",
    initial_sp=0x81055a8) at interpret.c:15929
#\19 0x0809ad02 in apply_low (fun=0xa7b7250 "call_command", ob=0x97f1e10,
    num_arg=1, b_ign_prot=0) at interpret.c:21684
#\20 0x0809b05d in sapply_int (fun=0xa7b7250 "call_command", ob=0x97f1e10,
    num_arg=1, b_find_static=0) at interpret.c:21796
#\21 0x0804cd97 in parse_command (buff=0xbfbcd0b6 "Call here reset 1",
---Type <return> to continue, or q <return> to quit---
    from_efun=0) at actions.c:1082
#\22 0x0804e4e3 in execute_command (str=0xbfbcd0b6 "Call here reset 1",
    ob=0xa6d7ef8) at actions.c:1238
#\23 0x08055f93 in backend () at backend.c:601
#\24 0x080a7aa1 in main (argc=14, argv=0xbfbceb94) at main.c:517
(gdb) q
Attached Files:
Notes
(0001900)
zesstra   
2010-10-01 08:17   
Without the core, corresponding binary and source it will be nearly impossible to analyze the cause of the crash. It looks like an incorrect size information. But line 2096 is in build_block() instead of large_free (at least in 3.2.16). Maybe an issue with showing inlined functions in gdb.
The interesting question is, if this issue still exists in 3.3.x or 3.5.x. ;-)
(0001901)
Coogan   
2010-10-02 11:36   
This is more a 3.2.17 than a plain 3.2.16, as the fix for 0000677 is mentioned in the CHANGELOG. In the src-directory, the following .c-files have a newer timestamp than original 3.2.16:
-rw-r--r-- 1 tubmud tubmud 130713 2009-10-05 00:28 make_func.c
-rw-r--r-- 1 tubmud tubmud 38245 2009-10-06 09:34 pkg-tls.c
-rw-r--r-- 1 tubmud tubmud 54494 2009-10-06 10:15 efun_defs.c
-rw-r--r-- 1 tubmud tubmud 3303 2009-10-06 10:16 stdstrings.c
-rw-r--r-- 1 tubmud tubmud 522080 2009-10-06 10:16 lang.c
(0001902)
Coogan   
2010-10-02 11:47   
The bzip2-ed core file is available under: http://www.tubmud.de/ftp/mantis/
(0001903)
Gnomi   
2010-10-16 10:28   
Zesstra is correct in that the size information of a memory block is corrupted (the higher half word was changed from 0xf000 to 0x8f07, the lower half seems to be correct, the bytes before and after that seem also okay).

But I have no idea how it could be changed in such a way.

If this happens more often, I'd recommend compiling with MALLOC_TRACE (which uses magic bytes for checking for correct pointers and gives information on the type of each memory block).
(0001904)
Gnomi   
2010-10-16 11:37   
Coogan, could you post the instrs.h from the sources?
(0001905)
Gnomi   
2010-10-16 12:07   
Never mind, I found a bug in the compiler with "call_other" simul-efuns, that corrupted the memory block afterwards. Maybe that resulted in the corruption of the program block itself. I'll commit a fix to 3.2 trunk. It does not affect 3.3 or 3.5.
(0001906)
Gnomi   
2010-10-16 12:27   
Fix committed as r2932.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
401 [LDMud 3.3] Networking feature always 2005-09-09 08:58 2010-08-18 16:55
Reporter: lynx Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: duplicate  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version:  
Summary: more control over discarded output
Description: this is how comm.c:add_message() handles the case of output lost in transmission
as reported by a EINTR or EWOULDBLOCK. additionally we get some stderr warnings.

    if (ip->msg_discarded)
    {
        ip->msg_discarded = MY_FALSE;
        add_message("%s", "\n*** Text lost in transmission ***\n");
        /* msg_discarded might be TRUE again now */
    }

i would prefer it the interactive or at least the master object was called
instead, and given as much information as possible on the event. then it can
decide to either recover the network link, or to drop it. but having a string
output which is meaningless to most protocols other than telnet, is not exactly
the solution these days... :-/

Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001121)
Gnomi   
2009-05-19 18:04   
In r2551 a driver hook was implemented, that is called after messages had to be discarded.
(0001898)
zesstra   
2010-08-18 16:55   
I haven't noticed it since then, but I did not use Mantis much, because vacations and not enough time.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
725 [LDMud 3.3] Runtime minor have not tried 2010-02-13 04:55 2010-07-14 18:31
Reporter: zesstra Platform: i686  
Assigned To: zesstra OS: GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version: 3.3.719  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: 'dumpallobj' crashes in svalue_size() on strings with 0 refs.
Description: svalue_size() in dumpstat.c takes into account any sharing of entities. In case of strings, its memory size will be divided by the number of its refcounts.

In case of strings with a refcount of 0, this will crash, because the function does not check the refcount before division. (Note: ref==0 for strings are perfectly valid, it marks the strings as 'permanent' and it is never free'd.)
Tags:
Steps To Reproduce:
Additional Information:
System Description MorgenGrauen server
Debian Etch.
Attached Files:
Notes
(0001720)
zesstra   
2010-02-13 05:06   
The same behaviour exists for symbols, mappings, arrays and quoted arrays, structs and closures.

Mappings are free'd for ref<=0, they don't this 'don't free marker'. Although a mapping with 0 refs may occur if somebody just uses deref_mapping() instead of free_mapping().

Structs, Arrays and Closures should currently also not have 0 refs.
But one question is, if we might want to introduce the 'no free for ref==0'-behaviour for them as well. The background for this behaviour of strings is that it serves as a protection against overflowing refcounters. Once this happens and ref==0, any refcounting will be disabled. This overflow can also happen for all other shared entities, although it seems unlikely to happen in reality.

In this respect, we might conservatively check for ref==0 in all this cases, 'dumpallobj' is anyway rarely executed and will stop the mud for some time anyway...
(0001721)
zesstra   
2010-02-13 06:56   
I commited a fix for the immediate problem with strings in r2849 and r2848.
Concerning the other types I wait for comments.
(0001873)
zesstra   
2010-07-13 16:12   
Any opinions? Should I check for ref==0 just in case we change something somewhere else and forget about this?
(0001875)
Gnomi   
2010-07-13 17:47   
I think a ref of 0 nearly always indicates an overflow and should be handled as such (the initialization and destruction of a value are the only exceptions I know of).
(0001877)
zesstra   
2010-07-13 18:06   
Ok... Then I will change svalue_size() first to cope with zero refcounters.
In a second step we then have to look at the refcounting code for the other shared entities. I guess I will open a new issue for that.
(0001880)
zesstra   
2010-07-14 18:31   
Ok, I changed svalue_size() to check for ref!=0 for all entities with ref counters in r2927 and r2928.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
659 [LDMud 3.5] Portability minor N/A 2009-06-12 17:19 2010-07-13 16:04
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Legacy functions / checks for C99/POSIX functions
Description: I think, we should get rid of non-standard/legacy functions (such as bcopy), if there is a standard function (like memmove).
Right now I noticed bcopy which is used if there is no memmove(). If there is also no bcopy, we provide our own definition. As we anyway require ISO C99 and POSIX compatibility, we should just require memmove().
Similar thing to memcpy(): remove check for it and require it.

I guess, a) there may be other functions which are nowadays 'legacy' and superseded by their equivalents in C90/C99/POSIX and b) checks for functions from these standards and fallbacks. Does anybody argue for keeping these in 3.5.x?
Tags:
Steps To Reproduce:
Additional Information: http://www.opengroup.org/onlinepubs/000095399/functions/bcopy.html
Attached Files:
Notes
(0001200)
zesstra   
2009-06-12 17:21   
Another one: bzero -> memset.
(0001201)
zesstra   
2009-06-12 17:38   
Next candidates:
* strtol
* memset
* strcspn
* strdup
* getrusage
(0001202)
zesstra   
2009-06-12 17:44   
Ok, now I noticed, that we already unconditionally use memmove() at many places and use only sometimes the move_memory() from ports.c. I think, we can just remove the abstraction move_memory() then as well. ;-)
(0001212)
zesstra   
2009-06-16 18:11   
Removed the ones mentioned until now in r2648 - r2658.
(0001871)
zesstra   
2010-07-13 16:04   
Closing until I (or someone else) find more candidates.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
340 [LDMud 3.5] LPC Compiler/Preprocessor feature N/A 2005-01-11 10:59 2010-07-13 15:40
Reporter: _xtian_ Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: "obsolete" modifier
Description: An "obsolete" modifier for lfuns, sefuns which throws a compilation/runtime warning if the so marked function is called (compiled function call as well as as call_others at runtime).

This is another item, that would help handling big libs with a lot of historical accumulated nonesense.
Tags:
Steps To Reproduce:
Additional Information: note that this behaviour can be simulated by explicitely notifying wizards, writing into a bug-database, etc.
But I would favour an easy, fast, standarized way to handle this.
Attached Files:
Notes
(0000298)
_xtian_   
2005-01-11 11:16   
ah, and it could help MUDs prepare their switch to 3.3 by masking the efuns that are to vanish with an "obsolete" sefun
(0000310)
_xtian_   
2005-01-19 06:15   
come to think about it "deprecated" probably wouldn't sound that harsh.
(0001718)
zesstra   
2010-02-12 19:14   
Oh, BTW: I like that idea (Although it might be difficult to find a bit for that flag in the function header.) We have plenty of old nonsense floating around... I am surprised that I did not comment earlier.
(0001749)
Coogan   
2010-03-03 18:00   
Years ago, I wrapped each obsoleted efun by an sefun of the same name, giving a warning each time it was used. In the second stage, the sefun throws an error, pointing to the particular successor function.
This way it's quite comfortable to switch to a more recent driver version with "vanished" efuns.
(0001750)
zesstra   
2010-03-03 18:11   
Yes, that works good for efuns. But for them we have such a mechanism in the driver source which we also use (e.g. cat(), tail() in 3.3.x).

But in this case (lfuns, sefuns) it does not really work. You might define sefuns for obsolete lfuns, but you will have difficulties to defer from the sefun to private/protected lfuns. And if it triggers a warning on each call you might be flooded with scroll.
Additionally it does not catch call_others. You might define a call_other sefun and check on each call. But that introduces a signifcant slowdown for each call_other...
I think, the driver would be better suited, because it can do a lot things at compile-time and the remaining (call_other) much more efficient.
(0001767)
Bardioc   
2010-03-05 14:15   
I would love to have this modifier! Even though EverLIB is not old, parts of the domains are, and this would help alot!
(0001768)
zesstra   
2010-03-07 12:02   
I worked on this a bit. It is not committed to the driver sources yet, because I would like to have some comments first.
I added a modifier 'deprecated' for functions (in theory it could be extended to variables at some point), which will set TYPE_MOD_DEPRECATED in the function flags. Upon calling such a function (intra-object + sefuns) the compiler will issue a warning at compile-time. Callothers and lfun closure evaluations will cause a warning at runtime (this could trigger a huge number of warnings, be warned).

There are still two caveats to be solved:
1) the warning in case of lfun closures will not include the correct line number + defining program (the correct solution would be to check before pushing a new control stack frame, but therefore I need a possibility to get the function flags indepedent of setup_new_frame1()).
2) If you call a not-defined function and this will be defined later by inheritance/cross-definition the compiler will miss any deprecated modifier, because the call was generated when the flag was unknown.

You can find the changeset at: http://github.com/zesstra/ldmud-dev/compare/deprecated_mod and the deprecated_mod branch is at http://github.com/zesstra/ldmud-dev/tree/deprecated_mod. Comments welcome.
(0001776)
zesstra   
2010-03-10 16:29   
BTW: Should it be possible to 'loose' the deprecated flags by redefining the function in inheritees?
Pro: I deprecate a specific function (e.g core lib) and don't care about redefined function as long as they don't call me.
Contra: Maybe I want to deprecate an interface as a whole, not only the function I define myself...
(0001778)
_xtian_   
2010-03-10 17:22   
We would use "deprecated" if we want to change or eliminate parts of APIs. In that case we don't even want another user to keep on redefining that function - which he surely only did redefine in the first place to extend the inherited API.

In that case redefining the function will not work any more as expected and the user should be notified of this.

So: Pro: "deprecated" should not go away.
(0001779)
_xtian_   
2010-03-10 17:29   
Concerning 2) (external declarations of functions):
In uni-libs, at least if we haven't diverged that much, we use external declarations quite a bit for the core living and player objects (the code is deployed over several inherits), so this limitation might be a bit hindering.

Could a work-around be to issue a warning if the compiler encounters a redefinition where not all declarations are "deprecated"?
(0001784)
Gnomi   
2010-03-11 04:55   
I disagree. I might have a program with a function fun() that is perfectly valid and will stay. And just because some other program had a fun() that is now deprecated, this doesn't make my fun() invalid or deprecated as well, just because both programs were inherited together in another program. And I'd rather not differentiate between redefining a function and cross-defining it to another inherited program (because it's basically the same and moving a function to an inherited program should be a valid refactoring step, so it should behave similarly).

In other words, the deprecated flag should warn whenever the removal of that function declaration with this flag alters the behavior at the point of the warning (might not compile anymore or might call a function that was hidden until now). And when a deprecated function is redefined by a non-deprecated function the removal of the deprecated function changes nothing for the caller (which still calls the non-deprecated one), so no warning there.
(0001785)
zesstra   
2010-03-11 05:33   
Right, so to summarize the two different wishes:
a) Gnomi wishes to deprecate functions
b) Xtian wishes to deprecate interfaces

Unfortunately both are mutually exclusive. Gnomi offered the opinion, that we probably can't do b) consistently. One issue is, that we can't prevent somebody from implementing a deprecated interface himself and not inheriting the original program defining the interface at all. Although that is IMHO very rare (might in theory be excluded by code-style conventions).

Actually I could probably use both a) and b) independently in our lib... ;-) Usually I would deprecate functions. But there are some exceptions. e.g. we have an interface do_wear() which is obsolete and we do things differently now. If a wizard redefined do_wear() and did not call ::do_wear() there would be no warning, but his do_wear() will a) do the wrong things to wear a piece of clothing or b) his object will completely miss when a player wears the object (e.g fail to enforce restrictions).

So far, I guess you would have to use first deprecated, then a deprecated+nomask empty function to deprecate interfaces.
(0001787)
_xtian_   
2010-03-11 14:01   
Yes, my wish (point b) can actually be realized by using "deprecated" (as Gnomi argued) and "nomask", or even the "warn_nomask" (http://mantis.bearnip.com/view.php?id=734) idea.

Please note, that we once proposed a "required" modifier which guaranteed that a inherited function would call ::fun() (http://mantis.bearnip.com/view.php?id=352). All these suggestions come from the frustrating experiences of maintaining an API over decades and inexperienced programmers, btw so all have real used cases. (yes, I remember that "required" still had some difficulties)
(0001788)
zesstra   
2010-03-11 14:26   
Yes, I fully share that frustration, we also have our share of ancient APIs and wizards who just copy a function from the core lib and the copy is never maintained anymore, gets no updates or bugfixes, until some ugly enough bug happens. (BTW: that suggestion about 'required' is still here in Mantis. Although I guess, we can't make it happen until we have a compiler which can analyze the execution flow. :-()
(0001794)
zesstra   
2010-03-14 10:54   
Ah, concerning the issue with the cross-defined functions: IMHO it not so big as it seems.
If you have a (matching) prototype with deprecated, the driver will warn. If you don't have a prototype, AFAIK you can only call the function if the calling function is compiled without type testing (it has no function type, which is not allowed with anything other than weak_types.
If you don't call a function without prototype yourself, that leaves call_other and symbol_function at runtime. And at runtime, the flags from the cross-defined functions are available (and would contain the deprecated flag).
(0001797)
zesstra   
2010-03-14 11:40   
Updated my test branch for this: the flag is now checked upon creation of closures, not at evaluation time (symbol_function, compiler (#'fun, #'::fun)).
(0001811)
zesstra   
2010-03-21 12:25   
I added checks for usages of deprecated global variables and committed my patch series to the trunk of 3.5. for testing.
(0001870)
zesstra   
2010-07-13 15:40   
Ok, no complaints so far. Closing this one for now.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
747 [LDMud 3.5] Implementation minor always 2010-04-21 17:53 2010-04-26 16:35
Reporter: zesstra Platform: i686  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Cloning a blueprint with active heart_beat() disables its heart_heart permanently.
Description: If you clone a blueprint object which has an active heart_beat, its HB will be deactivated.
AFAIR this is done to prevent creating clones with active HBs, so the HB of the blueprint will be deactivated first. But I think, the HB should be reactivated after cloning is complete.
Or is there a compelling reason why it should be this way?
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (32 bit)
Darwin Kernel Version 10.6.0: Wed Nov 10 18:13:17 PST 2010; root:xnu-1504.9.26~3/RELEASE_I386 i386
Attached Files:
Notes
(0001826)
zesstra   
2010-04-23 17:35   
I am a bit irritated. The source states that HBs are deactivated to prevent the creation of copied (cloned) objects with enabled HBs. But the flags of the blueprints are anyway not copied to the new object... So for me that deactivation seems to be completely superfluous.
(0001833)
zesstra   
2010-04-26 16:35   
Removed the deactivation of the HB in r2903 (3.5.) and r2904 (3.3.)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
742 [LDMud 3.5] Other minor always 2010-03-30 13:44 2010-04-23 18:30
Reporter: _xtian_ Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: 3.5.0 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: incorrect build no in debug-log (3.5)
Description: all my debug logs show in the first line:

2010.03.22 11:37:26 LDMud 3.5.0 (Build 2656) (development)

this can't be the correct build no / revision. it is the same on all my machines.

can anyone else reproduce or invalidate this?
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001818)
zesstra   
2010-04-08 14:18   
No, its true. As far I as can see that info comes from version.sh which is generated by the release scripts and release time. Unfortunately, the script which is supposed to modify version.sh is not in the svn repo, right now I can't even look what is it should do.
(0001819)
zesstra   
2010-04-21 17:22   
Ok, as I can't properly update version.sh right now, because I don't now, which script should do that, I changed now mk-patchlevel to extract the revision from SVN or git (depending on availability) first and fall back to the data from version.sh if no SCM data is available.
I hope, the shell logic is portable enough. ;-) If you like, please test r2900.
(0001824)
_xtian_   
2010-04-21 18:28   
works on debian
(0001827)
zesstra   
2010-04-23 18:30   
Then I assume this to be resolved for now.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
741 [LDMud 3.5] Runtime crash sometimes 2010-03-26 10:30 2010-03-27 06:17
Reporter: zesstra Platform: i686  
Assigned To: zesstra OS: GNU/Linux  
Priority: high OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Crash in closure_location()
Description: We had two crash in Morgengrauen in closure_location() during a errorf(), called by check_function_args(). I had no time for a closer look so far, but I have a stacktrace (it is the same for both crashes):

(gdb) bt
#0 0x0805fd7a in closure_location (l=0xffffffef) at closure.c:5652
0000001 0x08088efb in get_line_number_if_any (name=0xffff8d88) at interpret.c:18959
0000002 0x080e6b2f in errorf (fmt=<value optimized out>) at simulate.c:908
0000003 0x08088227 in check_function_args (fx=<value optimized out>,
    progp=<value optimized out>, funstart=0x9654b8a "\002\003a\002\002??l\001\031\b")
    at interpret.c:6536
0000004 0x080a37cb in int_call_lambda (lsvp=0x81541a0, num_arg=1, allowRefs=false,
    external=true) at interpret.c:18160
0000005 0x080a3e2f in v_funcall (sp=0x81541a8, num_arg=2) at interpret.c:20716
0000006 0x080992ef in eval_instruction (first_instruction=0x98bc5a4 "a\003\tb\036",
    initial_sp=0x8154058) at interpret.c:8480
0000007 0x080a3c2c in int_call_lambda (lsvp=0x8153ff8, num_arg=3, allowRefs=false,
    external=true) at interpret.c:18164
0000008 0x080a3e2f in v_funcall (sp=0x8154010, num_arg=4) at interpret.c:20716
0000009 0x080992ef in eval_instruction (
    first_instruction=0x9b2723c "a\004\002?\003<&\b?\017", initial_sp=0x8153f08)
    at interpret.c:8480
0000010 0x080a2e12 in apply_low (fun=0x9502c54, ob=0xe147584, num_arg=4, b_ign_prot=false,
    allowRefs=false) at interpret.c:17188
0000011 0x08091110 in int_apply (fun=0x9502c54, ob=0x11f704a0, num_arg=0, b_ign_prot=false,
    b_use_default=true) at interpret.c:17266
0000012 0x080993d2 in eval_instruction (first_instruction=0xc8eb348 "bp",
    initial_sp=0x8153dc0) at interpret.c:16517
0000013 0x080a323c in call_function (progp=0xc92f1dc, fx=286) at interpret.c:18629
#14 0x080831c4 in call_heart_beat () at heartbeat.c:289
#15 0x08057610 in backend () at backend.c:845
#16 0x080b091f in main (argc=3, argv=0xffffbbc4) at main.c:678
Tags:
Steps To Reproduce:
Additional Information:
System Description MorgenGrauen server
Debian Etch.
Attached Files:
Notes
(0001816)
zesstra   
2010-03-26 18:17   
The reason for this bug is a peculiar behaviour of int_call_lambda(): when executing closures from another object, an additional dummy frame with funstart==0 is pushed onto the control stack. check_function_args() pops a frame from the stack to attribute the error to the caller. In case of an error upon calling such a closure, this leaves the dummy frame and get_line_if_any() does not cope well with funstart==0. For now, check_function_args() must pop this dummy frame as well.

The long-term solution (also for some other problems) would be to call check_function_args() before pushing a control frame, but we first have to change the way to calculate and set funstart, progp, function_offset, variable_offset (separate the calculation of these from the actual update of the global variables).
(0001817)
zesstra   
2010-03-27 06:17   
This is fixed in r2897 by removing the dummy frame in check_function_args().

The long-term solution is planned (also for improving handling of 'deprecated' and possibly other things), but will take some time.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
136 [LDMud 3.5] LPC Compiler/Preprocessor feature N/A 2004-10-15 23:49 2010-03-15 18:45
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Enforce the call of super functions.
Description: I agree there is no common standard, that's why I thought about the
reserved word as a flag to functions like:

public <some keyword> void create();
or
<some keyword> public void create();

A function defined like that would then have to call (::create()) at some point
or make the compiler complain and possibly abort compilation. This way
any function with the keyword in its definition has to call the parent. In other
words not limited to return types of the function. Obviously the topmost
inherit doesn't have to call (::create()).

An alternative would be to flag overriding functions as 'wont-call-super', and have the error happen by default.

This way the proper initialisation of objects could be insured, for example.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000239)
_xtian_   
2004-12-07 07:26   
this is also a good idea. Note that most MUD wizards are not experienced coders (and many don't want to be), so we need all the syntactic sugar we can get to be able to design for really, really unknowing programmers.
(0000297)
_xtian_   
2005-01-11 10:51   
just thinking: additionally to the modifier, that ensures, that compilation is aborted, when a function is overridden without calling the super function, ANOTHER modifier would be useful, that just throws a compilation warning.
This would help for gradually updating big libraries. (where you can't foresee what you'll break)
(0000330)
_xtian_   
2005-02-19 15:20   
ideas for names are:
  super, sticky, obligated
(0000657)
zesstra   
2008-07-02 05:36   
Mhmm, I like this idea.
But I see a problem here: It is easy to check if the parent the is called at some point, but not easily possible to decide wether this code is executed at all, in some circumstances or if it is guarenteed to be called.
Multiple inheritance complicates it a little as well.
(0000795)
_xtian_   
2008-09-27 14:40   
Note that at some point lars suggested the term "required" for this feature, which we all liked best.
(0001803)
_xtian_   
2010-03-15 02:14   
Concerning the issue where this could only be properly implemented with a multi-pass interpreter: I would argue that it is sufficient for most cases to only enforce that the first line in the function needs to be ::fun
(0001804)
zesstra   
2010-03-15 05:02   
I am not sure about this. I know plenty of functions (including in my own code), which do not call their inherited one at the first line, e.g. because they change an argument before or do whatever else. Some others do something and end with return ::fun();, but there are IMHO enough functions which call the super functions somewhere in between to make this clumsy. (You can't make it an error than und there will be annoying warnings you have to remember to ignore.)
(0001805)
_xtian_   
2010-03-15 14:20   
Well, yes, but do they need to get a "required", too?

Most importantly, it'd be an acceptable compromise to get the functionality in ... even if it were just for starters.
(0001806)
Coogan   
2010-03-15 18:45   
We use replace_program() with a heuristic approach for a lot of objects. For this purpose, replace_program() must be called earlier then some of the <parent>::super() functions. Thus I can't agree to _xtian_ in #0001803 that the first line should be sufficient in most cases.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
704 [LDMud 3.5] Other tweak always 2009-11-12 04:23 2010-03-14 18:07
Reporter: Coogan Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: commandline options result in divergent named macros
Description: In my opinion the commandline options should match the corresponding macros (and vice versa).

Good examples:
__ALARM_TIME__ and --alarm-time
__MAX_COMMAND_LENGTH__ and --max-command-length
__MAX_MALLOC__ and --max-malloc

But:
__HEART_BEAT_INTERVAL__ and --heart-interval
__SYNCHRONOUS_HEART_BEAT__ and --sync-heart

Because the macros are named descriptively correct, their divergent commandline options should renamed.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001730)
zesstra   
2010-02-15 18:56   
I am inclined to change this in 3.5.x, then we don't break launch scripts from one minor revision to the next.
A argument against would be that people are lazy on the command-line, but we have the --args flag which should take care of most of the problem...

Are there more than these two? ;-)
(0001736)
zesstra   
2010-02-16 16:52   
I changed in r2865:
* --heart-interval -> --heart-beat-interval
* --sync-heart -> --synchronous-heart-beat
* --async-heart -> --asynchronous-heart-beat
* --no-heart -> --no-heart-beat
(0001800)
zesstra   
2010-03-14 18:07   
Closing for now, please ask me to re-open if there are others.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
731 [LDMud 3.5] Implementation minor N/A 2010-03-01 17:40 2010-03-14 12:47
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Make calling of heartbeats configurable at run-time
Description: [was: RfC: Remove suspension of heartbeats when no player is present.]
Currently the driver won't call any heart beats when no player is logged in. I guess, this was done to save computing time in the old times... Does anybody see another reason?

If not, I would like to change that and always call heart beats. That would make heart_beats a bit more reliable and one is not limited to callouts when doing regular tasks which should not be interrupted for an arbitrary amount of time.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001772)
Coogan   
2010-03-08 17:35   
I support the ability to have heartbeats even when no-one is logged on.
(0001777)
zesstra   
2010-03-10 16:32   
Another idea: we might make HB call just configurable at runtime (configure_driver()). Then the mudlib may just decide based on whatever wishes, assumptions or information it has.
(0001798)
zesstra   
2010-03-14 12:47   
I made the calling of heartbeats configurable at run-time by using configure_driver() in r2887. At the same time, calling of heartbeats does not need a logged-on player any longer.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
736 [LDMud 3.3] Runtime crash always 2010-03-11 16:51 2010-03-11 16:58
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: Crash in add_message() upon tracing (caused by do_trace())
Description: When compiled with DEBUG do_trace() calls add_message("%s",message_flush); message_flush is 0x0 and add_message basically calls strlen(0x0) which crashes at least on my platform.
The correct call would be add_message(message_flush);
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0001790)
zesstra   
2010-03-11 16:58   
Should be fixed in rr2884 and rr2885.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
728 [LDMud] Documentation text always 2010-02-22 20:51 2010-02-22 20:51
Reporter: Wildcat Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.3.718  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: efun documentation for filter hard to interpret
Description: the first line of the english doc for filter reads:
        Call the function <ob>-><func>() resp. the closure <cl> for
        every element of the array, or mapping <arg>, and return a
        result made from those elements for which the function call
        returns TRUE.

A strict reading of the sentence makes no sense. I believe what it is trying to say is:
"Call either the function <ob>-><func>() or the closure <cl> for every element of the array, or mapping <arg>, and return a result made from those elements for which the function call returns TRUE."

resp. is probably an abbreviation for respectively but that's not a word that a newly promoted wizard would expect to know in the context given.

In addition, that sentence does not address the prototype:
         mixed * filter (mixed *arg, mapping map, mixed extra...)
so the whole thing should probably be rewritten. (This was something that actually came up when a new wizard was trying to learn the Mudlib and when using filter was suggested to him he had difficulty in parsing what the efun actually did based on the man page.)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
174 [LDMud] LPC Compiler/Preprocessor minor N/A 2004-11-26 22:15 2010-02-14 12:38
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Preprocessor is not ISO-C compatible.
Description: Short: Preprocessor is not Standard-C compatible
Date: Tue, 22 Dec 1998 13:36:24 +0200 (EET)
Type: Feature
State: Acknowledged

Points in question:
 - macro substitution in strings shouldn't be done
 - no # or ## operators
 - this
     #define FUNCTION(func) #'func
   doesn't work as expected

Also the C-99 features are missing.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001727)
graveluth   
2010-02-14 12:38   
(Last edited: 2010-02-14 12:39)
Actually, I would like to have the # feature:

#define quote( X ) #X /* quote( foo ) is expanded to "foo" */

This is just an example the actual macro I want construct is slightly more complex.

Btw. we (Evermore) are using 3.5.


View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
560 [LDMud] Efuns feature always 2008-08-13 16:45 2010-02-13 04:40
Reporter: Largo Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: new efun to randomize array contents
Description: Hey guys,

I've written a small new efun named randomize_array() to replace some of these constructs with sort_array() to achieve an array randomization. Maybe you're interested in it, patch is attached.
Tags: ldmud-extensions
Steps To Reproduce:
Additional Information: Note that small p_int -> size_t change in array.h: It's not needed by the patch, but using size_t in this place made more sense to me.
Attached Files: shuffle_array.diff (3,442 bytes) 2008-08-17 10:55
http://ldmud.eu/file_download.php?file_id=151&type=bug
Notes
(0000757)
fufu   
2008-08-14 05:23   
I have no objection to this per se, but this is easy to implement with an sefun like this:

mixed *shuffle_array(mixed *a)
{
    a = copy(a);
    for (int i = sizeof(a); i; ) {
        int j = random(i--);
        mixed t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    return a;
}

I prefer the name shuffle_array (or maybe just shuffle). Also, the algorithm in the patch isn't quite correct - random_number(size) should be random_number(size - i) for fair shuffling.
(0000759)
Largo   
2008-08-17 09:03   
alright, useful or not, I adapted the patch to solve the issues.
(0001516)
zesstra   
2009-10-08 09:40   
I am not sure, if we should it as efun, because it does seem to be used so regularly or to be time-critical.
But it might well be useful, I know a few places in our mudlib, which do a similar thing. Maybe we can include a collection of contributed sefuns?
Either directly in the driver or in a 'unofficial ldmud extensions' (which could be in LPC as well as in C)?
(0001719)
zesstra   
2010-02-13 04:40   
For now I added the patch to http://github.com/zesstra/ldmud-extensions in hope that people find it there.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
720 [LDMud 3.5] Networking feature N/A 2010-01-29 15:33 2010-01-30 09:30
Reporter: zesstra Platform:  
Assigned To: OS:  
Priority: low OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Support DTLS (Datagram Transport Layer Security)
Description: Datagram Transport Layer Security (DTLS) protocol provides communications privacy for datagram protocols. It is based on the stream-oriented TLS protocol and is intended to provide similar security guarantees.
Since we support TLS for TCP connections, I think we should also support DTLS. This may also open up the possibility to encrypt Intermud traffic transparently at some point in the future.

Unfortunately, DTLS is not widely supported yet. OpenSSL has support for it, but no documentation at all. GnuTLS does not support it (yet?).
Until that changes or I have much more time to look into the code of OpenSSL (*shudder*), this issue serves just as reminder for the future...
Tags:
Steps To Reproduce:
Additional Information: http://en.wikipedia.org/wiki/Datagram_Transport_Layer_Security
http://www.net-snmp.org/wiki/index.php/DTLS_Implementation_Notes
http://sctp.fh-muenster.de/dtls-samples.html
http://archive.netbsd.se/?ml=openssl-users&a=2006-08&t=2303023
http://www.estacado.net/resip-dox/stack/files.html
http://vpmn.googlecode.com/svn-history/r103/trunk/src/udpsrvdtls.c
http://archive.netbsd.se/?ml=openssl-users&a=2009-01&m=9636051&list
http://git.infradead.org/users/dwmw2/openconnect.git/tree
Attached Files:
Notes
(0001710)
zesstra   
2010-01-30 09:30   
FTR. Some problems to solve later:
a) we have to store a SSL session for each peer. Upon receiving a packet, we have to assign it to a specific peer / SSL session.
b) we have to expire sessions at some point.
c) what happens, if we expire a session but the peer thinks it is still valid and sends us encrypted data?
d) if we use the same port for encrypted and unencrypted traffic, we have to decide which packets are intentionally not encrypted and should not trigger a session handshake. (e.g. if there is no SSL session for a peer, the packet has to contain something like STARTTLS to start a DTLS session, otherwise we send it directly to the mudlib...)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
713 [LDMud] Implementation minor always 2010-01-18 02:42 2010-01-25 17:20
Reporter: _xtian_ Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: 3.5.0 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: function names leaking in global string table?
Description: With the new string table allocator I get a lot of this in daily GC:


tabled string ace9ca20 'trinke_com' was left unreferenced, freeing now.


(about 20-30 items per day). All of these are function names to add_actions(), so maybe there is some kind of memleak.
Of course, it could also be in our mudlib, but for now I prefer putting this here, because I wouldnt know where to start looking anyway.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001698)
zesstra   
2010-01-24 13:55   
Uh, what new string allocator? AFAIR we didn't change anything in 3.5.
I believe, add_action() alone can not be the cause, I don't observe the issue in my testmud.
(0001699)
_xtian_   
2010-01-24 14:30   
Didn't you change the string allocator a while back? Or was it just the hash-function?
(0001700)
zesstra   
2010-01-24 14:42   
That was just the hash calculation and the length of the hashes and the max. no of chains in the table.
(0001701)
zesstra   
2010-01-24 16:23   
Ok, strings don't have a user field and knowing the original allocator (from MALLOC_TRACE, MALLOC_LPC_TRACE) of a shared string may also be not too informative...
Can you tell if the strings are always the same strings or does it seem to be random?
(0001702)
Gnomi   
2010-01-24 17:17   
I can reproduce it. Add_action() keep doesn't free its reference to the function name.
(0001703)
Gnomi   
2010-01-25 17:20   
Fixed in r2837.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
646 [LDMud 3.3] LPC Language feature have not tried 2009-06-01 06:22 2010-01-24 13:03
Reporter: _xtian_ Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.717  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: to_struct( STRUCT ) does nothing but could cast to other template
Description: Since casting in LPC is mostly done by to_int(), to_string(), etc ... it would be useful to be able to cast a struct to another struct type by using to_struct().

to_struct() already can cast mappings to specific struct-type by giving: to_struct( MAPPING, STRUCT-TEMPLATE ) so this would be a similar functionality. I propose:

to_struct( STRUCT, STRUCT-TEMPLATE )

Strictly speaking this can already be done by: to_struct( mkmapping( STRUCT ), STRUCT-TEMPLATE ) but I would suggest that this form of re-casting a struct should be stricter and thus throw an error/warning on incompatible struct-types (for ex. which are not inherited from another).
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001176)
zesstra   
2009-06-01 08:05   
Mhmm, I am not sure, if there is any information about the relation of two structs (e.g. b 'inherited' a) at runtime.
(0001177)
_xtian_   
2009-06-01 08:07   
Oh. hm. Mist. ;)
(0001181)
Gnomi   
2009-06-01 09:01   
There is even an efun that can do it: baseof. (But it seems that is has problems with empty base structs.)
(0001562)
zesstra   
2009-10-27 10:21   
I like the idea (although I would not call it 'cast', but 'conversion').

We could discuss, if in addition to conversion between structs in the same 'struct-inherit-chain' the conversion from anonymous structs to a specific one should be possible.

And one question is, if you can only convert from an inherited struct to one which inherits or also in the other direction:
struct a_s {int i;};
struct b_s (a_s) {int j; };

Conversion from a_s to b_s is simple (b_s->j would remain 0).
Conversion from b_s to a_s: disallow or just discard b_s->j in the new instance of a_s?
(0001565)
_xtian_   
2009-10-27 13:49   
Yes, I have a use-case where I convert up. Although the 'parent-struct' doesn't add members (I use it as a sort of typedef).
(0001591)
zesstra   
2009-11-03 16:38   
I created a patch for 3.5 implementing the conversion from a base to one its children and from a child to one of its bases. This is r2794 in trunk.
I plan to apply that later together with some other changes (e.g. for 0000695) to 3.3.
(0001696)
zesstra   
2010-01-24 13:03   
So far I heard of no complaints. I applied the changes as well to the 3.3 branch (r2827 - r2832). This should conclude the issue for now.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
715 [LDMud 3.5] Runtime crash always 2010-01-23 11:47 2010-01-23 11:53
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: call_out with bad arguments might crash with rttc
Description: When runtime type checks are activated, a call_out with bad arguments is about to be executed and prior to that a heart_beat() or a (s)efun closure call_out was executed the driver will crash while handling the rttc error.

The heart_beat or (s)efun closure leave the current_prog set afterwards which lead get_line_number_if_any() to believe that there is a valid stack frame (which isn't, because the rttc check removed the preliminary first one).
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0001691)
Gnomi   
2010-01-23 11:53   
I corrected both problems: current_prog is now cleared afterwards. And RTTC won't remove the first control frame. Committed as r2822.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
714 [LDMud 3.5] Runtime crash always 2010-01-19 17:02 2010-01-19 17:06
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: restore_object with RTTC crashes on unknown variables
Description: The runtime type checks in restore_object crash when a variable is restored that isn't there anymore.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0001689)
Gnomi   
2010-01-19 17:06   
Fixed in r2821.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
679 [LDMud 3.5] Implementation feature N/A 2009-09-20 05:26 2010-01-10 10:49
Reporter: zesstra Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Decouple the garbage collection code from the allocator code
Description: As suggested by Gawain via Fuchur in 0000552, we should try to decouple memory allocators and garbage collection.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001676)
zesstra   
2010-01-10 10:49   
If we work on garbage collection, we might have a look at http://doc.cat-v.org/inferno/concurrent_gc/concurrent_gc.pdf "Very concurrent Mark-&-Sweep Garbage Collection without Fine-Grain Synchronization" (L. Huelsbergen, P. Winterbottom, International Symposium on Memory Management, 1998)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
709 [LDMud 3.3] LPC Compiler/Preprocessor crash always 2009-12-20 22:05 2009-12-22 10:15
Reporter: Wildcat Platform: x86_64  
Assigned To: Gnomi OS: CentOS  
Priority: normal OS Version: 5.3  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: Repeatable crash in 64 bit build of 3.3.718
Description: Greetings,

I just upgraded form an ancient driver to the most recent driver and I'm getting a repeatable crash loading a specific NPC but as I try to narrow it down the stack changes, it's always in a null string deference during the cloning but the objects in the path can change. In this example it was /bin/damage/mino for example.

#0 0x0000000000450cf5 in mstr_mem_size (s=0x0) at mstrings.h:126
0000001 0x00000000004517cf in ref_mstring (s=0x0) at mstrings.h:187
0000002 0x00000000004588e0 in eval_instruction (
    first_instruction=0x24a41ca "b\001\002cq", initial_sp=0x7801f0)
    at interpret.c:8443
0000003 0x000000000046ea66 in apply_low (fun=0xbafbc8, ob=0x10dfd68, num_arg=1,
    b_ign_prot=true, allowRefs=false) at interpret.c:17096
0000004 0x000000000046ebf1 in int_apply (fun=0xbafbc8, ob=0x10dfd68, num_arg=1,
    b_ign_prot=true, b_use_default=true) at interpret.c:17174
0000005 0x000000000046f046 in sapply_int (fun=0xbafbc8, ob=0x10dfd68, num_arg=1,
    b_find_static=true, b_use_default=true) at interpret.c:17335
0000006 0x0000000000495002 in reset_object (ob=0x10dfd68, arg=5) at object.c:899
0000007 0x00000000004dffa0 in load_object (lname=0x7d0860 "bin/damage/mino",
    create_super=false, depth=0, isMasterObj=false, chain=0x0)
    at simulate.c:2120
0000008 0x00000000004e0842 in lookfor_object (str=0x108e950, bLoad=true)
    at simulate.c:2388
0000009 0x00000000004e473e in f_load_object (sp=0x7801a0) at simulate.c:4449
0000010 0x0000000000457eb5 in eval_instruction (
    first_instruction=0xbfd3b2 "b\001\001\037", initial_sp=0x780190)
    at interpret.c:8175
0000011 0x00000000004679b7 in eval_instruction (
    first_instruction=0x19777da "?\002\001\020,\00375l\001\031?\0035\n",
---Type <return> to continue, or q <return> to quit---
    initial_sp=0x780100) at interpret.c:14943
0000012 0x000000000046ea66 in apply_low (fun=0xbdb118, ob=0x250ea58, num_arg=1,
    b_ign_prot=false, allowRefs=false) at interpret.c:17096
0000013 0x000000000046ebf1 in int_apply (fun=0xbdb118, ob=0x250ea58, num_arg=1,
    b_ign_prot=false, b_use_default=true) at interpret.c:17174
#14 0x000000000046a57e in eval_instruction (
    first_instruction=0x7fff99e5e0f0 "?\030E", initial_sp=0x780100)
    at interpret.c:16444
#15 0x0000000000470df5 in int_call_lambda (lsvp=0x7800d0, num_arg=3,
    allowRefs=false, external=true) at interpret.c:18354
#16 0x0000000000474c65 in v_apply (sp=0x780100, num_arg=4) at interpret.c:20588
#17 0x0000000000458696 in eval_instruction (
    first_instruction=0xbffa2c "c\037", initial_sp=0x7800b0)
    at interpret.c:8374
#18 0x00000000004dc8c4 in catch_instruction (flags=0, offset=12,
    i_sp=0x8159b0, i_pc=0xbffa2c "c\037", i_fp=0x780070, reserve_cost=2000,
    i_context=0x0) at simulate.c:449
#19 0x000000000045a66b in eval_instruction (
    first_instruction=0xbffa22 "b\002\002?\003Yc ", initial_sp=0x7800a0)
    at interpret.c:9593
#20 0x000000000047048f in int_call_lambda (lsvp=0x780050, num_arg=2,
    allowRefs=false, external=true) at interpret.c:18075
#21 0x00000000004e5f63 in v_limited (sp=0x780080, num_arg=4) at simulate.c:5228
---Type <return> to continue, or q <return> to quit---
#22 0x0000000000458696 in eval_instruction (
    first_instruction=0xbffa82 "b\002\001\002\b\016?\206\001",
    initial_sp=0x780030) at interpret.c:8374
#23 0x00000000004679b7 in eval_instruction (
    first_instruction=0xb66d22 "b\002\006?\a", initial_sp=0x77fff0)
    at interpret.c:14943
#24 0x000000000046e646 in apply_low (fun=0xb88010, ob=0xbadb60, num_arg=2,
    b_ign_prot=false, allowRefs=false) at interpret.c:16983
#25 0x000000000046ebf1 in int_apply (fun=0xb88010, ob=0xbadb60, num_arg=2,
    b_ign_prot=false, b_use_default=true) at interpret.c:17174
#26 0x000000000046a57e in eval_instruction (
    first_instruction=0x12285a2 "b\001\003?\a", initial_sp=0x77ff40)
    at interpret.c:16444
#27 0x000000000046e646 in apply_low (fun=0xc02e08, ob=0x11e7aa8, num_arg=1,
    b_ign_prot=false, allowRefs=false) at interpret.c:16983
#28 0x000000000046ebf1 in int_apply (fun=0xc02e08, ob=0x11e7aa8, num_arg=1,
    b_ign_prot=false, b_use_default=true) at interpret.c:17174
#29 0x000000000046f046 in sapply_int (fun=0xc02e08, ob=0x11e7aa8, num_arg=1,
    b_find_static=false, b_use_default=true) at interpret.c:17335
#30 0x0000000000408968 in parse_command (buff=0x7fff99e62e30 "clone drguard",
    from_efun=false) at actions.c:1068
#31 0x0000000000409282 in execute_command (str=0x7fff99e62e30 "clone drguard",
    ob=0x11e7aa8) at actions.c:1269
---Type <return> to continue, or q <return> to quit---
#32 0x00000000004119f7 in backend () at backend.c:677
#33 0x00000000004819ef in main (argc=2, argv=0x7fff99e64888) at main.c:673

This only occurs if the driver is compiled on a 64 bit machine. I have a centos 5.3 i386 machine I do development on locally which doesn't exhibit the problem, but a centos 5.3 x64 does. Since it's so reproducible I can pretty much do whatever is needed to try to debug it more.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: bug709.diff (1,528 bytes) 2009-12-21 20:40
http://ldmud.eu/file_download.php?file_id=264&type=bug
Notes
(0001653)
zesstra   
2009-12-21 04:07   
Always nice to have some reproducible problem. ;-)
Could you supply us executable, coredump and the source code of the crashing program? Using a driver compiled with -O0 and -ggdb3 would be the best.
(If the package gets big, we might exchange it using ftp or alike).
(0001654)
zesstra   
2009-12-21 04:38   
Ok, on a second thought: as it is not a single program, which exhibits this behaviour, it may be a better idea to look at your mudlib. Do you have a public (minimal) mudlib, which triggers the crash and which we might use to reproduce it in our development environment?
Additionally, could you please add config.h, machine.h, Makefile and the output of 'gcc -dumpmachine' and 'gcc -dumpspecs' as well?
I use a driver compiled for x86_64 as well which does usually not crash. So I think, there has to be some significant difference either in your build environment or your mudlib.
(0001655)
Wildcat   
2009-12-21 12:55   
I've tarred up ldmud, a core dump, output of dumpmachine, dumpspecs, config.h, machine.h, Makefile into a tarball that can be found at http://www.thebigwave.net/709/709.tar.gz

Unfortunately the mudlib is extremely large and custom. It started life as a stock LP 2.4.5 in 1990 and has gone through different drivers along the way while still being compat mode. I'm pretty sure there isn't that many like it left around. The specific program that I found crashing 'drguard.c' hasn't been modified since '01 when I think we were on an Amylaar driver. I notice that it even used:
string sChat;
sChat = allocate(2);
sChat[0] = "String";
sChat[1] = "String";
type nomenclature, however changing that to string* sChat += does not avert the crash.

Is there an easy way to dump all programs that are being compiled? I could perhaps form a minimum mudlib if I can track down what's being loaded easily but there are several layers involved.

Given how reproducible it is, I just run a test driver/lib on another port and crash it all the time there, I can do whatever debugging you need done as I'm a professional game developer in my other life with experience shipping Linux based MMOs.
(0001656)
zesstra   
2009-12-21 15:11   
Thanks for the data.
Sometimes muds have a small, public version of their core lib without any secret objects and data, we could have checked if this is affected as well and used it as a starting point for a testcase. (Also, if we think about the possibility that programs are mis-compiled it helps to know how the compiled bytecode should look like.)
However, the driver writes a list of all programs compiled to stdout if you start it with the command line option -c.

Are you sure, you use a 3.3.718? I checked out 718 from our repository, but the line numbers in interpret.c don't match. Line 8443 is the opening { in CASE(F_FLOAT);. Are there any modifications/patches in use?
(0001657)
zesstra   
2009-12-21 16:00   
Ok, Gnomi told me, that this seems to be 3.3.719.
Then another thing: Could you do try 3.3.718 (and maybe even older releases) as well? If this bug was introduced recently, we may limit the problem to one release.

If you manage to assemble a test case, I could use git bisect to find the right revision, that would be even better. We could then trace the compilation as well.

Gnomi had a first look at the bytecode, which seems to be wrong. He needs the instr.h and the source of a crashing program.
(0001658)
Wildcat   
2009-12-21 16:59   
Yes it is 719, I'll try on 718 and a smattering of older releases. I'm also putting together a public mudlib with as much trimmed out as possible. One quick question, is there an option for 'deterministic random' I can easily turn on? The case has the NPC spawn a random race but I can trim out a few hundred files if it's always the same race. Actually an interesting point/question, I'm going to add the NPC in question to the end of the autoload and see if it crashes on startup with it listed there, this would reduce the set of files needed dramatically.

Another random thing while you can get all of the info from config.h I figure to mention the configure I run with:
./configure --prefix=/usr/users --enable-compat-mode --enable-erq=xerq --with-er
q-debug=0 --with-read-file-max-size=300000 --with-master-name=obj/master --with-
max-array-size=0 --with-max-mapping-size=0 --with-max-mapping-keys=0 --with-max-
players=100 --with-max-cost=5000000 --with-hard-malloc-limit=0 --enable-use-mysq
l --enable-use-mccp --enable-use-pcre=builtin --enable-use-xml=xml2 --enable-use
-tls --with-portno=2777 LDFLAGS=-L/usr/lib64/mysql

The driver is also stock 719 other than the configure script listed above, and ldd is returning:
        linux-vdso.so.1 => (0x00007fff7bffe000)
        /lib64/rtkaio/librt.so.1 (0x00007f1b73cae000)
        libnsl.so.1 => /lib64/libnsl.so.1 (0x000000396b000000)
        libm.so.6 => /lib64/libm.so.6 (0x0000003969c00000)
        libcrypt.so.1 => /lib64/libcrypt.so.1 (0x000000396b400000)
        libssl.so.6 => /lib64/libssl.so.6 (0x000000325e200000)
        libcrypto.so.6 => /lib64/libcrypto.so.6 (0x000000325ce00000)
        libmysqlclient.so.15 => /usr/lib64/mysql/libmysqlclient.so.15 (0x000000325e600000)
        libxml2.so.2 => /usr/lib64/libxml2.so.2 (0x0000003971000000)
        libz.so.1 => /usr/lib64/libz.so.1 (0x000000396a000000)
        libc.so.6 => /lib64/libc.so.6 (0x0000003969000000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003969800000)
        /lib64/ld-linux-x86-64.so.2 (0x0000003968c00000)
        libgssapi_krb5.so.2 => /usr/lib64/libgssapi_krb5.so.2 (0x000000325d200000)
        libkrb5.so.3 => /usr/lib64/libkrb5.so.3 (0x000000325da00000)
        libcom_err.so.2 => /lib64/libcom_err.so.2 (0x000000396e400000)
        libk5crypto.so.3 => /usr/lib64/libk5crypto.so.3 (0x000000325de00000)
        libdl.so.2 => /lib64/libdl.so.2 (0x0000003969400000)
        libkrb5support.so.0 => /usr/lib64/libkrb5support.so.0 (0x000000325d600000)
        libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x000000396b800000)
        libresolv.so.2 => /lib64/libresolv.so.2 (0x000000396bc00000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x000000325ca00000)
        libsepol.so.1 => /lib64/libsepol.so.1 (0x000000396a800000)

incase that comes up at all.

Ok, adding it to the startup file repros the crash 100% of the time and I just hardcoded the race to always be the same which also is reproing 100% of the time. Test mudlib should be forthcoming...

Ok, at http://www.thebigwave.net/crashlib.tgz is a minimal mudlib that reproduces it, you'll need to start the driver with -D PUBLIC_MUDLIB (used in master, quest, and commandd I believe) and it should start up and crash instantly given the before mentioned executable.

the instrs.h that was used to compile the debug version given before is in http://www.thebigwave.net/instrs.h

I think that's pretty much everything you could ask for/need, otherwise I'll be happy to supply more information.
(0001659)
Gnomi   
2009-12-21 17:14   
I tried the minimal mudlib and it complains about missing files in /obj/simul_efuns/ (included by /obj/simul_efun.c).
(0001660)
Wildcat   
2009-12-21 17:27   
I was afraid of that, there are some cases where includes are used and -c doesn't catch that, I'll grep the mudlib fast for includes and add anything that's not in a sys directory...

I did a single pass through it and update the lib at http://www.thebigwave.net/crashlib.tgz , I'll go and start a VM to verify it as well...
(0001661)
Wildcat   
2009-12-21 17:39   
Ok I verified that the size 213927 date stamp Dec 21 14:33 crashlib.tgz that's there now boots without an error until the point of crash. (While using -D PUBLIC_MUDLIB)
(0001662)
zesstra   
2009-12-21 18:01   
Thank you very much for the testcase. I can reproduce it on my system (and a different platform) and isolated the revision which introduced the error.
(0001663)
Gnomi   
2009-12-21 20:45   
I attached a patch that fixes this case. Unfortunately it doesn't seem to apply to 0000683 as well.

The problem was, that the compiler adjusted last_expression wrongly after it had moved some parts of the program, so that last_expression might point to an argument instead of an instruction (and when that arguments happened to be 0x14 (F_NUMBER) and the distance between last_expression and CURRENT_PROGRAM_SIZE happened to be 9, the compiler did some optimizations it better had not done).
(0001664)
Gnomi   
2009-12-22 10:15   
Bugfix committed as r2809.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
706 [LDMud 3.5] Documentation minor N/A 2009-11-21 06:18 2009-11-22 14:48
Reporter: Sorcerer Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: man-page of map_objects()
Description: Two corrections for the man-page of map_objects():

map_objects takes as first argument not object * but mixed * since one can also use the names of the objects (even mix objects and names). This applies to the English and the German man-page.

In the English description there is a reference to map_array() which should be replaced by map(). This is already fixed in the German man-page.

This issue also applies to other driver versions (at least 3.3).

Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001645)
zesstra   
2009-11-22 14:48   
Should be fixed by r2807 and r2808, thanks!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
64 [LDMud 3.5] Implementation feature N/A 2004-05-30 16:31 2009-11-06 05:57
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Improve array implementation.
Description: The current array implementation requires that with every change in length a new value block is allocated and initialized.

It would be advantageous to allow value blocks larger than required, and pre-alllocate them before they are used (e.g. double the allocated size whenever an extension is required).

In an even better version (which probably would require C++), multiple non-continguous blocks could be used to store the values.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000218)
lars   
2004-11-27 00:04   
Short:Efficient vector implementation
From: Lars
Date: 2001-06-15
Type: Idea

Use HATs (DDJ July 2001) for vector modifications,
essentially implementing 'dirty' and 'condensed' vectors.

The vector could be combined: the normal fixed length in one block,
plus the extensions as HAT. Very short arrays could be fully stored in the
vector control block, to save space.
(0001613)
zesstra   
2009-11-06 05:57   
Some links:
http://en.wikipedia.org/wiki/Hashed_array_tree
http://www.ddj.com/architect/184404698
http://www.ddj.com/184409965
http://www.ddj.com/architect/184410473

not related to HAT and arrays:
http://en.wikipedia.org/wiki/Radix_tree
http://cr.yp.to/critbit.html

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
50 [LDMud 3.5] LPC Compiler/Preprocessor minor always 2004-04-13 22:37 2009-11-04 19:12
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: redesign      
ETA: > 1 month Fixed in Version:  
    Target Version:  
Summary: & binds stronger than struct lookup
Description: In

  input_to("", 0, &room->exit);

the compiler complains that 'struct Room &' can't be used for member lookups. Reason is that & binds stronger than -> .

The current form of the compiler with its explicit spelling out of the reference productions prohibits any change of this behaviour - both the parser and the typetracking would need to get smarter to allow proper binding.

Testcase: t-040413
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
700 [LDMud 3.2] Documentation text always 2009-11-02 18:31 2009-11-03 16:45
Reporter: Coogan Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.16  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.2.16  
    Target Version:  
Summary: improve some efun manpages
Description: I backported my patches for the efun[.de] manpages to 3.2.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: diff-3.2-doc-efun-en.patch (153,760 bytes) 2009-11-02 18:31
http://ldmud.eu/file_download.php?file_id=261&type=bug
diff-3.2-doc-efun-de.patch (367,322 bytes) 2009-11-02 18:31
http://ldmud.eu/file_download.php?file_id=262&type=bug
Notes
(0001592)
zesstra   
2009-11-03 16:45   
Applied as r2797 in 3.2/trunk. Thank you Coogan.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
667 [LDMud] Runtime minor always 2009-07-28 01:35 2009-10-27 14:14
Reporter: _xtian_ Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.3.718  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: structs: compiled in access costs as many evals as runtime lookup
Description: If s is a struct with element int i:

both
  s->i; // compiled in access
and
  s->("i"); // computed at runtime
have the same evalcost (approx 30 evals)

This is not as expected, compiled-in access should be faster and cheaper.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001242)
Gnomi   
2009-07-28 02:42   
Struct indexing costs only 4 eval ticks (putting the struct on the stack, putting the index on the stack, putting the recognized structure type on the stack and performing the index operation).

This can't be made much faster. And I don't think we should make indexing per string more expensive, as mapping indexing using strings costs only 3 ticks.
(0001244)
_xtian_   
2009-07-30 10:05   
Yes, it seems my measurements were off. I get approx 5 eval ticks for both kinds of accessing now. Thank you for looking it up.

... one of the drawbacks to using an interpreter. One merit less for using structs, then, since in theory their compiled-in accesses should have been (noticeably) faster/cheaper than using mappings and mapping-indexing.
(0001253)
zesstra   
2009-09-04 13:40   
Well... Ticks are one thing, but just as important is runtime. I don't have any data on that and haven't used structs much. Does anybody know how that compares?
BTW: I think, the biggest advantage of structs is that the members are properly typed, while values in a mapping are completely anonymous.
(0001556)
zesstra   
2009-10-27 05:52   
Concerning my last note: I checked 100000 indexing operations 5 times with a struct with one element and a mapping with one element:
t->i: Time: 73074 +- 53us
t->"i": Time: 73143 +- 160 us
t->("i"): Time: 81036 +- 754 us
t["i"]: Time: 75890 +- 1749 us
(The number for +- are the standard deviations of the 5 measurements.)

Indexing a struct by t->i should be faster than indexing mappings (besides being typed), because it is basically indexing a vector/array. The difference should be bigger for larger structs/mappings...
BTW, I imagine when indexing big structs by strings, that will quickly be less favourable, because finding the member increases linearly with struct size.

BTW2: the compiler seems to optimize t->"i" to t->i. Couldn't it do the same for t->("i") ("i" is still a constant, after all)?

I agree with Gnomi, t->i can't be made much faster without removing type checks, which seem to have the largest share in execution time here (indexing itself is basically a vector indexing operation in C).
String indexing for structs might be made more efficient for large structs, but I don't now if it is worth the effort... Out of curiosity: How large are your structs Xtian?
(0001564)
_xtian_   
2009-10-27 13:39   
Hm, I hadn't even really thought about scalability. I would say none of our structs are larger than 10-20 elements.
For me the interest lay more in the simple overhead of the operation - what could be gained when we have several hundred (different) struct-queries per execution.

BTW: what is the rationale behind translating systime into eval-costs? Is there some sort of guideline? Is it even linear?
(0001566)
zesstra   
2009-10-27 14:14   
Ok, I guess, 10-20 is not too bad. ;-) Might be interesting to measure it once for comparison. You may order the members according to use frequency, because it is a linear search.

There is only one way of translating eval-costs to execution time: measuring it. The relation is certainly not linear.
The interpreter just increases the evalcost by one for every operation (or maybe better: loop in eval_instruction()). If dynamic evalcosts are enabled, for expensive efuns or efuns dealing with potentially large amount of data there are some additional costs (e.g. 5 ticks per iteration in md5(), 1/1000 chars of string length etc.). But the dynamic evalcosts are not consistently used.
So, if you are very unlucky: an operation may cost 1 tick, but lets the driver stall for hundreds of milliseconds (or even more), because the driver waits for the harddisk.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
180 [LDMud 3.5] Efuns feature N/A 2004-11-26 22:21 2009-10-07 07:56
Reporter: lars Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: Behaviour of explode("", "whatever")
Description: Short: Behaviour of explode()
From: Matthew Julius <julius.2@wright.edu>
Date: Fri, 08 Jan 1999 16:29:08 -0500
Type: Feature
State: Unclassified

explode("", "\n") returns ({ "" }) Snort. This should not be so.

alfebtcd wrote:

> no? why not? what should it be? all i want to be sure of is that it
> doesn't change every day and that x == implode(explode(x,y)) works for
> all legal x and y.

Erm. I must not have checked this correctly. I thought I tested it and it
did not work correctly. However, after checking again I see that it does
not cause any problems. The change was from the MudOS changelog so I can
only assume I was thinking of something else when I mentioned it.

Ahh yes, now I remember. I was confused in that explode("", "") == ({ })
This is different than, for example, explode("", "anything") == ({ "" })

explode("", whatever) should perhaps always return ({ "" })
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001325)
zesstra   
2009-09-28 13:02   
> explode("", whatever) should perhaps always return ({ "" })
Returning ({""}) seems to make sense to me. At least more than to return ({}) in explode("","") and ({""}) in explode("","whatever").

But how much breaks, when we just return ({""}), when the exploded string is ""? I guess not too much, because in most cases it anyways returns ({""})...
(0001344)
Gnomi   
2009-09-29 14:05   
This is fun. There are infinitely many solutions for explode(whatever, "") that satisfy implode(explode(whatever, ""), ""). For whatever = "", there are three noteworthy ones: ({}), ({""}), and ({"", ""}). Each one has its logic:

explode(whatever, whatever) returns always ({ "", "" }).
explode("", whatever) returns always ({ "" }).
sizeof(explode(whatever, "")) is always sizeof(whatever).

Perhaps make that configurable. :-D
(0001346)
Gnomi   
2009-09-29 14:22   
Oh, I forgot: explode(n*whatever, whatever) returns always (n+1)*({""}).

One of our wizards said, that when there are more than one solution, explode() should return the shortest one. And I agree.

We should leave it as it is now.

PS: On the other hand, that's the only occasion where explode() returns an empty array. Normally you can rely on the fact that explode(x,y)[0] exists. :-)
(0001358)
zesstra   
2009-09-30 16:03   
That reasoning is not bad...
I slightly favor the change to ({""}) because of your PS. I actually remember, that I was quite a long time the opinion, that explode will never return an empty array, because it returned a non-empty one on explode("","bla"). Therefore my code probably misses necessary checks an some points... ;-)
(0001387)
Coogan   
2009-10-01 04:13   
Even after long years of programming LPC, I'm surprised that explode() returns an empty array in one case. It was also my opinion, that explode()[0] exists. I'm not aware of any code in the mudlib (area lib) that checks for an empty result array of explode().

I also suggest to let explode("", whatever) always return ({""}).

As a next consequent step, implode(array, whatever) could return an error if the given array is empty.
(0001476)
zesstra   
2009-10-05 18:29   
I agree with Coogan and would change that for 3.5 and maybe for 3.3, if you think, the change in behaviour is not too big.
(0001483)
Gnomi   
2009-10-06 02:35   
It is rather unpredictable how much code this will break. So I'd say we do this in 3.5 only.
(0001486)
zesstra   
2009-10-06 03:42   
Right. Moved to 3.5.
(0001501)
zesstra   
2009-10-06 17:31   
I applied a patch to return ({""}) for empty strings in r2763. Additionally added some tests for explode checking the new behaviour and the example from the manpage. ;-)
(0001502)
zesstra   
2009-10-06 18:11   
Implemented Coogans suggestion as r2764. Added some tests for implode as well. I hope, that it will not cause too many errors. Otherwise we may have to reconsider.
(0001510)
zesstra   
2009-10-07 07:25   
There was a discussion about the issue of implode() raising an error if given an empty array on -d-code. Bardioc requested to keep the old behaviour.
I thought it to be a bit more consistent to the new explode behaviour, but overall I am quite indifferent.
(0001511)
Sorcerer   
2009-10-07 07:36   
This will break a lot of code, since explode() is not the only source of input to implode()... and up to now implode(({}),... works just fine.
(0001512)
zesstra   
2009-10-07 07:56   
OK, due to popular demand I removed the check for the empty array in implode() in r2766 (but kept the other changes like tests). ;-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
195 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-26 22:34 2009-10-07 01:42
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: feedback Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: New datatype 'long'
Description: Short: New datatype 'long'
From: Wessel Troost <mtroost@dds.nl>
Date: 990213
Type: Feature
State: Unclassified

Another good option would be a long data type.
Believe it or not, I've seen over 2 muds that had
experience go over MAX_INT.
*laugh*

Greetins
Xordin
Tags:
Steps To Reproduce:
Additional Information: Alternative: arbitrary long numbers (using one of the long-number libraries)
Attached Files:
Notes
(0000220)
lars   
2004-11-27 00:17   
Implement multi-precision numbers (see GNU MP Library gmp) on LPC level.
Righ's version for FinalFrontier currently uses efuns.
(0001475)
zesstra   
2009-10-05 18:27   
I think, on LP64 architectures long will be obsolete. The question is, whether we should implement something along GMP. Currently, it seems to me a bit overkill and it will make the language more complex and I don't really have a specific need for MUD development.

What about you (dear readers... ;-)?
(0001482)
Gnomi   
2009-10-06 02:34   
I don't know whether we should support GMP, but if we do so, it should be transparent to the user. I.e. the driver should automatically switch from int or float to a GMP type. (Because LPC is an amateur language.)
(0001491)
Largo   
2009-10-06 04:29   
There is a need for integers > MAX_INT. I "implemented" sort of GMP support, but (as lars mentioned) it's been based on efuns, so it's not transparent to the user.

I don't think it would be an overkill to support GMP, even for *every* LPC integral or floating point type, since it actually is well optimized and really fast. Some measurements I made confirmed that.

That would help us to get rid of borders or incorrect floating point calculations with no or just a really minimal trade-off.
(0001495)
zesstra   
2009-10-06 05:11   
Just to be sure: you have a need for integers > 2^63 / arbitrary large integers? Or a need for integers larger > 2^31?
(0001497)
Largo   
2009-10-06 06:26   
I've got a need for > 2^31.
(0001504)
zesstra   
2009-10-06 19:13   
Ok. ;-) That is something I also would like to have.
The question is, if we really need an additional type for that or if we should just fix the issues on LP64 platforms and then use the 64 bit wide long. (I regard a libGMP-type as additional, even if we would manage to implement it so that the user does not notice.)

Overkill wasn't necessarily targeted an runtime efficiency, but also at the work/time to implement it properly. Starting from the size of an svalue to the suggestion of the GMP developers that interpreters keep a free list or stack of initialized variables ready for use to save a lot of initialization/allocations/clearings. And then we might want to find ways to switch transparently between a standard C int and the mpz_t depending on the number the LPC int will have. Not to mention the less readable interface libGMP necessarily has for manipulating its entities (mpz_mul_ui (result, param, n); vs result=param*n;). We also have to take care of initializing and freeing all the GMP integers properly, e.g. before calling errorf().
I venture the idea, that it may be easier to switch to a long long in T_NUMBER on ILP32 platforms, if we just want to have a larger range.
(0001505)
Largo   
2009-10-07 00:19   
> The question is, if we really need an additional type for that or if
> we should just fix the issues on LP64 platforms and then use the
> 64 bit wide long.
No, it isn't. You don't have LP64 platforms widely spread, yet.

> (I regard a libGMP-type as additional, even if we would manage to
> implement it so that the user does not notice.)
> Overkill wasn't necessarily targeted an runtime efficiency, but also
> at the work/time to implement it properly.
You have to decide: Do you want to minimize the work or do you want to add an *additional* type? :-)

I think the first thing to do would be to have a clear distinction between LPC integers and C integers internally to the driver. That is also needed for proper 64 bit long support. This should be the most tricky part.

> if we just want to have a larger range
That seems to be the first step and the "must". The second question is, why do we have to have limited data types at all (limited in width, limited in precision)? LPC is a runtime language, we don't really have to get the last processor ticks out of it.

I think once we had that clear distinction mentioned above, it should not be a real problem to do any of the solutions.
(0001506)
Largo   
2009-10-07 01:42   
I thought a little more about the problem. We've got three different situations when handling numeric data types:

1) lib internal calculations, loading and storing numbers to/from objects
2) using numeric parameters with efun calls
3) driver internal

Point 3 code should avoid using the integral typedefs at all, but it often does not, because it is a convenient typedef if you want to make sure to have at least a 32 bit integer type to work with. This code is also the major problem if we wanted to use 64 bit integers.

In a perfect world, point 1 driver code would be encapsulated into its own module, and the only visible API for outside driver code would be two functions to convert C types from/into it.

Point 2 code (especially the efun code) uses the conversion function described above. That function could also do the runtime checking for driver internal needs, for instance to maximum array widths/string lengths and so on.

I think that we have to do *a lot of* the work decribed above, just to support 64 bit C types. Introducing a new, non-transparent integral type would be kind of unexplainable to the user and originated in the driver being unable to distinct between different numeric datatypes.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
164 [LDMud] Compilation, Installation minor always 2004-11-26 22:01 2009-10-06 04:43
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Location of telnet.h
Description: Short: telnet-Options
Type: Feature
State: Unclassified
From: Freaky <Freaky@UNItopia.rus.uni-stuttgart.de>
Date: Wed, 16 Dec 1998 01:53:59 +0100
X-Mailer: Mutt 0.95i

Hi,

Waere es in comm.c Zeile 77 nicht sinnvoller '#include <arpa/telnet.h>' zu
verwenden?
Eine Kopie irgendeines Telnet-Headerfiles mitzuliefern, ist wohl nicht die
beste Idee...
Weiterhin, wuerden dadurch auch wesentlich weniger 'Unknown telnet option'
Fehlermeldungen kommen.

Lars Duening:
> > Waere es in comm.c Zeile 77 nicht sinnvoller '#include <arpa/telnet.h>' zu
> > verwenden?
>
> Gekoppelt mit einem Test in configure, ob telnet.h auch wirklich dort zu
> finden ist.
>
> Die Kopie des telnet.h koennte dann nach hosts/ wandern fuer die
> Extremfaelle.

Im UNItopia-Logfile taucht sowas dauernd auf:

 Anzahl Fehlermeldung
    726 Unknown telnet option Will 39
    619 Unknown telnet option Will 36
    564 Unknown telnet option Will 35
    157 Unknown telnet option Do 200
     76 Unknown telnet option Wont 35
     74 Unknown telnet option Will 37
     26 Unknown telnet option Will 38
     26 Unknown telnet option Do 38
     25 Unknown telnet option Dont 200
      2 Unknown telnet option Wont 36
      2 Unknown telnet option Wont 170

Ciao
                Freaky
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001492)
zesstra   
2009-10-06 04:34   
In theory a nice idea, but we need a copy or a partial copy in the mudlib. So if we use <arpa/telnet.h>, we have to create the telnet.h for the mudlib on-the-fly when starting the mud. Or do you see other possibilities?

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
160 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-26 20:43 2009-10-06 04:22
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Extend the capabilities of closure evaluation
Description: Short: Extension of the capabilities of closure operators.
Date: 981202
Type: Feature
State: Unclassified
From: Zwirch

Zwirch@PK-Mud tells you: noch eine andere idee zu closures: ist es moeglich,
die binaeren operatoren #'+, #'&& usw. auf beliebig viele parameter zu erweitern,
so dann man zb mit apply(#'+, array) ein array von zahlen aufsummieren koennte
oder etwas in der art ({#'+,"text1",'x,"text2"}) klappen wuerde

Note: With a better LPC compiler this could be extended to normal LPC.
Statements like a+"x"+b+"y" could be made more efficient because the
result string could be allocated to the right size in the first place.
Maybe an instruction F_ADD_MULTI <numarg>?

The '+' operator could compile to a different VM instruction than the #'+
closure (right now its the same).
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000240)
_xtian_   
2004-12-07 07:28   
for lambda-operators: this would be useful indeed

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
298 [LDMud 3.5] LPC Compiler/Preprocessor feature N/A 2004-11-27 01:01 2009-10-06 04:16
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: const parameters
Description: Short: const parameter
From: Markus Peter
Date: 2002-08-13
Type: Feature
State: New

Die andere Sache waer von der Prioritaet her eher niedriger, mehr ein
nice to have: Es waer schoen, einen "const" modifier oder aehnliches bei
der Parameteruebergabe zur Verfuegung zu haben, der _alle_ Schreibzugriffe,
also auch Schreibzugriffe auf in arrays/mappings enthaltene References
verhindert, und zwar mit einem Error, so dass ich einer Funktion etwas
uebergeben kann, und sicher weiss, dass es nicht veraendert wird, ohne
einen deep_copy zu machen. In wiefern das mit der Struktur des Drivers
umsetzbar ist, weiss ich nicht, bin mit dem Source leider nicht sehr
vertraut.

-- It might be done using special const-LVALUEs, but it's almost easier to
rewrite the LPC compiler. But the same mechanism could be used for
'const references' in general, and for opening up variables to inheriting
classes for read-only access (like Oberon's '+' visibility).
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000235)
_xtian_   
2004-12-07 06:55   
I am very much in favor of all ideas involving "const", "&"-parameters, etc, as this would greatly be of help in maintaining consistency and stability in large libraries. (error exclusion by good design)
Having always to do copy() / deep_copy() on referenced variables does take up a lot of ressources, just to prevent the possibility of misuse.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
292 [LDMud 3.5] LPC Compiler/Preprocessor feature N/A 2004-11-27 00:56 2009-10-06 04:16
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Rething the mapping += mapping semantics
Description: Short: Rethink the 'mapping += mapping' semantics.
From: Lars
Date: 2002-05-07
Type: Feature
State: New

'mapping += mapping' should work like repeated calls to m_add(): the width of
the destination mapping is unchanged (unless generic empty mapping), the width
of the data added will be adjusted.

Possible way: + and += keep sizes and fail on size mismatch (with special
consideration of the empty mapping); | and |= merge even mappings is different
size.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
170 [LDMud] Efuns feature N/A 2004-11-26 22:09 2009-10-06 04:02
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: New efun: substitute_string()
Description: Short: new efun substitute_string()
From: Dave Setty <garpoz@locallink.net>
Date: Thu, 10 Dec 1998 02:03:04 -0500
Type: Feature
State: Unclassified
See also: f-020404

I've also got some various patches around that I'd like to see in there.
Lars, if you're interested in any of this let me know...
1) subst(), which is similar to MudOS's replace_string() which in turn
   is a more refined version of the old implode(explode()) trick. Mine
   can take two arrays or a mapping of search/replace pairs though.

--- Doomdark:
If I'm not mistaken, this is similar to 'substitute_string()'-efun
I made, which takes 2 string arrays to define the strings to replace.
It can be found from 'bugs/doomdark/strutil.c'-file from the ldmud-3.2.5
if you are interested. The extra arguments (min and max length
of the aliases to substitute) are just for optimizing the speed; also,
the first array is expeceted to be sorted to allow binary search of
the substitutions. Finally, the substitution is done by scanning the
whole string just once, and by using a static replace buffer (no mallocs
except for one used for mallocing room for the returned string, _if_
any substitutions were made). All in all, I tried to do a somewhat
optimized version which could be used for alias subsitution in command
strings; since this is called for every command players enter, it
should be made as fast as possible.
----

Suggestion by Matthew Julius:
varargs string strsubst(string, string|mapping|string*, string|string*)
  String replacement/substitution...
  Examples,
    strsubst("abc", "ab", "1") == "1c"
    strsubst("abc", ({ "a", "b" }), ({ "1", "2" })) == "12c"
    strsubst("abc", ([ "a": "1" ])) == "1bc"
    strsubst("abc", ({ "d" }), ({ "1" })) == "abc"
  The Timewarp mudlib has historically called this subst().

Or call it strreplace():

strreplace("abcdef", "cd", "x") -> "abxef"
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: doomdark-strutil.tar.gz (2,342 bytes) 2004-11-26 22:09
http://ldmud.eu/file_download.php?file_id=21&type=bug
p-990417-1.gz (1,076 bytes) 2004-11-27 01:21
http://ldmud.eu/file_download.php?file_id=32&type=bug
Notes
(0000224)
lars   
2004-11-27 01:21   
p-990417-1: Daniel Sloan's take on this.

Short: New efun replace_string()
From: Daniel Sloan
Date: 990410
Type: Patch
State Unclassified

diff-replace : A diff for the efun 'replace_string()', which does the same as
               implode(explode(X, Y), Z);, but does it faster and without
               creating an array, of course :-)

MudOS uses a very efficient algorithm for it.
(0000244)
Bardioc   
2004-12-11 19:49   
Hmm, i'm not sure, but cant this be done by regreplace() in a very efficient manner too? Actually replace_string() as known from MudOS allows to replace several strings at once in a easy way. This can be done via regreplace() to, but with regular expression syntax which is not that obvious.
(0000248)
menaures   
2004-12-12 05:51   
We use regreplace to convert umlauts and other characters to ascii. All player input goes through this conversion. It's really fast since it's just a single call to regreplace. (A replacepattern closure gets the replacement characters out of a mapping). No need for a new EFun there. But in this scenario, the regular expression is static (and most likely cached by the driver) and replacement mapping/closure are static too, so there really isn't much to do.

Making strsubst()/substitute_string() a simul efun which uses regreplace would be much more difficult to do, because you have to both escape and (in the case of mappings) sort the input strings.

Of course you can just use regreplace directly, but that requires knowledge of regexp. It's like saying we don't need inline closures, we have lambda. ;-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
215 [LDMud 3.5] Runtime feature N/A 2004-11-26 23:09 2009-10-06 03:55
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Output hook
Description: Date: Fri, 21 Jan 2000 14:47:12 +0100 (MEZ)
From: Holger Kremss <jur94ewp@studserv.uni-leipzig.de>
Short: Output-Hook
Type: Feature
State: New


Hi Lars!

Ich haette mal ne Bitte und die Frage, ob es moeglich waere, sowas
einzubauen. Und zwar haette ich gerne ne Applied-Funktion, oder besser
natuerlich nen Driver-Hook, der alles bekommt, was ein Spieler an text
gesendet bekommt. Also im grund so aehnlich, wie das catch_tell und
catch_msg machen, aber eben unmittelbar vor der Ausgabe an den Socket
und fuer ALLEN Text. Und zwar waere das ne Moeglichkeit, Umlaute zu
filtern, die bestimmte Leute auch heute noch nicht auf ihren Terminals
sehen koennen. Also der Hook wuerde zum Beispiel folgendes machen:

    (string)str=player->modify_output(str);

In modify_output wuerde man dann alle 'umlaute' und 'sz' umwandeln, so
dass der Spieler eben 'ae' und 'ue' statt den Umlauten bekommt. Ich hab
mich im WL immerwieder dafuer eingesetzt, Umlaute zugaenglich zu machen,
aber da einige leider immernoch Terminals haben, die damit nichts anfangen
koennen oder englische Consolen usw, wo sie die auch nichtmal tippen
koennen, waere das eine Moeglichkeit. Ich habe mit catch_tell() und
catch_msg() rumexperimentiert und festgestellt, dass da immer einiges
nicht ankommt. Und zwar all die tell_object() die im Spieler erzeugt
werden. Und das sind in unserer Lib sehr viele. Eine andere Moeglichkeit
gibt es leider nicht. Und die gesamte Lib umschreiben, dass man mit
catch_tell und so arbeiten kann, darauf hab ich ehrlich gesagt keine Lust
*stoehn*. Waer doch bestimmt simpel so einen Hook (analog modiy_command)
zu machen, oder? Und bestimmt auch nicht zu viel Aufwand...

Leider hab ich die aktuellsten Driver-Sourcen nicht hier, aber ich denke
mir, alle Textausgaben werden an einer einheitlichen Stelle gemacht. Wenn
es doch eine Moeglichkeit jetzt schon gibt, die mir entgangen ist, dann
waer ich ueber jeden Tip dankbar. :-)

Danke und Byebye!

Holger


Hi Lars.

Ich haette noch einen Vorschlag zu meiner letzten Mail. Ich hab mir
nochmal gedanken gemacht, wie das umlaute-parsen am besten zu realisieren
ist und bin drauf gekommen, dass es besser ist, die Eingabe des Spielers
umzuwandeln in Spezialzeichen und erst bei der Ausgabe das wieder
umzuwandeln. Das ist deshalb besser, weil der Umlaut ue nur ein zeichen
lang ist, wohingegen 'ue' 2 Zeichen lang ist und dann kommen unsere ganzen
zeilenumbrueche durcheinander. Also bei der Eingabe ue -> "u und dann bei
der Ausgabe dann Spieler-individuell in Umlaute oder eben ue ae oe
umwandeln. Dann werden die Umbrueche nur vielleicht kuerzer, nicht etwa
laenger und fuer die strlen-spezifischen Sachen muss ich mir dann auch
noch was einfallen lassen. ;-)

Lange Rede kurzer Sinn: Neben dem output-Hook waer noch ein Input-Hook
schoen. Also wo alles veraendert werden kann, was reinkommt. Nicht nur
Commands (modify_command()) sondern auch all das, was an input_to() geht
usw. Eben _alles_.

Also meine Bitte nochmal zusammengefasst. 2 Hooks, einer fuers
Input-Modifizieren und einer fuer Output-Modifizieren. :-) Wenn Du keine
Lust hast, das zu machen, muss ich mich vielleicht doch mal selbst
ranwagen, aber ich glaub das koennte dann dauern...

Holger@Wunderland


Subject: H_MODIFY_OUTPUT
From: Thomas Feldmeier <tf4@informatik.uni-ulm.de>
Date: Wed, 17 Mar 1999 17:26:50 +0100 (MET)
Type: Feature
State: Acknowledged.

H_MODIFY_OUTPUT

Optionaler Hook zum Modifizieren jeder Textausgabe,
bevor der Spieler sie sieht.
Kann eine unbound closure oder ein String sein.

Ist der Hook eine Closure, wird er aufgerufen als
  string <closure>(string output).

Ist der Hook ein String, wird eine Funktion mit diesem Namen
in dem Spieler aufgerufen:
  string <name>(string output).

this_player() enthaelt den Spieler, der die Textausgabe sieht.

Bevor ein Text an einen Spieler gesendet wird, wird der Hook
mit diesem Text als Paramter aufgerufen. Ist der Rueckgabewert
des Hooks ein String, so wird dieser String anstelle des Textes
an den Spieler gesendet.

--------------------------------------
Als Vorlage zum H_MODIFY_HOOK koennte man H_MODIFY_COMMAND nehmen
(aehnliche Parameteruebergabe)

Ich habe mir gedacht, dass in comm.c, add_message() geaendert wird:
bevor die message umgewandelt wird (also die /n zu /r/n geaendert usw.),
wird ein Hook aufgerufen, der die Message aendern koennte.
(vielleicht an der gleichen stelle, an der auch gesnoopt wird?)

Damit wird wohl jedes printf(), write() usw. auch einen eigenen Aufruf des
Hooks bewirken. Nur binary_message( ,0) nicht.

Der Hook ist ja gedacht, um alle ausgaben automatisch umzubrechen, bei
beruecksichtigung der ansi-steuerzeichen. pro write usw. wuerde also
zusaetzlich ein hook ausgefuehrt werden, der dann ein paar mapping-
operationen macht und ein aufruf von terminal_colour. ich schaetze, die
cpu-last waere noch ok.

                                                     Zora
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: pkmud-outputhook.diff (7,381 bytes) 2004-11-26 23:13
http://ldmud.eu/file_download.php?file_id=23&type=bug
Notes
(0000215)
lars   
2004-11-26 23:13   
Zwirch implemented the hook for PKMud.
(0001304)
zesstra   
2009-09-26 19:45   
I thought, that catch_tell() receives every message sent to an interactive and only the interactive object itself can sent messages directly to its socket. So, isn't the output hook superfluous now?
(0001313)
Sorcerer   
2009-09-27 14:48   
When this bug was created, tell_object() did not yet call catch_msg(). This was introduced with issue 354 one year later.
So probably this issue is resolved by now.
(0001337)
Gnomi   
2009-09-29 13:00   
But on the other hand I think an interface via input and output hooks might be much cleaner than the call of catch_tell (and having a simul_efun for input_to to catch umlauts). Without an output hook the driver could still call catch_tell as a default.
(0001353)
Coogan   
2009-09-29 17:24   
In Tubmud, all input from resp. output to a player is sent through encoding functions to ensure all players are able to communicate with each other. This way it's also possible for player A to use UTF8, player B to use LATIN1 and C to use plain ascii, and umlauts and other characters are converted correctly.
This is of course combined with proper linebreaks even for coloured messages.

Shortly, it is possible to handle that real reason behind this issue completely by the mudlib.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
328 [LDMud] LPC Compiler/Preprocessor feature always 2004-12-23 14:18 2009-10-06 03:52
Reporter: lars Platform:  
Assigned To: OS:  
Priority: low OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Introduce NaN integers
Description: When handling numeric overflows (-0x100000000), the driver doesn't really handle these but instead maps them to INT_MIN or INT_MAX.

A better way would be to introduce NaN values for +/- infinity.

This is probably most easily done if the compiler is rewritten to use ASTs and to delay the number parsing until the very last moment.

Alternatively, implement long numbers and let the driver automatically select the best implementation.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001487)
zesstra   
2009-10-06 03:52   
At runtime the driver raises an error upon numeric overflows. Couldn't we do the same during compiletime when the compiler stumbles upon a literal number exceeding the limits?

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
677 [LDMud 3.2] Runtime crash always 2009-09-19 15:06 2009-10-06 03:32
Reporter: Coogan Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.16  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: starting an SSL-secured connection crashes the driver
Description: Running on Debian stable and compiled with SSL-support (openssl), starting an SSL-connection on the mud-SSL-port crashes the driver, dumping a core file.

coogan@mud:/home/tubmud/mudlib$ telnet-ssl -z ssl mud.tubmud.de 7682
Trying 85.214.44.4...
SSL_connect: Success
coogan@mud:/home/tubmud/mudlib$

LDMUD-3.2.14 works fine. The handshake code looks a bit different to 3.2.14, so I think this is a regression.
Tags:
Steps To Reproduce:
Additional Information: tubmud@mud:~/mudlib$ gdb ../mudbin/driver-3.2.16 core.3917
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...

warning: core file may not match specified executable file.
Reading symbols from /lib/libnsl.so.1...done.
Loaded symbols for /lib/libnsl.so.1
Reading symbols from /lib/libm.so.6...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libcrypt.so.1...done.
Loaded symbols for /lib/libcrypt.so.1
Reading symbols from /usr/lib/i686/cmov/libssl.so.0.9.8...done.
Loaded symbols for /usr/lib/i686/cmov/libssl.so.0.9.8
Reading symbols from /usr/lib/i686/cmov/libcrypto.so.0.9.8...done.
Loaded symbols for /usr/lib/i686/cmov/libcrypto.so.0.9.8
Reading symbols from /usr/lib/libz.so.1...done.
Loaded symbols for /usr/lib/libz.so.1
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /lib/libdl.so.2...done.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /lib/libnss_files.so.2...done.
Loaded symbols for /lib/libnss_files.so.2
Core was generated by `/home/tubmud/mudbin/driver -Mkernel/master -DTUBMUD=1 -D__START_TIME__="_S_T_20'.
Program terminated with signal 11, Segmentation fault.
[New process 3917]
#0 0x00a4782c in sk_value () from /usr/lib/i686/cmov/libcrypto.so.0.9.8
(gdb) bt
#0 0x00a4782c in sk_value () from /usr/lib/i686/cmov/libcrypto.so.0.9.8
0000001 0x00fa08b8 in ssl3_accept () from /usr/lib/i686/cmov/libssl.so.0.9.8
0000002 0x00fb8d7a in SSL_accept () from /usr/lib/i686/cmov/libssl.so.0.9.8
0000003 0x00faae70 in ssl23_get_client_hello ()
   from /usr/lib/i686/cmov/libssl.so.0.9.8
0000004 0x00fab768 in ssl23_accept () from /usr/lib/i686/cmov/libssl.so.0.9.8
0000005 0x00fb8713 in SSL_do_handshake () from /usr/lib/i686/cmov/libssl.so.0.9.8
0000006 0x080bf38d in tls_continue_handshake (ip=0xa8ad054) at pkg-tls.c:774
0000007 0x08063977 in get_message (buff=0xbfcd3f38 "") at comm.c:2896
0000008 0x08054f81 in backend () at backend.c:537
0000009 0x080a3805 in main (argc=14, argv=0xbfcd58c4) at main.c:517
(gdb)
Attached Files: 0001-Register-our-own-allocator-functions-with-openssl.patch (1,724 bytes) 2009-10-04 16:36
http://ldmud.eu/file_download.php?file_id=253&type=bug
Notes
(0001279)
zesstra   
2009-09-19 15:55   
Just a spontaneous shot in the dark: something like this (segfaults in used libraries) may happen, if our memory allocator does not replace the system allocator reliably, openssl uses (partially) the system allocator and the two interfere. It seems unlikely in this particular case, but it is not much effort: You may just try --enable-malloc-sbrk=no and see if that changes anything.
(0001444)
zesstra   
2009-10-03 19:23   
I just saw that there are references in the net to CRYPTO_malloc_init(), CRYPTO_set_mem_functions(), CRYPTO_set_mem_ex_functions(), CRYPTO_set_locked_mem_functions(), CRYPTO_set_locked_mem_ex_functions(). So there is a way to tell openssl to use a custom memory allocator. Which we use but don't tell openssl. Unfortunately - and quite typical for openssl - documentation seems to be missing. Or better: use the source, luke... *argl*
(0001445)
zesstra   
2009-10-04 05:22   
I had a look at Coogans Coredump. Relevant stacktrace with data:
(gdb) bt full
#0 sk_value (st=0x84e5060, i=4) at stack.c:310
No locals.
0000001 0x00e54888 in ssl3_accept (s=0x84e5060) at s3_srvr.c:393
    buf = <value optimized out>
    l = <value optimized out>
    Time = 1254609144
    cb = (void (*)(const SSL *, int, int)) 0
    num1 = <value optimized out>
    ret = <value optimized out>
    state = 8544
    skip = <value optimized out>
0000002 0x00e6cd4a in SSL_accept (s=0x84e5060) at ssl_lib.c:850
No locals.
0000003 0x00e5ee40 in ssl23_get_client_hello (s=0x84e5060) at s23_srvr.c:568
    buf_space = "\200d\001\003\001\000K\000\000\000\020"
    p = (unsigned char *) 0x84e9b91 ""
    d = (unsigned char *) 0x84da0cd ""
    i = <value optimized out>
    csl = 75
    cl = <value optimized out>
    n = 100
    j = <value optimized out>
    type = 2
0000004 0x00e5f738 in ssl23_accept (s=0x84e5060) at s23_srvr.c:203
    buf = (BUF_MEM *) 0x84d7ae8
    Time = 1254609144
    cb = (void (*)(const SSL *, int, int)) 0
    ret = <value optimized out>
    state = 139350112
0000005 0x00e6c6e3 in SSL_do_handshake (s=0x84e5060) at ssl_lib.c:2085
    ret = 0
0000005 0x00e6c6e3 in SSL_do_handshake (s=0x84e5060) at ssl_lib.c:2085
    ret = 0
0000006 0x080dd7df in tls_continue_handshake (ip=0x84d9400) at pkg-tls.c:774
    n = 139350112
    ret = 1
0000007 0x080ddd38 in f_tls_init_connection (sp=0x8124e38, num_arg=3) at pkg-tls.c:1012
    session = (SSL *) 0x84e5060
    argp = (svalue_t *) 0x8124e38
    ret = 0
    obj = (object_t *) 0x84b3f84
    ip = (interactive_t *) 0x84d9400


char *sk_value(const STACK *st, int i)
{
  if(!st || (i < 0) || (i >= st->num)) return NULL;
  return st->data[i];
}
It crashes upon st->data[i].
st is:
$3 = {num = 769, data = 0x2000, sorted = 15213344, num_alloc = 139295540,
  comp = 0x84d7be8}
Clearly, 0x2000 is not mapped into the process memory, and the values for num_alloc and sorted look rather strange, num probably as well. The address 0x84d7be8 should be a function pointer to an openssl function. But as far as I can see, they are mapped somewhere around 0x00e.... and 0x84d7be8 is part of the heap.
Note that the given address for the st is 0x84e5060 which is the address of the SSL context/session. And that is:
(gdb) print *s
$1 = {version = 769, type = 8192, method = 0xe82320, rbio = 0x84d7b34, wbio = 0x84d7be8, bbio = 0x84d7be8, rwstate = 1, in_handshake = 2, ...

line 393 in s3_srvr.c is
  ret=ssl3_send_certificate_request(s);
That one actually iterates over a stack in the session and calls sk_value (although it is called differently, these openssl people love playing tricks with defines). But strange enough, I would expect ssl3_send_certificate_request(s) to be in the stacktrace...

The stack is extracted from the SSL context by SSL_get_client_CA_list(). That one should return s->ctx->client_CA which is:
(gdb) print s->ctx->client_CA
$4 = (STACK *) 0x832fc58
(gdb) print *(s->ctx->client_CA)
$5 = {num = 1, data = 0x0, sorted = 0, num_alloc = 1886220131, comp = 0x8007461}
That would make more sense, but it is obviously not the address given to sk_value().

So... I don't know what openssl exactly does here... BTW: I assume, you use 0.9.8g-15+lenny5?
(0001448)
zesstra   
2009-10-04 13:01   
I checked this afternoon with tubmuds settings and tubmuds public mudlib on MacOS 10.6 and Debian Lenny.
Debian Lenny: crash as Coogan described (openssl-0.9.8g-15+lenny5)
MacOS x86_64: driver not working at all
MacOS i386: no crash, TLS works fine. (openssl-0.9.8)
(0001449)
zesstra   
2009-10-04 15:03   
The stack used by the sk_value() which segfaults is tls_session->ctx->client_CA, which is als context->client_CA in pkg-tls.c, created during tls_global_init() by SSL_CTX_new().
After creation it is
(gdb) print *context->client_CA
$20 = {num = 0, data = 0x931abf8, sorted = 0, num_alloc = 4, comp = 0}

When we get a new ssl session in f_tls_init_connection(), that context contains already the wrong data:
   SSL * session = SSL_new(context); // line 978
(gdb) print *session->ctx->client_CA
$13 = {num = 30, data = 0x20003, sorted = 170242664, num_alloc = 2, comp = 0x28}

So somewhere between tls_global_init() and f_tls_init_connection this context gets somehow changed. I tried to find out more by using gdb's watchpoints, but that seems to slow it down far to much. :-(
(0001450)
zesstra   
2009-10-04 16:21   
Mhmm:

Hardware watchpoint 9: ((struct stack_st *) 154250276)->num
Old value = 150
New value = 978082211
0xb7db5032 in BN_lshift (r=0x9322a78, a=0x9322a78, n=320) at bn_shift.c:151
1: *(struct stack_st *) 154250276 = {num = 978082211, data = 0x35b5d4c7,
  sorted = -557861449, num_alloc = 1591931666, comp = 0}
(gdb) list
146 f=a->d;
147 t=r->d;
148 t[a->top+nw]=0;
149 if (lb == 0)
150 for (i=a->top-1; i>=0; i--)
151 t[nw+i]=f[i];
152 else
153 for (i=a->top-1; i>=0; i--)
154 {
155 l=f[i];
(gdb) bt
#0 0xb7db5032 in BN_lshift (r=0x9322a78, a=0x9322a78, n=320) at bn_shift.c:151
0000001 0xb7dd5dc8 in DSA_generate_parameters_ex (ret=0x931a1cc, bits=1024, seed_in=0x0,
    seed_len=<value optimized out>, counter_ret=0x0, h_ret=0x0, cb=0xbf9685f4)
    at dsa_gen.c:236
0000002 0xb7dd7b43 in DSA_generate_parameters (bits=1024,
    seed_in=0xbf968644 ";-) :-( :-) :-( $\223\021\b$\223\021\b9\223\021\b$\223\021\bN\223\021\b\003", seed_len=20, counter_ret=0x0, h_ret=0x0, callback=0, cb_arg=0x0)
    at dsa_depr.c:99
0000003 0x080df54b in set_dhe1024 () at pkg-tls.c:130
0000004 0x080dfcec in tls_global_init () at pkg-tls.c:500
0000005 0x080b6a62 in main (argc=9, argv=0xbf9699d4) at main.c:390

(gdb) print *a
$39 = {d = 0x931abf8, top = 5, dmax = 16, neg = 0, flags = 0}


And then another:
Hardware watchpoint 9: ((struct stack_st *) 154250276)->num
Old value = 978082211
New value = 0
0x0804f4fa in _allocate_array (n=6, file=0x8107020 "interpret.c::allocate_uninit_array",
    line=12370) at array.c:271
271 *svp++ = const0;
1: *(struct stack_st *) 154250276 = {num = 0, data = 0x35b5d4c7, sorted = -557861449,
  num_alloc = 1591931666, comp = 0x931abdc}
(gdb) bt
#0 0x0804f4fa in _allocate_array (n=6,
    file=0x8107020 "interpret.c::allocate_uninit_array", line=12370) at array.c:271
0000001 0x080948a0 in eval_instruction (first_instruction=0x94618cf "R\001\001\033",
    initial_sp=0x8129a50) at interpret.c:12370
0000002 0x080a8cbf in apply_low (fun=0x92aa750 "inaugurate_master", ob=0x932afec, num_arg=1,
    b_ign_prot=1) at interpret.c:21684
0000003 0x080a8f15 in sapply_int (fun=0x92aa750 "inaugurate_master", ob=0x932afec,
    num_arg=1, b_find_static=1) at interpret.c:21796
0000004 0x080a94bd in apply_master_ob (fun=0x92aa750 "inaugurate_master", num_arg=1,
    external=1) at interpret.c:22084
0000005 0x080b6e12 in main (argc=9, argv=0xbf9699d4) at main.c:483

And then it goes on and on and on with changing st->num, before finally transfer_svalue_no_free_spc() writes the 'final' data into it.

So somehow that memory range gets just used twice, because openssl gets it from a different allocator than our own. That is confirmed by undefining SBRK_OK in machine.h before make.

Sooooo.... Workaround for Coogan: disable SBRK_OK. Unfortunately, in 3.2 that does not work with --enable-malloc-sbrk=no which I mentioned earlier, because that does not exist anymore. Und obviously, our detection whether it is safe to use SBRK_OK and replace the system allocator is again not working.

I guess, the more libraries we optionally use, the more severe our problems with sbrk and replacing the system allocator get. I suggest to change our defaults in 3.3. and 3.5 (but that is a different issue).
(0001451)
zesstra   
2009-10-04 16:41   
Coogan: please apply the attached patch and try on your system. I believe it will solve the immediate problem. At least it does on my test system.


BTW: Even the OpenSSL developers are sceptical, that all memory allocation and deallocation in openssl takes place by using the functions supplied by the user with CRYPTO_set_mem_functions(). (The function is even undocumented.) So I believe, there may be more issues like this.
The only proper and robust fix would be
a) not to use SBRK_OK and replace the memory allocators or
b) use mmap() for allocating memory.

b) is only possibly in 3.3 and 3.5 and a) increases memory allocator overhead because our allocator then uses the system allocator for getting memory. It is also not that easy, because it can't be configured by configure in 3.2 (but in 3.3 and 3.5).
(0001469)
zesstra   
2009-10-05 16:27   
OK. For some reason, my idea yesterday was just plain wrong. Don't know why my test didn't crash, maybe I used the wrong binary. :-(

So, next gdb session today:
The client_CA stack is at 0x94594b4. I checked now all allocations and deallocations and finally found:

Breakpoint 18, sfree (ptr=0x94594b4) at smalloc.c:1147
1147 if (bsize > SMALL_BLOCK_MAX)
(gdb) print context->client_CA
$27 = (STACK *) 0x94594b4
(gdb) bt
#0 sfree (ptr=0x94594b4) at smalloc.c:1147
0000001 0x080f73d4 in xfree (ptr=0x94594b4) at smalloc.c:1245
0000002 0x080f88cd in pfree (p=0x94594b4) at smalloc.c:2891
0000003 0x080f89e2 in afree (p=0x94594b4) at smalloc.c:2987
0000004 0x080f988f in free (ptr=0x94594b4) at smalloc.c:3441
0000005 0xb7dc1cca in CRYPTO_free (str=0x94594b4) at mem.c:378
0000006 0xb7e2d925 in sk_free (st=0x94594b4) at stack.c:298
0000007 0xb7e2d979 in sk_pop_free (st=0x94594b4, func=0xb7e48880 <X509_NAME_free>)
    at stack.c:291
0000008 0xb7f01006 in SSL_CTX_set_client_CA_list (ctx=0x944febc, name_list=0x94594b4)
    at ssl_cert.c:549
0000009 0x080dd216 in tls_verify_init () at pkg-tls.c:395
0000010 0x080dd4c7 in tls_global_init () at pkg-tls.c:498
0000011 0x080b47ce in main (argc=9, argv=0xbf8a8914) at main.c:390

Ok... OpenSSL deliberately frees that stack.

static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,STACK_OF(X509_NAME) *name_list)
{
  if (*ca_list != NULL)
      sk_X509_NAME_pop_free(*ca_list,X509_NAME_free);
  *ca_list=name_list;
}
Yeah, it frees the old content before storing the new pointer.

Now the problem:
We do in tls_verify_init():
    stack = SSL_CTX_get_client_CA_list(context);
    if (trustdirectory != NULL) {
    SSL_add_dir_cert_subjects_to_stack(stack, trustdirectory);
    }
    if (stack != NULL) {
    SSL_CTX_set_client_CA_list(context, stack);
    }

So we set the old stack again. Now openssl frees the stack and stores the pointer to the stack it just free'd. No wonder that that stack is overwritten all the time. ;-)
(0001470)
zesstra   
2009-10-05 17:01   
I duplicated the fix for this issue in 3.3.x. This should now be fixed in r2755.
(0001484)
Coogan   
2009-10-06 03:10   
Please be aware, that this is a report against LDMud-3.2. A fix for 3.5 and/or 3.3 is nice but does not help me here.
As this seems to be a regression since 3.2.14, it should also get fixed in the 3.2 trunk.
(0001485)
Gnomi   
2009-10-06 03:32   
The last note was a little ambiguous. Zesstra took a fix for 3.3 and applied it to 3.2. So this bug is now fixed in the 3.2 trunk.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
176 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-26 22:17 2009-10-05 18:41
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: #pragma reserve_efun_names
Description: Short: #pragma reserve_efun_names
From: Matthew Julius <julius.2@wright.edu>
Date: Fri, 08 Jan 1999 16:29:08 -0500
Type: Feature
State: Unclassified

pragma to 'reserve' [s]efun names
  For example, the following code compiles fine,
    void go() {
      int member;
      member = member(map, 1);
      ...
    }
  Whereas this will not,
    #pragma reserve_efun_names
    void go() {
      int member;
      ...
    }
  This obviously should not affect overloading [s]efuns. This is also
  limited to compile time only.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001400)
zesstra   
2009-10-02 05:25   
Mhmmm. Using variables called like efuns irritates me as well, when reading code. Sometimes it even happens to me by accident, e.g. in case of min,max. So I would welcome it to optionally disallow that. Maybe even including it into 'pedantic'?
(0001401)
Largo   
2009-10-02 05:28   
Very good point. Agreed.
(0001478)
zesstra   
2009-10-05 18:41   
Mhmm. An issue concerning sefuns: they are more volatile than efuns and may appear and disappear even during an uptime. Should they be included in here?

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
166 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-26 22:04 2009-10-05 12:49
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Add args to load_object() et al
Description: Short: Add. args to load_object(), clone_object(), allocate()
From: Alfe
Date: Wed, 16 Dec 1998 21:11:51 +0100 (MET)
Type: Feature
State: Acknowledged

ah, another thing: i'd like an optional second argument to allocate(),
which should be the value to initially fill the array with. e.g.:
allocate(5,3.1) ==> ({ 3.1, 3.1, 3.1, 3.1, 3.1 }).

Implement something similar for clone_object() and (new) load_object(),
with the additional args passed to create().
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001319)
zesstra   
2009-09-27 18:39   
allocate() is already solved, so there is the issue about
load_object/clone_object(). Sounds not like a bad idea to me... On the other hand you can get nearly the same result by
ob = clone_object(bar);
ob->initialize(foo);
(0001454)
alfe   
2009-10-05 09:24   
(Last edited: 2009-10-05 09:26)
Hi Zesstra,

Sure, ob->initialize(foo) can be used as a workaround for the missing "parametrizability" of the constructor facility, but it has obvious drawbacks; e. g. you will have to ensure that initialize() is called exactly once before the object is used otherwise. And you cannot really prevent "using" an object if the usage is done by just putting it into a container, passing it to a library function or similar.

Mudlib programmers can, however, use a simul_efun which clones/creates and initializes objects and forbid the use of the efuns clone_object() and load_object().

It still is an open question what loading by calling ("/foo/bar"->bla()) should do in these cases, whether it can be prevented and the like.

(0001455)
alfe   
2009-10-05 09:28   
btw -- that issue is so old i didn't even remember reporting the issue :-}
(0001456)
zesstra   
2009-10-05 09:41   
I see your point. But you have to ensure the proper initialization also if you do it via create() in load_object()/clone_object(). And you can prevent moving an uninitialized object if you really want to (not the case that an object is passed around as argument, but sooner or later somebody will do something more with it).
I am not so happy with making load_object/clone_object/create varargs and accept arbitrary arguments however.
(0001460)
alfe   
2009-10-05 11:08   
(Last edited: 2009-10-05 11:09)
I wasn't talking about moving it (in a mud sense) which you can prevent (but then the prevent_move() lfun needs to take care of this special case as well). Actually, I was just talking about putting it into a container like a mapping or an array.

Hard to find bugs are the reason why all other object-oriented languages (at least the ones I know like C++, Python, Java, Smalltalk, ...) allow creation also with parameters.

Anyway, what are the reasons against my proposal (besides being something utterly new in the 20-year-old LPC history which I followed nearly from its beginning)? I see no reason not to simply allow additional arguments. If the mudlib does not want to use it, so be it :-}

(0001466)
fufu   
2009-10-05 12:33   
MudOS has such functionality since 1995 - it calls create() with any extra arguments passed to clone_object(). Note that this is a bit simpler in MudOS' case because there are no create hooks.

I'm not opposed to adding this feature to ldmud, although I believe that it's of limited utility.

I think that the implicit object creation by call_other() is a good reason against extending the feature to load_object().
(0001467)
bubbs   
2009-10-05 12:49   
Please add another vote in favour. If available, this would allow a cleverly designed core object to be instantiated very simply;

e.g. object sword = clone_object(WEAPON, "iron shortsword");

Could pass the additional params to the hook, which could ignore them or pass them to the "create" function as appropriate. i.e. unless the mudlib tweaked the hooks, no changes would be evident.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
687 [LDMud] Portability minor N/A 2009-10-04 18:01 2009-10-05 11:48
Reporter: zesstra Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: RfC: Change defaults concerning MALLOC_SBRK / SBRK_OK
Description: Several of the crashes in the last 1-2 years were caused by memory corruption, because shared libs used different allocators then the driver, although we tried to replace malloc. These usually leads to a rather investment of time for hunting that bugs. I also believe, some of the crashes still not resolved, may be related to this.
(Side note: sbrk/brk() are anyway not POSIX anymore.)

I suggest, that we do not replace the system memory allocator by default in the future. On systems where it does not work at all, our configure script detects it most of the times. But systems, where it basically works and suddenly breaks when some shared library is changed/added, are really a nuisance. And the more optional shared libraries we add in the form of pkg*.c, the worse it gets. Not all libs offer hooks for the allocator functions and some may not use them consistently. I don't believe, that we can invent any reliable form of detection in autoconf for all combinations.
If somebody really wants to use sbrk() and take the risk, he or she can explicitly enable it (but should be aware of a risk).

Suggestion:
3.5: disable MALLOC_SBRK / --enable-malloc-sbrk by default. The allocators can fall back to mmap(), which is available on most systems nowadays. Then we will not interfere with the system allocator, even if we don't replace malloc and some shared libs use the system allocator.
3.3: backport 0000680 and do as described for 3.5
3.2: well... I don't know. The only fall-back in this branch is to use the system allocator by default, which leads to an increased allocator overhead. But I still tend to do that.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001464)
zesstra   
2009-10-05 11:48   
Mhmm. I was a little bit to single-minded: even with mmap it can be dangerous if the replacement of the system allocator is incomplete.
a) if the shared lib uses the system malloc, but our free or vice versa
b) if the shared lib uses our malloc, the system realloc and our free
c) if some lib uses the system strdup() and that uses a non-replaced malloc.
d) if we replace malloc, realloc, free, but some lib uses valloc. In that case, valloc may allocate from the system (if it does not use our malloc) and the memory is free'd by calling our free(). This seems to me the most severe case, because we don't know, what allocation functions in addition to Posix may exist and be used by someone.

a) and b) don't seem very probable, but I don't know if we can rely on it.

So maybe it is just the best, to not replace even with mmap and just live with the fact, that our memory account does not account for memory used by shared libs...

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
682 [LDMud] Implementation feature N/A 2009-09-26 18:45 2009-10-05 09:33
Reporter: zesstra Platform:  
Assigned To: OS:  
Priority: low OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Auto-destructed / Auto-cleaned objects
Description: This idea is in my mind for quite some time now and I think, I should it record in finally here: A flag for an object which tells the driver to automatically destruct the object shortly after there is no (external) reference to that object.

This is especially related to the idea of 'light-weight' objects (nameless objects).

But there may be even a usage for normal clones. Imagine the situation a wizard clones and object and does not move it in some environment, because the move into the player/room/container fails and he doesn't check for that. In that case, the clone will leak and in practice just fill up memory (in former times, MG had hundred-thhousands of such leaked objects but since a number of years, clones of standard items (thing, weapon, armour, everything which should have player interaction) raise an error and self-destruct if they are without environment 2s after creation.

(Short digression to light-weight objects: They would have much less overhead in creation and function calls (call_other) than normal objects and could be used to implement structures like ring buffers efficiently, which is now not possible. An idea here would be to bind functions to data structures (e.g. mappings/structs), but there are only a preliminary and rough ideas about such light-weight objects.)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001311)
_xtian_   
2009-09-27 03:44   
In my mind, this is what structs should be used for, i.e. implementing complex data structures in a way you would do with C (not C++).
Something like:
  get_next_ring_buffer( struct ring_buffer_t )
Of course this doesn't offer the features of OOP, but it is feasible atm.

Note: This has some problems: Ex: Ring buffers leak memory due to the circular self-reference in the list.

Also: In our lib we handle the case of catching moves that went wrong and didnt move the object at all with a call_out(, 0).
(0001328)
zesstra   
2009-09-28 15:51   
We also check objects without environment, although this is not the most elegant way.

Using structs for ringbuffers is fine, I had such an implementation for playing around.
But something like object buf=clone("/std/ring_buffer"), buf->add(foo); would be interesting, if you could spare the huge overhead it currently has. That would suggest a very tight binding between code/behaviour and data of the entity.
I think, there was once the idea of binding closures to structures which might be executed/called by struct->fun().

BTW: the strategy of inheriting a ringbuffer struct and lfuns manipulating it: in my experience, the function call overhead was so large, that it was faster to perform a arr = ({foo}) + arr[1..]; for every addition than to actually call something like RingBufferPut(buf, foo); I then abandoned the project (although the code still lies around somewhere).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
684 [LDMud 3.3] Efuns minor N/A 2009-10-01 18:33 2009-10-04 10:17
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.720  
Summary: get_dir(): listing directory contents does not work according to documentation
Description: The get_dir() efun has a few inconsistencies.
One is: get_dir("/",...) returns the _contents_ of the root directory. get_dir("/some/other/path/",...) will not return the contents, but the directory "/some/other/path" itself.
Additionally, the man page states:
      To query the content of a directory, use the directory name with a
      trailing '/' or '/.', for example get_dir("/path/."). Use the
      directory name as it is to get information about the directory itself.
But neither a trailing '/' nor a trailing '/.' does work, because they are stripped off by get_dir. You have to use "/some/other/path/*" for path not being the root dir of the mudlib.

So, unfortunately, changing the behaviour to be a) consistent and b) according to documentation will probably lead to compatibility problems, as Gnomi already pointed out in a private discussion.

So, I want to record the issue here and document the decision: adapt the behaviour to the documentation or change the documentation to the inconsistent behaviour?
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001430)
fufu   
2009-10-02 15:01   
I believe the efun works as described, but with a twist: The path being used is the one returned from valid_read() in the master. That fact should be documented.

(In our mudlibs, valid_read() does path normalization, 'breaking' get_dir)
(0001441)
zesstra   
2009-10-03 18:33   
Very good point, that seems to be the reason. *argl*
For "/" it works, because that is then stripped to "" and "" is converted to "." which is interpretated as the mudlib root directory itself.
I guess, I have to fix some mudlib, there is no real reason not to conserve the trailing /. ;-)
But I agree, that the documentation has to be improved.
(0001446)
zesstra   
2009-10-04 10:17   
I added a note about the path normalization to the manpage in r2752 and r2753.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
206 [LDMud] Runtime feature N/A 2004-11-26 22:52 2009-10-02 10:06
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Error handling inside a hook
Description: Short: Error handling within a catch.
From: Michael Sporn
Date: 990629
Type: Feature
State: Unclassified

Immediate error handling should be independent from a catch(), as too
many people forget to handle errors returned by a catch.

Maybe a modification to runtime/heartbeat/log_error, giving an extra
parameter 'is_caught', and if is_caught is true, the return value decides
if the driver prints a traceback or not before doing the actual catch.

In general, the error and diagnostic handling is much too confused.

--- See the discussion on amylaar-users in November '2000. The error routine
could be set by a hook, and if not set, the driver could fall back to the
old routines.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001307)
zesstra   
2009-09-26 19:56   
I agree, that catch() was often (and is still sometimes) bad, because the error does not get visible except for the people reading the debug log (not many). The ;publish modifier changes that to a degree. But maybe a possibility to implicitly use ;publish by default, enabled by some compiletime, commandline option or pragma...?
(0001314)
Sorcerer   
2009-09-27 14:53   
If you do not want to introduce an new pragma - I consider 'pedantic' to be quite suitable for such a behaviour.
(0001338)
Gnomi   
2009-09-29 13:06   
What about the other catch modifiers. Should a mudlib or program be able to change their default, too? (We have a default statement, might use that?)
(0001360)
zesstra   
2009-09-30 16:11   
Default statement? Uh, never read about that. :-(
If we enable to change the default behaviour, we may also introduce log and nopublish in addition to nolog and publish to override default behaviour, I guess.
BTW: related is the wish to disallow to use certain modifiers, e.g. disallow nolog. I think, there was/is somewhere an issue dealing with that.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
202 [LDMud] Efuns feature N/A 2004-11-26 22:43 2009-10-02 09:55
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: New efuns: previous_program()
Description: Short: New efun: previous_program(), program_stack()
From: Daniel Sloan <sloand@alphalink.com.au>
From: Michael <virus@mpinet.net>
Date: Tue, 23 Mar 1999 15:29:14 +0000
Type: Feature
State: Unclassified

Maybe also an efun program_stack()?

Daniel writes:

A 'previous_program' efun, parallel to previous_object(). Real handy for
tracing certain things and working out where a call was *really* made from.
I've not implemented this in the current driver I use, only an old 3.1.2
driver =-)

Michael writes:

After looking through a DGD driver source code, there is something
similar to the previous_object() function, but called
previous_program(). I don't have that much knowledge of the DGD driver,
but from what I found, this previous_program() could be used as a good
base for making a better security system for alot of mudlibs.

Excerpt from kfun/std.c under the DGD src directory:

/*
 * NAME: kfun->previous_program()
 * DESCRIPTION: return the previous program in the function call chain
 */
int kf_previous_program(nargs)
int nargs;
{
    char *prog;
    register string *str;

    if (nargs == 0) {
        (--sp)->type = T_INT;
        sp->u.number = 0;
    } else if (sp->u.number < 0) {
        return 1;
    }

    prog = i_prev_program((int) sp->u.number);
    if (prog != (char *) NULL) {
        sp->type = T_STRING;
        str = str_new((char *) NULL, strlen(prog) + 1L);
        str->text[0] = '/';
        strcpy(str->text + 1, prog);
        str_ref(sp->u.string = str);
    } else {
        sp->u.number = 0;
    }
    return 0;
}

Think something like this would be viable for the LD project/driver?
I found the DGD driver from ftp.imaginary.com server if you wish to
follow up on it more.

-- Michael

Rodney writes:

> When you use extern_call() within a module which is inherited, it is
> difficult to tell when a function is being called externally or not.
>
> For example, if you had two modules A and B which contained:
>
> // File : /obj/modules/a
> // Module A
>
> query_extern() { return extern_call(); }
>
> // File : /obj/modules/b
> // Module B
>
> inherit "obj/modules/a";
>
> query_extern() { return ::query_extern(); }
>
>
> If you call query_extern(), in Module A, it will return 1 or 0 depending on
> whether you used call_other(), or some external function, as documented.
> If you call query_extern() using call_other(), in Module B, it will always
> return 0.
>
> One possible solution is to modify extern_call() so that its behaviour
> changes depending on the situation. If a function Y calls a function X,
> which calls extern_call(), it should either:
>
> (1) KEEPS ITS CURRENT BEHAVIOUR.
> if X != Y (i.e. X has not got the same name, or is from a
> different object to Y)
>
> (2) BEHAVE AS IF IT WAS CALLED FROM Y.
> if X == Y (i.e. X has the same name as Y and is from the same
> object).
>
> Another solution is to create a new function e.g.
>
> extern_func_call()
>
> which behaves in the manner just described.
>
> Or yet another solution is to provide a efun which returns a list of
> function names in the current call stack, and the objects they came from.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: p-990423-0.gz (945 bytes) 2004-11-27 01:23
http://ldmud.eu/file_download.php?file_id=33&type=bug
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
284 [LDMud] Efuns feature N/A 2004-11-27 00:49 2009-10-02 09:51
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Efun to show all inheritees
Description: Short: inherits() returns all programs inheriting a given program
From: Pulami
Date: 2002-03-10
Type: Feature
State: New

Ich f=E4nde eine Efun interessant, die zu einem gegebenen Objekt a alle =
Objekte liefert, die a inheriten.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001419)
zesstra   
2009-10-02 09:51   
Phew. AFAIK this requires to search all objects and check if they are a blueprint and inherit the given program, because the driver does have only the refcount... If that is the case, then one could probably just as well do it in LPC by iterating through the object list, because that is probably not something done all the time...

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
286 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-27 00:51 2009-10-02 09:40
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: select() statement to complement switch()
Description: Short: select() statement to complement switch()
Date: Tue, 26 Mar 2002 11:21:59 -0700
From: Lars Duening <c-lars.duening@wcom.com>
Type: Feature
State: New

Transform switch() back to it's old behaviour.

Implement select() { case... } with the following changes:

 - ints, floats, symbols, #'symbols, strings are
   allowed as values.
 - runtime error if no match is found (read: default required)
 - Allow typenames as labels: 'case object:'
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001417)
zesstra   
2009-10-02 09:40   
What was the old behaviour of switch()? BTW: I don't think it is a wise thing to change the behaviour of switch() nowadays.
Typenames as labels could be done by a switch(typeof(a)) { }, although that is probably not what was suggested here...

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
283 [LDMud] Runtime feature N/A 2004-11-27 00:49 2009-10-02 09:32
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Stack size watch
Description: Short: Stack size watch
From: Lars Duening <lars@bearnip.com>
Date: Sat, 09 Mar 2002 22:40:26 -0700
Type: Feature
State: New

Add a new configuration parameter MAX_STACK_SIZE/--max-stack (default: 0 =
infinite), which is used by assert_stack_gap() to limit recursions.

On systems which provide limits on stack/heap (BSD: getrlimit(), BeOS:
Hardcoded system constants?), use these values to override the max-stack/max-
malloc.


AIX uses the ulimit() efun.
  
                                   
-------------------------------------------------------------------------------
      Base Operating System and Extensions Technical Reference, Volume 2
-------------------------------------------------------------------------------

ulimit Subroutine

Purpose

Sets and gets user limits.

Library

Standard C Library (libc.a)

Syntax

The syntax for the ulimit subroutine when the Command parameter specifies a
value of GET_FSIZE or SET_FSIZE is:
#include <ulimit.h>

long int ulimit (Command, NewLimit)

int Command;

off_t NewLimit;

The syntax for the ulimit subroutine when the Command parameter specifies a
value of GET_DATALIM, SET_DATALIM, GET_STACKLIM, SET_STACKLIM, GET_REALDIR, or
SET_REALDIR is:
#include <ulimit.h>

long int ulimit (Command, NewLimit)

int Command;

int NewLimit;

Description

The ulimit subroutine controls process limits.

Even with remote files, the ulimit subroutine values of the process on the
client node are used.

    Note: Raising the data ulimit does not necessarily raise the program break
    value. If the proper memory segments are not initialized at program load
    time, raising your memory limit will not allow access to this memory. Also,
    without these memory segments initialized, the value returned after such a
    change may not be the proper break value. If your data limit is
    RLIM_INFINITY, this value will never advance past the segment size, even if
    that data is available. Use the -bmaxdata flag of the ld command to set up
    these segments at load time.

Parameters

Command Specifies the form of control. The following Command parameter values
require that the NewLimit parameter be declared as an off_t structure:

GET_FSIZE (1) Returns the process file size limit. The limit is in units of
UBSIZE blocks (see the sys/param.h file) and is inherited by child processes.
Files of any size can be read. The process file size limit is returned in the
off_t structure specified by the NewLimit parameter.

SET_FSIZE (2) Sets the process file size limit to the value in the off_t
structure specified by the NewLimit parameter. Any process can decrease this
limit, but only a process with root user authority can increase the limit. The
new file size limit is returned.

The following Command parameter values require that the NewLimit parameter be
declared as an integer:

GET_DATALIM (3) Returns the maximum possible break value (as described in the
brk or sbrk subroutine).

SET_DATALIM (1004) Sets the maximum possible break value (described in the brk
and sbrk subroutines). Returns the new maximum break value, which is the
NewLimit parameter rounded up to the nearest page boundary.

GET_STACKLIM (1005) Returns the lowest valid stack address.

    Note: Stacks grow from high addresses to low addresses.

SET_STACKLIM (1006) Sets the lowest valid stack address. Returns the new minimum
valid stack address, which is the NewLimit parameter rounded down to the nearest
page boundary.

GET_REALDIR (1007) Returns the current value of the real directory read flag. If
this flag is a value of 0, a read system call (or readx with Extension parameter
value of 0) against a directory returns fixed-format entries compatible with the
System V UNIX operating system. Otherwise, a read system call(or readx with
Extension parameter value of 0) against a directory returns the underlying
physical format.

SET_REALDIR (1008) Sets the value of the real directory read flag. If the
NewLimit parameter is a value of 0, this flag is cleared; otherwise, it is set.
The old value of the real directory read flag is returned.

NewLimit Specifies the new limit. The value and data type or structure of the
NewLimit parameter depends on the Command parameter value that is used.

Examples

To increase the size of the stack by 4096 bytes (use 4096 or PAGESIZE), and set
the rc to the new lowest valid stack address, enter:
rc = ulimit(SET_STACKLIM, ulimit(GET_STACKLIM, 0) - 4096);

Return Values

Upon successful completion, the value of the requested limit is returned.
Otherwise, a value of -1 is returned and the errno global variable is set to
indicate the error.

All return values are permissible if the ulimit subroutine is successful. To
check for error situations, an application should set the errno global variable
to 0 before calling the ulimit subroutine. If the ulimit subroutine returns a
value of -1, the application should check the errno global variable to verify
that it is nonzero.

Error Codes

The ulimit subroutine is unsuccessful and the limit remains unchanged if one of
the following is true:

EPERM A process without root user authority attempts to increase the file size
limit.

EINVAL The Command parameter is a value other than GET_FSIZE, SET_FSIZE,
GET_DATALIM, SET_DATALIM, GET_STACKLIM, SET_STACKLIM, GET_REALDIR, or
SET_REALDIR.

Implementation Specifics

This subroutine is part of Base Operating System (BOS) Runtime.

Related Information

The brk subroutine, sbrk subroutine, getrlimit or setrlimit subroutine, pathconf
subroutine, read subroutines, vlimit subroutine, write subroutine.
-------------------------------------------------------------------------------
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001415)
zesstra   
2009-10-02 09:32   
One problem ist, that it is not so easy to find out about the stack size. ulimit is highly platform dependent and last time I checked, not many implement something like GET_STACKLIM/SET_STACKLIM. Also Posix does not define many ulimit commands:
http://www.opengroup.org/onlinepubs/009695399/basedefs/ulimit.h.html
getrlimit() is better in the respect that you can set the maximum stack size on more platforms, but there is no way to query the current stack size there.

So, while this is a nice idea and I thought about this also in the bug about too many recursions in PCRE (0000524), I am very sceptical, there is a sane and portable way to do this.
Additionally, the checks for exceeded stack size on many systems are not really reliable, see 0000532. Most have a guard page and any access to that page causes SIGSEGV, but if you exceed that guard page any access _after_ that guard page does not an error.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
276 [LDMud] Efuns feature N/A 2004-11-27 00:27 2009-10-02 09:08
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: feedback Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Implement seeded randoms
Description: Short: Implement seeded randoms
From: Lars
Date: 2001-12-30
Type: Feature
State: New

value = seeded_random(seed, limit);

Internally, put the random generator into a structure so that multiple can
be created.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001413)
zesstra   
2009-10-02 09:08   
But then each object relying on a specific seed and sequence for a longer time must have its own copy bound to the object and no other object can extract numbers from it.
Is there a concrete application here? From my everyday mud experience, I often need random numbers, but until now I never needed a specific sequence.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
273 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-27 00:25 2009-10-02 08:00
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Named function arguments
Description: Short: Better functiona arg definitions
From: Nathan
Date: 2001-12-13
Type: Feature
State: New

In function calls, allow specification of arguments by name:

  foo(1, victim: him, 2);


In varargs function definitions, allow to mark where the optional args
begin, for example with a ';':

  void foo (int i, int j ; mixed k)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001410)
zesstra   
2009-10-02 08:00   
The possibility to distinguish between needed an optional argument might be done by using int fun(int arg1, string arg2, varargs int moreargs), although that is a bit more clumsy then just marking the first optional argument.
But I would not define this issue as really important.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
153 [LDMud 3.5] Compilation, Installation feature N/A 2004-11-26 20:33 2009-10-02 04:58
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Improving the inherit list
Description: Eine Sache, die man vielleicht ins Auge fassen kann ist, die inherit
liste ein wenig sauberer zu machen (vielleicht alle extra virtual zuerst
und die dann auch nicht mehr als einmal). Man koennte den lookup zur
Laufzeit optimieren und f_inherit_list() verbessern (die gibt naemlich
auch die extra inherits aus).

With the current one-pass compiler this is not that easy.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
156 [LDMud] Runtime minor N/A 2004-11-26 20:39 2009-10-02 04:53
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Performance of object memory management
Description: Allerdings gibt es eine kleine Ausnahme: Sowohl bei Amylaar als auch
bei MUDOS scheint das Objekt-Memory Management eine Schwachstelle zu
sein. Bei raschem Touching von sehr vielen Objekten hintereinander
kommt es zu einem dramatischen, nichlinearen(!) Anstieg der Rechenzeit.
Dass man schon mit einem relativ harmlosen Wegescipt richtig uebel Lag
produzieren kann, wenn man damit in eine ungeladene Gegend rennt,
ist wegen der Plattenzugriffe klar.
 Aber selbst bei bereits geladenen Objekten nimmt die Effektive CPUzeit
nach etwa 400 Objekten radikal nichtlinear zu. (Das Phaenomen tauchte
im Zusammenhang mit rekursiv arbeitenden Wegfinde- oder Maptools auf.
Getestet hatte ich es vor laengerem unter DOS mit einem 486er, trat aber
gleichermassen unter UNIX auf.)
Vielleicht hat ja mal jemand Lust, auf einem aktuellen System eine
Messreihe aufzunehmen?
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001398)
zesstra   
2009-10-02 04:53   
Maybe related, maybe not, I had on our current system the following experience:

inherit "/std/thing";
#include <properties.h>
int _query_disable_attack() {return 0;}
void create() {
  ::create();
  Set(P_DISABLE_ATTACK, #'_query_disable_attack, F_QUERY_METHOD);
}
void test() {
  foreach(int i: 10000) {
    this_object()->QueryProp(P_DISABLE_ATTACK);
  }
}
So test() would query the property 10000 and each time the function _query_disable_attack() is evaluated.

test() typically needs:
Eval-Ticks: 570327
Evaluation time: 92 ms.

but surprisingly sometimes:
Eval-Ticks: 570327
Evaluation time: 22490 ms.

Also suprising:
mixed test1() {
  int c=get_eval_cost();
  mixed arr=allocate(100,0);
  foreach(int i: 30000) {
    arr = ({i}) + arr[0..<2];
  }
  return c-get_eval_cost();
}
xcall test->test1()
Evaluation time: 61663 ms.
Result: 300017
Evaluation time: 61748 ms.
Result: 300017
Evaluation time: 224 ms.
Result: 300017
Evaluation time: 1504 ms.
Result: 300017
Evaluation time: 424 ms.
Result: 300017
Evaluation time: 11152 ms.
Result: 300017

So the second test may stop the whole mud for more than a minute, thats more a 250 fold increase in execution time. I could not trace the issue, because I can't reproduce this at home and I can't produce minute long lags the whole time. ;-)
It seems to depend on the hardware, maybe CPU cache issues?

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
244 [LDMud] Efuns feature N/A 2004-11-26 23:55 2009-10-01 17:09
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Add priority to notify_fail()
Description: Short: Add a priority to notify_fail()
Date: 2001-05-16
From: Gnomi
Type: Feature
State: New

Add a numeric priority to notify_fails(), so that a previous message
is replaced only by one with an equal or higher priority.

In other words: previous messages are not overwritten by messages with a lower
priority.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001372)
zesstra   
2009-09-30 17:13   
We currently solve this by an sefun, which also estimates priorities of different objects. But letting the driver take care of this, would also be nice.
(0001386)
_xtian_   
2009-10-01 03:31   
I'm not sure, if it's a good idea. In the end the wizards will have to adhere to a MUD-standard for notify_fail() call priorities for different situations (thus replacing our _notify_fail() and notify_fail()), but then it would just be simpler to use these two (s)efuns directly. Because its clearer what they're for: One case, if your not sure, that the object was the intended target; one case, if youre sure of it - at least, thats how we use it.

If we end up allowing all kind of priorities for notify_fail(), we will just make bug-tracking more complicated.
(0001395)
Coogan   
2009-10-01 17:09   
In the Tublib, we implement notify_fail() with priorities as sefun. If the driver takes care of this, it should be possible to receive all n_f()-messages which were raised during the evaluation of a player command (which is our current sefun implementation and very handy in rare cases of debugging).

I'm not sure if the handling of notify_fail() with priorities should better stay in the mudlib.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
260 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-27 00:11 2009-10-01 05:21
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Make '>' indexing default, with an option?
Description: Short: Make > indexing default with an option ?
From: Tomba@Batmud
Date: 2001-08-25
Type: Feature
State: New

Anyway, I was wondering what's the difference between normal indexing and
> indexing. Isn't normal indexing just a subset of > indexing? If so, why
not default to > style indexing and add a compile time option for allowing
or disabling negative indexes. Just to clear up a bit, arr[-2] would be
the same as arr[>-2] etc.

Batmud's old driver works this way, and even if I have already made my own
changes to ldmud to allow negative indexing, it'd be nice to have it by
default. =)

And Alfe said to this topic:

Alfe says: man koennte vielleicht folgendes sagen:
Alfe says: x[>a..>b] ist das, was x[a..b] bisher ist.
Alfe says: x[a..b] ist das, was extract(x,a,b) bisher ist (d.h. vorzeichen
  legt fest, ob von rechts oder links).
Alfe says: und x[<a..<b] ist wie gehabt.

Alfe says: aber dann muesste man mal durchs mud gehen und alle vorkommen von
  x[a..b] ueberpruefen
Alfe says: du kannst nicht garantieren, dass ein x[a..b] bisher immer mit
  positiven werten arbeitete, also solltest du besser davon ausgehen, dass
  alle stellen potentiell auch mit negativen werten passieren koennen.
Alfe says: demnach stehe ich dieser version etwas ambivalent gegenueber.
Alfe says: es waere zwar sehr schoen, wenn das < sagt: von rechts, das > sagt:
  von links und sonst sagt das vorzeichen das.
Alfe says: denn das ist logisch strukturiert.

Alfe says: so gesehen waere es vielleicht besser, wenn das x[>a..>b]
  bedeutet, dass das vorzeichen entscheidet und x[a..b] wie gehabt bleibt.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001373)
zesstra   
2009-09-30 17:25   
Just until now I thought, that indexing with negative numbers/ranges is deprecated but I seem to be wrong.
Can anybody tell me about the real purpose of indexing something from before the beginning?
(0001375)
Gnomi   
2009-09-30 17:33   
Single indices (a[x]) are not allowed to be negative, but indices in ranges can be (a[-1..x] is the same as a[0..x]). Ranges are much sloppier than normal indexing operations.
(0001376)
zesstra   
2009-09-30 17:37   
Mhmm, is it feasible to deprecate negative numbers in ranges and issue warnings and errors with pedantic (and later even without). Or is that too heavily used?
(0001378)
Gnomi   
2009-09-30 17:44   
Can't say without warnings... (With the deprecated indexing past string ends we got more warnings than I expected, so there might be a lot of that around, too.)
(0001390)
Sorcerer   
2009-10-01 05:08   
One the one hand, as long as the driver ensures all ranges that start below 0 to be remapped to 0..rangemax I would rather call it a feature than a bug. It allows for a very easy-to-use way to get that last n elements (or less if there are less than n elements at all) of an array/string.
On the other hand, this possibility implies, that I should also be able to get the first n elements of an array/string by [0..(n-1)] - which might complain about indexing past string end.

So, for the sake of consistency, I would opt for deprecating negative indices.
(0001391)
zesstra   
2009-10-01 05:21   
Ok, but that is possible without negative indices:
[0..n-1]: first n elements
[<n..]: last n elements

This negative indices I meant was [-3..-1] which is the empty array/string and [-2..2] which is [0..2]. I don't really think, you need the negative indices as they are now (for other than backwards compatibility).
Something else would be to use the sign instead of <. That [-3..] would be the last 3 elements, but to change to this will silently break code and I would not like that.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
264 [LDMud] Networking feature N/A 2004-11-27 00:15 2009-09-30 18:08
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Make telnet negotiations more configurable
Description: Short: Make telnet negotiation options more configurable
From: Markus Peter
Date: 2001 09 28
Type: Feature
State: New

I recently wanted to implement support for the MSP and MXP protocols into
my mudlib. The specifications on those protocols allow to negotiate their
availability in the client using telnet negotiations via the inofficial
options 90 and 91.

The problem I ran now into is: H_TELNET_NEG will only allow my mudlib
handling stuff like NAWS, TTYPE etc. I could now of course also set
H_NOECHO and handle all negotiations myself, but this seems like a little
bit overkill to re-develop the echo part of the negotiations myself when
it already works perfectly ok in the driver.

So my request basically is: Could options 90 and 91 be added to the list
of options which are handled through H_TELNET_NEG or can the list of
options be made configurable without patching the driver ?

--- I added the options 90 and 91 explicitely, the generic configuration (e.g.
via map set in driver hook) would be a nice idea.

From: Lars Duening <lars@bearnip.com>
Date: Mon, 04 Feb 2002 21:43:51 -0700

Allow a driver hook to specify which telnet hooks are to be piped through the
mudlib - not this all-or-nothing like now.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
240 [LDMud] Other feature always 2004-11-26 23:52 2009-09-30 17:40
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: LPC keyword 'yield'
Description: Short:'yield' to convert statements into expressions
From: Lars
Date: 2001-03-09
Type: Feature
State: New

E.g.
a = if (foo) { bla; yield 1; }
    else { if (bar) yield 2; yield 3;}
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001374)
zesstra   
2009-09-30 17:29   
Isn't that, was
val = a ? b : c
is doing?
(0001377)
Gnomi   
2009-09-30 17:40   
Hmm, that syntax looks rather complicated for an amateur language like LPC.

(But it would be fun to implement a Python-style yield statement. I don't know if there's any need for it, but it surely would be fun...)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
254 [LDMud 3.5] Runtime feature N/A 2004-11-27 00:05 2009-09-30 17:02
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: restore_/save_object(): pass full filename to valid_write/read
Description: Short: On save/restore object, pass full filename to valid_write/read
From: Lars
Date: 010701
Type: Feature
State: New

restore_object("foo") does not pass "foo.o" to valid_read(), but instead
just "foo", which confuses some people.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
167 [LDMud] Efuns feature N/A 2004-11-26 22:05 2009-09-27 18:17
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: New efun truncate_file()
Description: Short: new efun truncate_file()
From: Alfe
Date: Wed, 16 Dec 1998 21:11:51 +0100 (MET)
Type: Feature
State: Acknowledged

speaking of such: i'd like a truncate_file() efun which truncates files
(you guessed that from the name already?). the current simulefun
implementation in TubMud for that function is rather ugly, copying the
file to a new one until the truncate position is reached and then removing
the original and renaming the copy. for copying it also has to work
around the read/write_bytes limitation.

Note: make this a special mode of copy_file(),
e.g. copy_file(from,to,start,len)?
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001317)
zesstra   
2009-09-27 18:17   
ok, truncation can be achieved with write_file(,,1), but not from a specific position onwards. But is it really common to just truncate a file to a certain length without knowing whats inside? And if I know the data, then probably I can just use write_file(file, data, 1). Or do you have really big files in mind?

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
187 [LDMud] Efuns feature N/A 2004-11-26 22:26 2009-09-27 13:46
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: New efun: raise_caller_error()
Description: Short: New efun raise_caller_error()
From: Lars, Daniel von Dincklage <vondincklage@usa.net>
Date: Mon, 22 Jun 1998 00:53:36 +0200
Type: Feature
State: Unclassified
See also: p-990204-1, f-000716

void raise_caller_error(string msg, object caller = previous_object())

  Works like raise_error, except that the error is attributed
  to <caller>, not this_object().

  <caller> must be in the current call stack!

Maybe make this an extension of raise_error() itself.

Note: can be done in an sefun using caller_stack() and set_this_object()?
Note: could also be called raise_error()
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001310)
zesstra   
2009-09-26 20:11   
For this purpose, we actually use this approach with set_this_object() sometimes. The disadvantage is, that only privileged objects can do that. ok, one could make a sefun using that mechanism.
(0001312)
fufu   
2009-09-27 13:46   
We (Wunderland) have code in the master object's runtime_error() function using debug_info(DINFO_TRACE, DIT_UNCAUGHT_ERROR) to attribute errors to calling objects. The reference is encoded in the error message itself: http://wl.mud.de/mud/doc/efun/raise_error.html

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
191 [LDMud] Efuns feature N/A 2004-11-26 22:31 2009-09-26 20:07
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: object argument to set_next_reset()
Description: Short: New efun: reset_object()
From: Daniel von Dincklage <vondincklage@usa.net>
Date: Fri, 19 Jun 1998 13:17:34 +0200
Type: Feature
State: Unclassified

- A reset_object() efun that updates the last-reset.

Note: add object argument to set_next_reset(), but make that priviledged.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001309)
zesstra   
2009-09-26 20:07   
What application would the last_reset() efun have?
Concerning the set_next_reset() argument: ok, that is one possibility. The other one, which we use:
funcall(bind_lambda(#'efun::set_next_reset,ob),zeit);
in a privileged object. That object then has to check any privileges of the caller.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
672 [LDMud] Other tweak have not tried 2009-09-16 04:58 2009-09-16 16:16
Reporter: _xtian_ Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: [PATCH] "status malloc": output the mem allocator type
Description: Trivial patch to output the name of the used allocator on "status malloc" for the other 3 allocators that don't already do this.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: output_xalloctype.patch (1,554 bytes) 2009-09-16 04:58
http://ldmud.eu/file_download.php?file_id=249&type=bug
Notes
(0001266)
zesstra   
2009-09-16 05:40   
Ah, this clashes somewhat with our plan to remove commands like status from the driver (see 0000165). ;-)
Comments?
(0001267)
_xtian_   
2009-09-16 07:07   
discard it, if you want, no worries. It was just 2mins. My incentive was to detect the active allocator at runtime (from inside the mud). There seems to also be a debug_info(6,2) to get this. But including it in status malloc was more agreeable.
(0001270)
zesstra   
2009-09-16 09:43   
Ok, it is a quite small patch. I don't mind to apply it, even if we remove status soon (in 3.3.x status will anyway be available until that branch is not supported anymore).
(0001272)
zesstra   
2009-09-16 16:16   
Applied in r2745 and r2745. Thanks. ;-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
675 [LDMud 3.5] LPC Compiler/Preprocessor feature N/A 2009-09-16 06:30 2009-09-16 09:36
Reporter: Bardioc Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.3  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Implementation of generational garbage collection using the 'Train Algorithm' (real-time, interruptable)
Description: Implementation of the Train Algorithm as described in the document

http://www.ssw.uni-linz.ac.at/General/Staff/TW/Wuerthinger05Train.pdf

Adantages over the currently "mark-and-sweep" garbage collection:
* interruptable (handles small partions of the memory, so called 'cars' in the 'train'
* realtime, as interruptable (can be set to only work for e.g. 10 ms, and stop afterwards)
* finds circular references and is able to free them
* is generational, thus preserves long-time objects to stay in other generation than short-time objects (reduces fragmentation)

Maybe some others that I actually don't recall. JVM > 1.4 uses Train Algorithm if called with -Xincgc.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001269)
zesstra   
2009-09-16 09:36   
I may be wrong, but as far as I understand the algorithm (I just glanced over), this will require quite extensive changes (GC itself + allocators, reference management, interpreter, swapper).
In this case, I don't see that as suitable for 3.5.x if we want to finish that in a foreseeable time.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
674 [LDMud] Runtime major always 2009-09-16 05:33 2009-09-16 07:28
Reporter: _xtian_ Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: memleak: copying self referencing mappings
Description: Avalon is being plagued by a memleak and baba@avalon seems to have found its cause: copying a mapping that holds a self-reference. Now tracking memleaks is difficult, but I am appending some code in the hopes that you will be able to reproduce it in an isolated environment.
Tags:
Steps To Reproduce:
Additional Information: // memleak.c
mapping m; // global to not obfuscate my output

void leak()
{
  mapping n;

  printf("starting ...\n");

  m=([]);
  m["self"]= m; // set self reference

  n= deep_copy(m); // this is the leak, leads to ref-counter being off
}

void pre()
{
  printf("preparing ...\n");
  efun::garbage_collection(); // clean slate
}

void post()
{
  printf("post ...\n");
  efun::garbage_collection("MEMLEAK");
  printf("done.\n");
}

void create()
{
  pre();
  leak();
  post();
}
Attached Files:
Notes
(0001268)
_xtian_   
2009-09-16 07:28   
After some discussion on d-chat:

a) self-referencing in general is the problem
b) there is no trivial way to efficiently check for self-refcounts when creating/deleting the self-referencing data, which I would need here (not at GC time!)
c) Although Im still hoping that this may be adressed someday in the future, on the short-term we should not use self-referencing data in LPC

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
671 [LDMud 3.3] Runtime crash always 2009-09-04 10:32 2009-09-08 17:48
Reporter: favoretti Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.719  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.720  
    Target Version: 3.3.720  
Summary: Crash in xml_generate / xml_parse
Description: been trying to run the example of xml_generate:

exec xml_generate(({ "abc", ([ "xyz" : "cde" ]), 0 }));

crashed immediately with the following in stack trace:

(gdb) bt
#0 0x00000000004c07f5 in remove_from_free_list (ptr=0x1b3a6f8) at smalloc.c:2148
0000001 0x00000000004c1075 in add_large_free (ptr=0x1b3a6f8, block_size=0) at smalloc.c:2854
0000002 0x00000000004c3789 in mem_free (ptr=0x1b3a700) at smalloc.c:1871
0000003 0x00007fcf6bd82edb in xmlCleanupCharEncodingHandlers () from /usr/lib/libxml2.so.2
0000004 0x00007fcf6bd8bed3 in xmlCleanupParser () from /usr/lib/libxml2.so.2
0000005 0x000000000049a083 in xml_cleanup (arg=<value optimized out>) at pkg-xml2.c:277
0000006 0x000000000049a2c1 in f_xml_generate (sp=0x713000) at pkg-xml2.c:457
0000007 0x000000000044ee88 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:8276
0000008 0x00000000004579e7 in apply_low (fun=0x7fcf35b27c30, ob=0x1d0a0, num_arg=0, b_ign_prot=false, allowRefs=false, b_ign_shadows=false) at interpret.c:17442
0000009 0x0000000000447584 in int_apply (fun=0x1b3a6f8, ob=0x0, num_arg=1809604848, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
0000010 0x000000000044d623 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:16645
0000011 0x00000000004579e7 in apply_low (fun=0x7fcf35b27db0, ob=0x177c0, num_arg=1, b_ign_prot=false, allowRefs=false, b_ign_shadows=false) at interpret.c:17442
0000012 0x0000000000447584 in int_apply (fun=0x1b3a6f8, ob=0x0, num_arg=1809604848, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
0000013 0x000000000044d623 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:16645
#14 0x00000000004ad303 in catch_instruction (flags=0, offset=<value optimized out>, i_sp=0x7e3d50, i_pc=0x7fcf45cd949e "e?\037\001\037", i_fp=<value optimized out>,
    reserve_cost=150000, i_context=0x0) at simulate.c:455
#15 0x000000000044a9a2 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:9730
#16 0x00000000004579e7 in apply_low (fun=0x7fcf4315bb00, ob=0x21480, num_arg=1, b_ign_prot=false, allowRefs=false, b_ign_shadows=false) at interpret.c:17442
#17 0x0000000000447584 in int_apply (fun=0x1b3a6f8, ob=0x0, num_arg=1809604848, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
#18 0x000000000044d623 in eval_instruction (first_instruction=<value optimized out>, initial_sp=<value optimized out>) at interpret.c:16645
#19 0x00000000004579e7 in apply_low (fun=0x7fcf431c0c88, ob=0x24210, num_arg=1, b_ign_prot=false, allowRefs=false, b_ign_shadows=false) at interpret.c:17442
#20 0x0000000000447584 in int_apply (fun=0x1b3a6f8, ob=0x0, num_arg=1809604848, b_ign_prot=<value optimized out>, b_use_default=true,
    b_ign_shadows=<value optimized out>) at interpret.c:17546
#21 0x00000000004480cb in sapply_int (fun=0x7fcf431c0c88, ob=0x7fcf48cb90a8, num_arg=1, b_find_static=false, b_use_default=true) at interpret.c:17707
#22 0x000000000040741d in parse_command (buff=0x7fff7500d1a0 "exec xml_generate(({ \"abc\", ([ \"xyz\" : \"cde\" ]), 0 }));", from_efun=false) at actions.c:1158
#23 0x0000000000408711 in execute_command (str=0x7fff7500d1a0 "exec xml_generate(({ \"abc\", ([ \"xyz\" : \"cde\" ]), 0 }));", ob=0x7fcf48cb90a8) at actions.c:1333
#24 0x000000000040f2bf in backend () at backend.c:696
#25 0x0000000000464f36 in main (argc=<value optimized out>, argv=<value optimized out>) at main.c:688
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001248)
zesstra   
2009-09-04 11:10   
Mhmm. Unfortunately, I can't reproduce this.
I checked 3.3.719 and 3.3/trunk.

# uname -a
Linux mg 2.6.26-2-amd64 0000001 SMP Fri Aug 14 07:12:04 UTC 2009 x86_64 GNU/Linux
# file ldmud
ldmud: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, not stripped
# ldd ldmud
[...]
    libxml2.so.2 => /usr/lib/libxml2.so.2 (0x00007f66a8721000)

xml_generate(({ "abc", ([ "xyz" : "cde" ]), 0 })); returns the string
   "<?xml version=\"1.0\"?>\n<abc xyz=\"cde\"/>\n"

Please tell us more about your environment/platform.
 
(0001252)
favoretti   
2009-09-04 13:25   
Hi there,

We're running batmud, www.bat.org, with our custom lib.
The system is debian lenny 64-bit.
batmud64:/bat/mudlib# dpkg -l | grep libxml
ii libxml2 2.6.32.dfsg-5+lenny1 GNOME XML library
ii libxml2-dev 2.6.32.dfsg-5+lenny1 Development files for the GNOME XML library

Linux batmud64 2.6.26-2-amd64 0000001 SMP Sun Jul 26 20:35:48 UTC 2009 x86_64 GNU/Linux

batmud64:/bat/bin# file ldmud
ldmud: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, not stripped
batmud64:/bat/bin# ldd ldmud
        linux-vdso.so.1 => (0x00007fff933ff000)
        libnsl.so.1 => /lib/libnsl.so.1 (0x00007f9d8afc0000)
        libm.so.6 => /lib/libm.so.6 (0x00007f9d8ad3d000)
        libcrypt.so.1 => /lib/libcrypt.so.1 (0x00007f9d8ab05000)
        libgcrypt.so.11 => /usr/lib/libgcrypt.so.11 (0x00007f9d8a89e000)
        libmysqlclient.so.15 => /usr/lib/libmysqlclient.so.15 (0x00007f9d8a493000)
        libxml2.so.2 => /usr/lib/libxml2.so.2 (0x00007f9d8a137000)
        libc.so.6 => /lib/libc.so.6 (0x00007f9d89de4000)
        libgpg-error.so.0 => /usr/lib/libgpg-error.so.0 (0x00007f9d8b2e7000)
        libpthread.so.0 => /lib/libpthread.so.0 (0x00007f9d89bc8000)
        libz.so.1 => /usr/lib/libz.so.1 (0x00007f9d899b1000)
        libdl.so.2 => /lib/libdl.so.2 (0x00007f9d897ad000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f9d8b1d8000)
(0001254)
zesstra   
2009-09-04 13:49   
Well. I tested on Lenny 64-bit as well, kernel, libxml2 (and probably other libs as well) being exactly the same.
Was that a plaing 3.3.719 without any modifications?
What is probably different is the driver configuration we use. I would suggest to attach your config.h, machine.h (and Makefile in case you changed anything there) to this issue and then I may try again with that configuration.
(0001255)
favoretti   
2009-09-04 13:51   
It is a bit modified source, but nothing that would affect smalloc. Our configuration is in your trunk under src/settings/bat. I only added enable_use_xml=xml2
(0001256)
zesstra   
2009-09-04 14:07   
Mhmm. Checked with your settings/bat with added enable_use_xml=xml2, but still no luck.
I don't have the Batmud lib, so I just used a master which calls
debug_message(xml_generate(({ "abc", ([ "xyz" : "cde" ]), 0 }))); in
inaugurate_master() and shuts down. The outout on the console is:
<?xml version="1.0"?>
<abc xyz="cde"/>
(0001257)
zesstra   
2009-09-04 14:10   
Ahhh. Now it clears up a bit. I checked settings/bat and recognized that it configures the sysmalloc allocator, while the stacktrace above references the smalloc allocator. I changed the settings file to smalloc and can now reproduce the issue.
I will have a look at the details without any optimization later this evening, but it may take some time to track the root cause. (If anyone else wants to have look as well: feel free).
(0001258)
favoretti   
2009-09-04 14:24   
aha. Thanks :) Keep me posted.
(0001259)
favoretti   
2009-09-04 17:04   
One more thing to add. Compiled with enable_use_xml=iksemel doesn't crash.
(0001260)
zesstra   
2009-09-04 18:02   
Ok, this issue should be fixed in r2725 (trunk of 3.3 (in 3.3.720)) and r2727 on trunk.
The cause was a wrong sequence in initializing libxml2 and later memory was free'd with our allocator that was allocated by the system malloc.
That error emerged only in configurations where the system malloc was not replaced by our own allocator functions.
Thank you for reporting.
(0001262)
zesstra   
2009-09-08 17:48   
FYI: Although not strictly related to this issue here, there was a second issue in the package which could cause memory corruption and subsequent crashes. That was caused by using memory for libxml2 which was subject to our garbage collector and would be free'd by that during a GC run. That second issue is fixed by r2729 (3.3/trunk) and r2730 (on trunk).
You might want to get that patch as well.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
309 [LDMud] Efuns feature N/A 2004-11-27 01:16 2009-09-07 04:55
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: ODBC Implementation
Description: From: Robert Treml
Date: 2003-10-02
Short: ODBC
Type: Patch
State: New
See also: pkg-odbc.[ch]

Here is the source of the ODBC package. It might be a bit chaotic since it
was the first C project i did after years and my first ODBC project ever.

Installing it should be quite simple:
1) getting and installing an ODBC driver manager and ODBC drivers for the
used databases

I used the unixODBC driver manager (http://www.unixodbc.org/) which comes
with the required .h files and lib to access ODBC datasources and the
standard ODBC drivers for Postgres and MySQL which can be found on the
according web pages.

2) adding the .[ch] files and the odbc lib to the make file

3) adding the efuns to the func_spec file:
int sql_odbc_enabled();
mapping sql_odbc_datasources();
int *sql_handles();
int sql_connect(string, ...);
int sql_close(int);
int sql_exec(int, string);
int sql_affected_rows(int);
string *sql_column_names(int);
mixed sql_fetch(int, ...);
string sql_error(int);

4) complie & run

I used the mysql package as template and implemented its functionality
using ODBC. The ODBC functions should behave like the existing MySQL
functions with some small differences:
sql_fetch now supports a second optional parameter describing
the way the fetched data is returned.
0, default: The data is returned as an array
1: The data is returned as a mapping with the column name as key.

There is no function that covers the functionality of db_conv_string.
This function could be implemented as a simul_efun.

Actually i did some basic testing using a Postgres DB on the
same server (unix) and a MySQL DB on a different server (Win2k) and
everything seemed to work.
As soon as i have some more time i'll test an Oracle and a filebased ODBC
driver.

Awaiting you comments
thx,
 Robert
Tags:
Steps To Reproduce:
Additional Information: The pkg-odbc source files are already in the driver archive, albeit inactive.
Attached Files:
Notes
(0001261)
zesstra   
2009-09-07 04:55   
Ok, before somebody activates the package: it should be reviewed before. I just had a very quick look and there seems to be a memory leak: extract_diagnostics_info() allocates its non-static return value with pxalloc(), but the callers don't free the memory, e.g. errorf(extract_diagnostics_info(SQL_HANDLE_STMT, handle->hStmt ) ).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
669 [LDMud 3.5] LPC Language feature N/A 2009-08-20 09:35 2009-09-02 16:04
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version: 3.3.719  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.3.720  
Summary: Add a specifier to explicitly call simul efuns.
Description: Similar to efun::fun() there should be a sefun::fun() to call simul-efuns directly (and bypass any redefinitions as lfuns).
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0001247)
Gnomi   
2009-09-02 16:04   
Implemented in r2721.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
668 [LDMud] LPC Language minor always 2009-07-28 01:59 2009-08-14 10:23
Reporter: _xtian_ Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: passing by reference: unclear pointer/reference semantics
Description: Im am unsure if this is simply not explained enough in the documentation or a language problem: There is a difference in the way variables that are passed by reference by themselves (mappings, structs, ...) are handled when they are implicitely or explicitely passed by reference.

example:

void delete(mapping m)
{
  m= 0; // what does this delete?
}

void create()
{
  mapping n= ([1:2]);

  delete(n); // this will not delete n (pointer-like semantics)
  printf("%O\n",n);
  delete(&n); // this will delete n (reference-like semantics)
  printf("%O\n", n);
}
Tags:
Steps To Reproduce:
Additional Information: note that:
  object ob= ...; // any object
  delete(&ob); // ob= 0

does _not_ destruct the object, which is probably good. But this special case should be mentioned in the documentation somewhere.
Attached Files:
Notes
(0001241)
Gnomi   
2009-07-28 02:26   
The difference is because only the mapping is implicitly passed by reference, not the variable pointing to the mapping. So changes in the mapping itself are globally visible. But changes to the variable (putting another value in there, even if it's new mapping) are not.
(0001243)
_xtian_   
2009-07-30 09:43   
Yes, I understand the implementation details. But my point is that these are not clear at first glance, even for people that use C++ for example. You have to try it out to understand how the language/driver behaves.

One the one hand I find that this is a bit too convoluted and technical for a language like LPC which, I find, should especially target unexperienced programmers and be as newbie-safe as possible. (but it is probably too difficult to introduce a new behaviour without breaking code all over the place)

On the other hand then, this behaviour should at least be well documented.

So I guess I am asking: Do you think this is more or less error prone for a user than any other way? (while it probably is better this way, since changing it will be difficult anyhow) And then could we document this behaviour better?
(0001245)
fufu   
2009-07-31 12:42   
void delete(mapping m)
{
  m= 0; // what does this delete?
}

This does not delete anything really, not even if m is passed by reference:

{
   mapping n = ([ 1:2 ]);
   mapping m = n;
   delete(&n);
   // now n is 0, but the mapping is still accessible through m
}

What happens in your example is that by assigning 0 to m, the mapping is no longer accessible, and its reference count drops to 0, causing it to be freed.

Objects on the other hand are not destructed when they are not accessible through any variables - they can still be found by their name after all, and by other means. Also, unlike simple values, objects can be active - there can be a heart_beat, pending call_outs, and so on.

I find this quite intuitive - which part of the documentation would you like to have clarified? Where does the idea that the assignment deletes anything come from?

Does it come from Java? But even in Java, o = null; does not delete anything; it may cause objects to become unreachable though, and consequently be garbage collected.
(0001246)
_xtian_   
2009-08-14 10:23   
The thing is that typical LPC users dont think about how their data is represented in hardware and dont have a concept of pointers and memory adresses. To be honest: You can only understand the above issues if you have an understanding of C++ or other real life programming languages.

Suggestion for an addendum to the manpage:

Subtleties concerning references:
--------------------------------
As has been explained above, performing any operation on an argument that has been passed by reference to a function will modify the data that has been referred to, effectively "changing it for everybody".

But this does not hold true for assignements (as in x= 123) to references. Assignements do not operate on the referenced data, but on the reference itself. The original data is not modified. The target of the reference is.
This means that for explicit argument references (invoked by using the & ) the target of the reference is changed locally and for the caller. And that for implicit (automatical) referencing for mappings, arrays, structs or objects, which is the normal usage, the target of the reference is changed locally only.

If then the data is not accessible to any other program any more, the driver will free the system memory for it, albeit this may not happen immediately. Also, assigning a zero to an object will not delete it, only calling destruct() will.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
662 [LDMud 3.5] LPC Language minor have not tried 2009-06-16 08:39 2009-06-17 07:11
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: assigned Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: RFC: Inline closures should be able to modify outer local variables
Description: Currently the values of local variables that were referenced within an inline closures are copied, so that assignments in the inline closure won't affect the local variable. This behavior applies only to local variables, not global ones.

After 0000650 it should be possible to create an lvalue of the local variable instead of copying its value, so that modifications within the inline closure would reflect on the local variable. But this change might break code and it's hard to find where.

Any opinions on this?
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0001207)
Sorcerer   
2009-06-16 09:05   
While I would prefer to have context variables referenced instead of copied (so the inline can do changes on them that will affect the original variable) I agree that changing this behaviour might break a lot of code and cause some hard-to-find inconsistencies.
At the moment you can simply pass a reference to an inline in order to be able to modify it from within.
So - for me - the perfect option would be an option (even at driver-compile-time) to switch that behaviour and in addition a pragma, that allows me to throw a warning whenever a context variable is changed within a closure. So MUDs can turn on this pragma while staying at the old behaviour and find all occurances of possible code-breaks before activating the new behaviour.
(0001213)
zesstra   
2009-06-16 18:30   
Mhmm. I am pretty sure, we have some code in the lib which relies on outer variables not being changed by changing the implicitly defined context variables.
A change of behaviour would require something Sorceror sketched.

I am not sure about this, I kind of like it that the context variables are independent, because you can create a whole lot of closures (with different data) from the same place which can be used in parallel without interfering.
On the other hand, you can achieve this with explicitly defined context variables or variables defined in the local scope of the closure body.
But then you have two different types of context variables: implicitly defined ones, which change some other entity in a different scope and explicitly defined ones, which don't. Sounds like a source of potential problems if you are not very careful. BTW: You may define 'foo' as explicitly defined context variable and use it. What happens, if later someone defines 'foo' in the outer scope?
(0001214)
zesstra   
2009-06-16 18:35   
Ah, BTW: I am also not sure, if I like the possibility to switch the behaviour with a driver-compile-time switch, because it leads to even more splintering (or fragmentation?) of the LPC language. In discussions you have to ask one more parameter about the driver configuration. Thats fine for optional efuns, timings etc. but for the language itself I don't really like it.
A pragma would be slightly better, because you can at least copy the program between different systems and it behaves the same.
(0001215)
fufu   
2009-06-16 19:59   
Btw, if the restrictions on lvalues are lifted, the opposite idea may work as well (Gnomi: Is that right?):

int foo()
{
    int bar;
    closure f = function void () : int bar = &bar { bar = 42; };
    funcall(f);
    return bar;
}

I'm not sure where I stand on this issue; I dislike the inconsistent handling of local and global variables right now, but I also dislike the potential of breaking existing code in non-obvious ways. A pragma may be a good middle compromise, if it isn't too hard to support in the compiler. (And if we have a pragma, we don't need a compile time switch - people can pick their preferred default using the auto include string)
(0001216)
Gnomi   
2009-06-17 02:17   
Yes, for explicit context variables you would have the choice of taking the value or the reference to another variable as Fuchur described.

Zesstra, implicit and explicit context variable differ in that way, that explicit context variables have their own variable definition - so there it is very clear, that they are variables on their own. Implicit context doesn't, that's why I don't see a problem with differentiating between them.

If you define 'foo' as an explicit context variable it has precedence over all outer scopes (normal scoping rules).

I agree that making this a pragma would be a good compromise. Issuing warnings where it would break code is very hard. (You have to track whether a variable is written by the inline closure or the outer function and after that accessed by the other one. Because the compiler can't guess the timing (the closure might be executed within or after the outer function), it has to be done at runtime or otherwise there would be a lot of false positives.)
(0001217)
zesstra   
2009-06-17 06:04   
Well, yes. But they remain context variables with different behaviour. If I use <a> in an inline-closure I have to check, if it is an implicit, explicit context variable, explicit context variable referencing another one, a locally defined variable or a global one. Right now, I can trust (with <a> being global as exception), that I don't alter values in different closures and the defining function. I just prefer that as a safer default the same way I appreciate that arguments are passed as values, because it separates different functional units of my program from interfering.
Although I would appreciate the possibility to explicitly create a referencing context variable by 'int ref_b = &b;' in the rare cases I need it, it is just a matter of default.
That just to explain why I like the current behaviour. I won't really resist such a change, but I see not only advantages.

Concerning the pragma and 'LPC language fragmentation': The pragma is definitely needed for an intermediate time. But we should discuss, if we need it forever. I think, in the long-term I would prefer a decision for one behaviour...

Warnings... Basically, I think what Sorcerer suggests is: warn for _every_ assignment of values to an implicit context variable at compile-time. Then the wizard has to check if that assignment would be OK for a reference to the outer variable and disable the warning pragma for that program after this check. Yes... Produces a lot of warnings. But the alternative is to check every inline-closure, which is much worse.
(0001218)
Gnomi   
2009-06-17 06:14   
It is not sufficient to check assignments to implicit context variables, but we also have to warn on assignments to local variables that were used as context variables (closure fun() { int a = 1; closure cl = (: a :); a = 2; return cl; } - with the current behavior funcall(fun()) would return 1, with the new behavior 2.).
(0001219)
zesstra   
2009-06-17 06:58   
Your are right. *sigh* :-(
(0001220)
Sorcerer   
2009-06-17 07:11   
I agree with Zesstra that a compile-time-option would lead to an undesirable fragmentation of the language, so a pragma will be the better choice.

As for argument passing: I agree that explicitly passing arguments to functions (including inlines) should remain a call-by-value. This makes things way easier for inexperienced programmers. But using a variable that I declared only once (e.g. in the local scope of the function containing the inline) for me intuitively means: altering the variable, not a copy of it which I never explicitly created. Of course, I also see the problematic created in Gnomi's last example (changing values in a closure after it was created and before it is called). Still, I would prefer implicit context to be by-reference, explicit one being to option in case I need something by-value.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
658 [LDMud 3.5] Compilation, Installation minor N/A 2009-06-12 16:51 2009-06-16 17:43
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: RfC: Remove/Update supplied version of pcre
Description: The pcre version we supply is dreadfully out-dated. We should either update or remove it.
I wanted to update it for a long time, but the longer I think about it, the more I would like to remove it and just link against the system libpcre. That should save us time to concentrate on our core development. I think, nearly nobody currently uses the supplied pcre package and it seems to be ubiquitary available on POSIX systems.
Please comment. ;-)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001203)
fufu   
2009-06-14 19:33   
I agree with removing the bundled libpcre. Even cygwin has a pcre-devel package.
(0001204)
zesstra   
2009-06-15 01:55   
The driver currently relies on libpcre's availability (because it is bundled). Removing it leads to a non-optional requirement for libpcre on the system. It seems OK for me, but I could alternatively insert some #ifdef HAS_PCRE into mregex.c, so that without a system libpcre only the traditional RE implementation is available. Gnomi and me don't like #ifdefs too much, but that way we would have libpcre still optional.
(0001205)
Gnomi   
2009-06-15 06:05   
I agree, too, that the libpcre sources should be removed from the driver sources, and I think that pcre support should be made optional.
(0001210)
zesstra   
2009-06-16 15:18   
I am just preparing a patch which removes our builtin pcre package and encapsulates the references to it in mregex.c by #ifdef HAS_PCRE.
I plan to commit the patch directly to 3.5. because that is anyway expected to be unstable. ;-)
(0001211)
zesstra   
2009-06-16 17:43   
Ok, I removed the built-in PCRE package in r2646. The existence of libpcre on the host system should be completely optional. Of course, without it, no PCREs in the driver.
I hope, I did not miss some manpage... ;-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
637 [LDMud 3.5] Efuns minor N/A 2009-05-18 14:16 2009-06-03 18:06
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.5.0  
    Target Version: 3.5.0  
Summary: RfC: Remove the efun cat()
Description: In the discussion about 0000636 on -d-code, there was a suggestion to remove the efun cat(). cat() is nearly the same as read_file()+tell_object() - the biggest difference being that cat() does not read in the whole file.
Please comment on this idea.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001116)
zesstra   
2009-05-19 04:31   
Ah, BTW: For a removal I would suggest the following strategy: deprecate the efun now in 3.3.x and remove it in 3.5.1, because I don't like to remove it from one minor release to the other. I had a quick look in our mudlib and it is used about 110 times, so we have to introduce a sefun as replacement in MG.

I guess, it is a good idea to start our reference simul_efun.c which contains suggestions for sefuns emulating removed efuns (I think, we discussed the in some other bug shortly).
(0001117)
Gnomi   
2009-05-19 04:33   
I agree.
(0001132)
lynx   
2009-05-22 04:00   
I once thought cat() could be the superhighway for files on the disk to be copied to a socket bypassing the main LPC memory.. like throwing an mp3, an xvid, an flv or mp4 directly at an httpd or socket of other protocol.
(0001138)
zesstra   
2009-05-22 06:19   
Mhm, that would be a different semantic compared to the current one. You could think of mmapping a file to some memory page(s), directly use that as buffer and transfer it. Possible, and reportedly faster then lseek()+read(). Using sendfile() may be another approach, but I don't know, if sendfile() is POSIX and widely supported. But in both cases, it is very different to the current cat(), which transfers a range of lines, not the complete file or a range of bytes.
So probably it would be better to use a differently named efun() (e.g. sendfile()) for this.
How often do you transfer (large) files directly without any pre-processing?
(0001140)
lynx   
2009-05-22 07:01   
We do have situations where swfs, applets, javascripts and graphics need to come from the same host as the http application, and I increasingly like to implement web applications on top of psyced because of its decentralized multi-user awareness.

But if ldmud/psyced were a rock solid httpd, I would probably kick out Apache, migrate all websites... saving one IP address and simplifying my general web technology configuration. I have some DJ mixes for download etc, so files can enter the hundreds of megs range.

Then again, I might be a borderline case.

Other thoughts go into direction of doing file sharing or pubsub apps using the userbase.. throwing MP3s at PSYC sockets in order to have them distributed to all subscribers in realtime.. sendfile(2) allows for using incoming TCP sockets instead of files as the source, which is interesting, too.

So I guess you are right, cat() is a candidate for simul_efun. sendfile() or something like it is the thing.
(0001141)
lynx   
2009-05-22 07:05   
(Last edited: 2009-05-22 07:05)
Heheh .. wait... the LPC tradition is to have implicit sockets tied to objects.. therefore, sendfile(inobject, outobject...) is too much like socket libs.

cat() already uses the implicit output socket being this_interactive(), now if the source can be an interactive object instead of string - poof, you are copying data from that interactive's socket to this interactive's socket without even changing the lpc API much.

(0001142)
zesstra   
2009-05-22 07:14   
You are certainly a borderline case. ;-) At least compared to all muds, which don't really transfer large files as raw data. And additionally, I think some sendfile() on the telnet socket will break something. ;-) So, it is something which can only be used on other (TCP) sockets.
I guess, if somebody wants to work on it, I don't object, by I personally would probably do other things first. I looked up sendfile() and found out, that it is not standardized in any way and its use in portable programs is discouraged. That suggests using mmap() to me for implementing sendfile().
(0001143)
zesstra   
2009-05-22 07:23   
You are changing the _semantics_ and the API of cat() significantly. cat() counts _lines_ in textfiles (which don't really exist in random files) and transfers the desired range of lines.
What you suggest can not attempt to count lines if its purpose is to efficiently transfer (large) binary files, you can either transfer a complete file or a range [byte_x...byte_y].
And using an object as source for cat() instead of a string describing the location of a file is also a major change in API, although that can be alleviated a bit by using 'mixed'.
And then cat has to raise a privilege violation, because you can't allow random objects to copy raw data from the socket of one interactive to the socket of another interactive.
(0001144)
lynx   
2009-05-22 07:37   
Uh oh.. always neglecting some details like the *lines* feature of cat() which would require some #define CAT_USE_BYTES flag to make sense for binary files.

Ok, let's send the cat() to simul-efun-wonderland and think of sendfile() elsewhere...
(0001148)
fufu   
2009-05-23 18:07   
I'm for removing cat() as well. Here's a possible sefun replacement (depending on the mudlib it may require some efun:: prefixes):

#define CAT_MAX_LINES 50

varargs int cat(string file, int start, int num)
{
    if (extern_call())
        set_this_object(previous_object());

    int more;

    if (num < 0)
        return 0;

    if (!start || !this_player())
        start = 1;

    if (!num || num > CAT_MAX_LINES) {
        num = CAT_MAX_LINES;
        more = strlen(read_file(file, start+num, 1));
    }

    string txt = read_file(file, start, num);
    if (!txt)
        return 0;

    tell_object(this_player(), txt);

    if (more)
        tell_object(this_player(), "*****TRUNCATED****\n");

    return strlen(txt & "\n");
}

Where do we want to put compatibility sefuns? How about ${TOP}/mudlib/deprecated/cat.c for this one?
(0001149)
fufu   
2009-05-23 18:08   
Sorry, the ' || !this_player()' condition belongs to the previous if. (It was an afterthought, and I pasted it to the wrong location.)
(0001152)
zesstra   
2009-05-25 09:59   
Ok, then it is decided. I will take care of this soon.
${TOP}/mudlib/deprecated/ sounds good to me. Additionally, we might include a ${TOP}/mudlib/deprecated/simul_efun.c which #includes all the single files (each coding one removed efun as sefun) in that directory.
(0001161)
zesstra   
2009-05-26 07:53   
efun marked as deprecated in r2593.
I move this bug to 3.5 and set the target version to 3.5.1 for removal. I will add the sefun Fuchur suggested later today or tomorrow.
(0001192)
zesstra   
2009-06-03 18:06   
cat() was removed in r2627.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
579 [LDMud 3.5] LPC Compiler/Preprocessor feature always 2008-09-30 05:19 2009-06-01 09:03
Reporter: Gnomi Platform: i686  
Assigned To: OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Allow struct prototypes and definitions to be in different programs
Description: I had a talk with Bardioc@Evermore about not being able to put struct and function prototypes into one file und define them later in another file.

The driver cannot handle this, because it internally identifies structs in function argument lists directly by its struct_type_t, and both, the original struct_type_t and its entry in the argument type list, may be problematic to modify later on when its true definition appears. That's why it requires a struct prototype to be defined in the same file.

So what's needed is a struct table just like the function table with its ability to complete a prototype by an inheritor later on, where then the argument type would just point into. (And if we want to have a lot of fun we can try to make re- and cross-definitions possible. ;-)
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
640 [LDMud 3.3] Portability minor N/A 2009-05-22 06:55 2009-05-28 16:16
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Support mmap() for allocating memory from the system
Description: Our allocators usually try to use sbrk()/brk() for getting memory from the system and replace the system malloc. If this does not work, the fall back to allocate memory with malloc().
sbrk/brk() is declared legacy in SUSv2 and removed in POSIX.1-2001. Darwin has the functions, but brk() is basically a noop and sbrk() can only adjust the break value within 4MB.
Therefore we should introduce support to get memory by mmapping anonymous pages into our virtual address range. This will support REPLACE_MALLOC on Darwin/MacOS again (and maybe on other systems). When support for brk/sbrk() vanishes in mainline OS, we may remove brk() eventually.
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files: 0001-Use-mmap-for-getting-memory-from-the-system-slaba.patch (6,249 bytes) 2009-05-26 17:16
http://ldmud.eu/file_download.php?file_id=242&type=bug
0002-Use-mmap-for-getting-memory-from-the-system-small.patch (6,988 bytes) 2009-05-26 17:16
http://ldmud.eu/file_download.php?file_id=243&type=bug
0003-Removed-amalloc-afree-MALLOC_ALIGN-and-MEM_ALIGN.patch (14,690 bytes) 2009-05-26 17:16
http://ldmud.eu/file_download.php?file_id=244&type=bug
Notes
(0001165)
zesstra   
2009-05-26 17:20   
I attached 3 patches for adding mmap support to slaballoc.c and smalloc.c
The third patch removes amalloc() and MALLOC_ALIGN. The reasoning for this is:

If we replace the system malloc, we defined amalloc() to get aligned memory.
These function used MEM_ALIGN and MALLOC_ALIGN. Unfortunately it contained
an overflow (it reserved MALLOC_ALIGN-MEM_ALIGN, but wrote up to
MALLOC_ALIGN chars).
Additionally, it never worked. If using slaballoc/smalloc/sysmalloc,
MEM_ALIGN and MALLOC_ALIGN were always equal and in case of xptmalloc
MALLOC_ALIGN was always <= MEM_ALIGN. Therefore, amalloc never added
anything for alignment.
Furthermore, if malloc/amalloc() should use the same alignment as the system
allocator, our amalloc() was not sufficient.
We may re-introduce allocator functions for aligned (other than the word_t which the allocators guarantee) memory if needed (the driver does obviously not), but then we should do it properly (and ensure to have the same alignment as the system allocator).
(0001173)
zesstra   
2009-05-28 16:16   
This should be resolved by r2604 - r2606.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
635 [LDMud 3.3] Compilation, Installation major N/A 2009-05-13 16:17 2009-05-28 09:46
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Use -fwrapv by default if available and the compiler is gcc
Description: The overflow of signed integers is undefined behaviour according to the C standard. While usually a wrap to -INT_MAX occurs and it is a fairly common assumption among C programmers (and often used), modern gcc (and maybe other compilers) may generate code with the assumption, that such a wrap-around does not happen. Unfortunately we have some (yet mostly unidentified) pieces of code which assumes the wrapping behaviour. This will silently behave different than intended and may cause who-knows-what problems.

Until we have had time to analyze our code with respect to this problem, I suggest to add the compiler switch -fwrapv to CFLAGS by default to enforce wrapping in case of signed integers. This will not help users of other compilers, but reduces the number of affected people at least.

The downside is: enabling this option disables some optimizations, most prominently concerning loops. ("When a loop uses a signed integer index, the compiler can do much better when it doesn’t have to consider the possibility that the index will overflow." from http://www.airs.com/blog/archives/120)
But actually, I don't see alternatives until we checked our code. Users could remove the -fwrapv if they are willing to take the risk.
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files: 0003-Added-check-for-the-support-of-fwrapv.patch (1,261 bytes) 2009-05-13 17:33
http://ldmud.eu/file_download.php?file_id=238&type=bug
Notes
(0001104)
zesstra   
2009-05-13 16:34   
Ah, BTW: does anybody know the simplest way to detect in autoconf if a compiler supports -fwrapv? ;-)
An alternative may be -fno-strict-overflow, but that is supported only by newer gcc. BTW: I don't exactly get the difference between the two until now.
(0001105)
zesstra   
2009-05-13 17:39   
I added an experimental patch for checking the support of -fwrapv in in the attached patch. Maybe we want to do some benchmarks for checking the impact, although I don't have a reasonable benchmark suite for LDMud. Does anybody have? But... Speed is less important than obscure bugs, crashes and exploits...
(0001106)
fufu   
2009-05-14 09:11   
-fstrict-overflow affects both integer arithmetic (unless -fwrapv is set) and pointer arithmetic. (An instance of the latter is simplifying p + x > p to x > 0 if p is a pointer.)

-fwrapv makes integer overflows fully defined, even if -fstrict-overflow is set.

I think -fwrapv is what we want. The patch looks fine to me, except for this extra "check":

checking check whether compiler supports -fwrapv...... yes
(0001114)
zesstra   
2009-05-18 16:30   
Our configure checks for several compiler switches. I had the idea to use the same autoconf macro for all of them and re-wrote my first patch to include the following macro. It adds supported switches for all environment variables which are specified in a list. Unfortunately, I am not sure about the portability of the shell code:
dnl Check if the compiler in use supports the given argument as command-line
dnl switch and adds it to CFLAGS and EXTRA_CFLAGS if supported.
AC_DEFUN([LD_CHECK_CC_SWITCH], [
    ld_cc_switch_savecflags="$CFLAGS"
    CFLAGS="${CFLAGS} $1"
    AC_MSG_CHECKING([whether compiler supports $1])
    AC_COMPILE_IFELSE(
      [AC_LANG_PROGRAM(
        [[]],
        [[]])],
      [AC_MSG_RESULT([yes])]
      CFLAGS="$ld_cc_switch_savecflags"
      for v in $2; do
          todo="$v=\"`echo ${!v}` $1\"";
          eval "$todo";
      done,
      [AC_MSG_RESULT([no])]
      CFLAGS="$ld_cc_switch_savecflags"
    )
    ]
)

Could anybody comment? The other possibility would be to add a macro for every environment variable where compiler switches are added...
(0001153)
zesstra   
2009-05-25 10:09   
I will take care of including this switch into our configure. Additionally, I guess, this is a candidate for being back-ported to 3.2?

I am still unsure how to consolidate all compiler option checks into one autoconf macro, because I guess, the code in the for loop is not portable enough... On the other hand, we might postpone it... ;-)
(0001171)
zesstra   
2009-05-28 09:46   
-fwrapv was added to the default compiler flags in r2602, if supported by the compiler.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
133 [LDMud 3.5] LPC Compiler/Preprocessor feature N/A 2004-09-30 12:05 2009-05-26 10:18
Reporter: lars Platform:  
Assigned To: OS:  
Priority: low OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Faster function calls
Description: Calls to private/nomask functions could be made faster by skipping the argument massaging done for normal functions. Since the functions are private/nomask, the number of arguments taken is known at compile time and can be adjusted there.

Omitting the control frame as well would be possible by storing the previous pc/ap on the stack as well, but for that we would need to mark these functions as inlineable in order to generate the correct 'return' code. This is probably just not worth it.

A simple benchmark is in order, I think.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001130)
lynx   
2009-05-22 03:50   
Cool. Motivation to put a lot of "private" everywhere! ;)
(0001162)
zesstra   
2009-05-26 10:18   
I don't have any hard facts/benchmarks here, but I once wrote some functions containing only a few instructions for implementing a kind of ring buffer in LPC. In the end, the function call overheads were so big, that arr=({foo}) + arr[1..]; was significantly faster (until a host system dependent size, typically around 70-110).
In such cases, it would be interesting to save setting up the control frame and argument massaging.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
642 [LDMud 3.5] Implementation minor N/A 2009-05-26 10:01 2009-05-26 10:01
Reporter: zesstra Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Check code which assumes a defined overflow behaviour of signed integers
Description: The overflow of signed integers is undefined behaviour according to the C standard. While usually a wrap to -INT_MAX occurs and it is a fairly common assumption among C programmers (and often used), modern gcc (and maybe other compilers) may generate code with the assumption, that such a wrap-around does not happen. Unfortunately we have some (yet mostly unidentified) pieces of code which assumes the wrapping behaviour. This will silently behave different than intended and may cause who-knows-what problems.

We have enabled -fwrapv with gcc in 0000635. However, this doesn't help for other compilers and it impairs gcc's ability to optimize. Therefore we should check our code for assumptions of a defined wrap-around behaviour of signed integers. After that we can remove -fwrapv again.

The option -Wstrict-overflow=x of gcc may help us to identify such code pieces.

I guess we should discuss here as well, how to deal with such code and reliably add (signed) integers. There are suggestions which involve a massacre of #defines (see below) but are ugly as hell...
Tags:
Steps To Reproduce:
Additional Information: http://www.fefe.de/intof.html
http://www.gnu.org/software/hello/manual/autoconf/Signed-Overflow-Advice.html#Signed-Overflow-Advice
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
639 [LDMud 3.3] LPC Language feature have not tried 2009-05-22 04:24 2009-05-22 05:16
Reporter: lynx Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.3.718  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: hash table data type?
Description: Congratulations LDMUD team for cleaning up most of the bugs that had accumulated in mantis! Looking forward to try out the fixes and hoping for greater stability!
Time for an actual old-fashioned feature request.. or rather, an inquiry.

I noticed ldmud only runs a few real hash tables.. like the object name table and the shared string table. Things that one imagines to be hash tables like mappings and switches are actually implemented by binary trees or similar.

This sure made sense in the days of tight memory conditions, but not all of us have to consider memory over performance. Turning switches into hashes is probably pointless, unless we can make very good use of the fact, that we know how many elements are in the switch. Our "mudlib" uses lots of extralarge switches.

Having an option to compile mappings as hashes would affect the behaviour of an ldmud application dramatically.. might be an interesting thought.

The completely-in-control option would be to have an actual 'hash' data type which behaves pretty much like mappings, but uses more memory and gives you more performance in exchange.

We'd probably consider rewriting some of those huge switches into shared hashes, if the performance is worth it. I bet every mud these days has a bunch of large central mappings and switches that may be worth implementing as a hash instead.

But maybe I'm completely naive on the actual performance gains and the whole thing being worth the hassle.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001134)
zesstra   
2009-05-22 05:16   
Mhmm. Some short first comment concerning the mappings:
they are implemented as a kind of hybrid containing a hashed part and a condensed part. All changes end up first in the hash part and are being compacted by the backend after some time without additions/deletions. This time is configurable (TIME_TO_COMPACT, typically 10min), although not by configure right now. If you really want to have mappings contain only the hash table, you may try to set this time really high for the moment (although a garbage collection compacts them nonetheless).
It would be interesting to make a benchmark with mappings containing only the hash part ('dirty' mappings) and with mappings fully condensed...

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
211 [LDMud] Networking feature N/A 2004-11-26 22:57 2009-05-19 18:08
Reporter: lars Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.8 and before  
Product Build: Resolution: duplicate  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Sychronous write()
Description: Subject: Synchronous write()
From: Lars
Date: 991104
Type: Feature
State: Unclassified

When writing data to the network, the driver drops messages when
encountering an EWOULDBLOCK.

This is ok for normal game usage, but deadly when used as e.g. httpd.
Either a synchronous write() is implemented (not easy, as it requires
buffering in the comm.c module) and/or we implement the TCP efuns.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001122)
Gnomi   
2009-05-19 18:08   
Write buffers were implemented in r2489 and since r2551 the size of the buffer can be changed per connection.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
622 [LDMud 3.3] Runtime crash have not tried 2009-04-08 19:10 2009-05-11 03:55
Reporter: garapol Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.717  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version:  
Summary: GeoLiteCity as big switch-blocks crashes on high usage
Description: I crashed avalon while trying some code for the usage of GeoLiteCity.
I converted the csv file to 324 files (many very small, many around 250 KB code). There is one "central" master, which is called.
Each of theese 324 files is a big switch-case block, having up to 5000 cases.
For some IP-Address (x,y,z,w) to lookup the master calls the file x.c, which may call x_2.c and so on.

I crashed avalon by a stress test, where I got all IP addresses of any logged in user (around 35) and tryed to ask the master where they came from.

Tags:
Steps To Reproduce:
Additional Information: The exact code, which crashes was:
zlpc map(map(map(users(), (: ({$1})+explode(query_ip_number($1), ".") :)), (: ({$1[0], "/w/garapol/temp_neu/GeoLiteCity"->query_town($1[1],$1[2],$1[3],$1[4],1) }) :)), (: tell_object(OBJ(garapol), $1[0]->query_name()+"\t -> " + $2) :))

I have only added some examples of ranges, because I got some Mantis error on uploading the big files...
If you need all files, compile and start the GeoLiteCityConverter.java in the directory both GeoLiteCity.csv and iso_country_names.txt are.

For the crash-code I am sure the problem may be, the compiler have too much to do (or load) on a second... but I am not sure.
Attached Files: avalon_absturz.zip (67,332 bytes) 2009-04-08 19:10
http://ldmud.eu/file_download.php?file_id=205&type=bug
Notes
(0001014)
garapol   
2009-04-08 19:12   
Sorry, I got some internal server errors (0000401) of Mantis and tryed again and again... this time it worked and added the file...
Please delete the other issues.
(0001015)
Gnomi   
2009-04-09 03:06   
What messages were on stdout or in the debug.log prior to the crash?
Do you have a backtrace ('gdb <ldmud binary> <core dump file>' and there 'bt f')?
(0001016)
Gnomi   
2009-04-09 03:10   
There is btw a mistake in the zlpc command. The arguments to query_town() are strings (results from explode()), but query_town() expects ints.
(0001017)
zesstra   
2009-04-09 10:17   
Gnomi found one problem with very large switches. A jump offset was wrongly calculated due to a signed/unsigned short confusion. He committed a fix in r2540 in the trunk.
I guess, any further investigation relies on the debug log and a core dump (or at least stack trace).

The best approach would be to reproduce the problem with 717 in some testmud and then try the current trunk.
I quickly tried the code generator, but it aborted due to some missing class. As I don't want to spend time on working on meta-problems I would appreciate if you make the complete code/testcase available for download or send it bzip2-compressed by mail to me (lets exchange mail addresses via Intermud).
(0001018)
fufu   
2009-04-09 11:03   
I managed to run the generator after downloading the csv database from http://www.maxmind.com/app/geolitecity.

I have not been able to make it crash though (tried with 3.3.717 and a relatively recent svn version, without Gnomis patch). Things I tried:

xlpc for (; get_eval_cost() > 100000; ) "/players/fuchur/geolite/GeoLiteCity"->query_town(random(256), random(256), random(256), random(256), 1);

xlpc for (int i = 0; i < 256; i++) "/players/fuchur/geolite/GeoLiteCity"->query_town("" + i, "" + random(256), "" + random(256), "" + random(256), 1);

(I tried the provided crashing command as well, but there was only one user, coming from 127.0.0.1, so unsurprisingly it didn't do much.)
(0001021)
garapol   
2009-04-12 17:29   
Last lines of Debug-Log of Avalon (tail):
It really seems to be that signed/unsigned thing.

2009.04.08 20:13:47 Bad stack after evaluation.
sp: 8151590 minimum expected: 8151598
Instruction 53(!=), num arg -1
2009.04.08 20:13:47 Current object was w/garapol/temp_neu/GeoLiteCity84
2009.04.08 20:13:47 Dump of the call chain:
2009.04.08 20:13:47 get_line_number(): Illegal offset -15079 in object w/garapol/temp_neu/GeoLiteCity84.c
' z_lpc' in 'i/zepter/zepter.c (/i/zepter/zmarker.inc)' (' obj/zepter#955457') line 359
' start_lpc' in 'i/zepter/zepter.c (/i/zepter/zmarker.inc)' (' obj/zepter#955457') line 269
' fun' in ' w/garapol/LPC_zst.c' (' w/garapol/LPC_zst') line 10
'__inline_w_garapol_LPC_zst_c_10_#0001' in ' w/garapol/LPC_zst.c' (' w/garapol/LPC_zst') line 10
' query_town' in 'w/garapol/temp_neu/GeoLiteCity.c' ('w/garapol/temp_neu/GeoLiteCity') line 69
'query_geocity_town' in 'w/garapol/temp_neu/GeoLiteCity.c' ('w/garapol/temp_neu/GeoLiteCity') line 48
' query_town' in ' UNDEFINED' ('w/garapol/temp_neu/GeoLiteCity84') line 0
(0001095)
zesstra   
2009-05-10 17:30   
Can we assume, that was fixed by Gnomis change? Or is there any new information?
(0001100)
garapol   
2009-05-11 02:14   
Avalon uses another system, but I am sure Gnomi found the bug. But I did not try.
(0001101)
zesstra   
2009-05-11 03:53   
Apparently fixed by Gnomi in r2540.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
634 [LDMud 3.3] Portability major N/A 2009-05-05 15:49 2009-05-10 12:55
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: high OS Version: 10.5.x  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Overflow of number_buffer in object.c
Description: save_svalue() in object.c uses the static buffer number_buffer to store a textual representation of numbers. sprintf() is used to write into the buffer. Its size is 36, which should be sufficient for even 64 bit integers and our floats.
But Gnomi noticed, that the buffer size was not sufficient in one case, where the exponent of a float was printed as 32 bit integer (0xffffffff).

1) This should IMHO not happen.
2) The buffer should only be written with a sprintfn(...,sizeof(number_buffer),...)
to prevent such overflows.
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0001093)
zesstra   
2009-05-10 12:55   
Fixed in r2579 by writing the exponent as a uint16_t.

I could not reproduce the issue, but Gnomi found out, that on his system (glibc-...) PRIx16 was defined to be %x, although int16_t is a short on that system. This is plain wrong according to the manpage of sprintf. Despite this, SCNx16 is %hx.
Additionally all sprintf(), which write into number_buffer were replaced by snprintf().

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
615 [LDMud 3.3] Implementation minor N/A 2009-03-13 17:45 2009-05-10 09:39
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: RfC: Replace SINT in slaballoc.c/smalloc.c by sizeof(word_t)
Description: During tracing 0000611 I noticed that in slaballoc.c and smalloc.c the define SINT (SIZEOF_CHAR_P) is heavily used as the size of a word. I don't know the origin of SINT, but I think the semantic of it is not very apparant and there isn't even a comment.

a) One suggestion is to replace it by a sizeof(word_t), because it is used as such. sizeof(word_t) is the same as SIZEOF_CHAR_P [0], because word_t is typedef'ed to p_uint and p_(u)int are integers with the same size as a pointer.
b) Another possibility is, to give SINT a new name which directly reflects meaning as sizeof(word_t). But I don't think, SIZOF_WORD_T is any better than sizeof(word_t).
c) And the third one: replace calculations with char* (e.g. block + 8*sizeof(word_t)) by the corresponding ones with word_t*, e.g. (word_t)block + 8, which is the most effort, but IMHO the cleanest approach. I would see it more as independent measure to a) or b).

[0]: I am not sure, but I think the standard allows pointers to have different sizes, e.g. sizeof(void*)!=sizeof(int*). On systems like that we may be in rather bad shape...

Do you have any opinions about this?
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000996)
zesstra   
2009-03-13 17:52   
BTW:
the comment about CHUNK_SIZE says: "make sure that the resulting chunk sizes are SINT aligned."
We may discuss replacing
#define MEM_ALIGN (SIZEOF_CHAR_P)
by
#define MEM_ALIGN (sizeof(word_t))
as well.
(0000998)
fufu   
2009-03-13 19:14   
I don't like the idea of replacing a dedicated #define, however ill-named, by an anonymous sizeof().

How about renaming SINT to GRAN for "granularity"? We can then define MEM_ALIGN as GRAN.

I have no opinion on whether sizeof(word_t) is better than SIZEOF_CHAR_P.

slaballoc.c uses the same definitions, so whatever changes we decide on should be made in both smalloc.c and slaballoc.c.
(0001000)
zesstra   
2009-03-13 20:02   
Usually I would agree. But in this case I am not sure. Both allocators base on word_t:
* Allocations are measured in 'word_t's which are the same size as void*.

Which means, that you anyway can't change SINT/GRAN/whatever from being sizeof(word_t), because first you would have to decouple the rest of the file from word_t - which is a lot. And I would not see any reason to do so at the moment, because word_t is already an abstraction which can be changed.
We might decide not to base the allocations on void*/p_uint and increase/decrease granularity. But in any case we would IMHO just change word_t. (Ok, maybe something breaks in that case, because some code may rely on word_t being the size of void*/p_uint.)
(0001050)
zesstra   
2009-04-16 17:07   
Ok... The state is now, that we can't change any granularity and word_t independently.
Maybe de-coupling the two things is a nice idea, but I won't do now, because it is a lot of work and IMHO not that important (any other volounteers?).

I can use a better-named enum/define, but until someone checks the complete allocator, that will be IMHO very incomplete (and at some points may be even mis-used). Therefore I am not sure, if this does not lead to confusion (the false impression that we could change a granularity independently of word_t and that all uses of GRAN are correct). A comment may alleviate that somewhat. But for a long time (if not forever), any GRAN has to be sizeof(word_t).
(0001089)
zesstra   
2009-05-10 09:39   
Ok, I want this from my to-do list.
I replaced SINT by GRANULARITY and defined MEM_ALIGN to be GRANULARITY in r2575.
(BTW: I had to replace an #if by if, but as the expression is constant, the compiler will remove the if anyway.)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
624 [LDMud 3.3] Portability crash always 2009-04-13 23:13 2009-05-06 16:25
Reporter: wedsall Platform: x86_64  
Assigned To: zesstra OS: GNU/Linux  
Priority: low OS Version: 2.6.22.5  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Crash in included crypt() implementation on platforms with sizeof(long)==8 (e.g. x86_64)
Description: Hello!
 Well, there isn't much information to go by but I'm trying to compile on 64 bit suse 10.3 and not having luck.

 I was able to get the bare bones dev version of the game to start up and I could connect, but it disconnects as I enter my password. There is a small bit of debug information after this password is entered, it is pasted below in additional information.

 As always, thank you all for the hard work.
Tags:
Steps To Reproduce:
Additional Information: Linux df 2.6.22.5-31-default 0000001 SMP 2007/09/21 22:29:00 UTC x86_64 x86_64 x86_64 GNU/Linux

Apr 13 23:06:01 df kernel: ldmud[8496]: segfault at 00002b4d97045874 rip 00000000004930c8 rsp 00007fff14b71860 error 4

df:/home/dragonfire/logs # more 04-13-2009-22\:36\:01.DF.err
2009.04.13 22:35:02 [xerq] XERQ Apr 13 2009: Path 'erq', debuglevel 0
2009.04.13 22:35:02 [xerq] Demon started
[xerq] read: No such device or address
2009.04.13 22:35:02 [xerq] Demon exiting.

df:/home/dragonfire/logs # more 04-13-2009-22\:36\:01.debug.log
2009.04.13 22:35:02 LDMud 3.3.718 (Build 2483) (stable)
2009.04.13 22:35:02 mySQL 5.0.45
2009.04.13 22:35:02 Attempting to start erq '/home/dragonfire/bin/erq'.
2009.04.13 22:35:02 Hostname 'df' address '127.0.0.1'
2009.04.13 22:35:02 UDP recv-socket requested for port: 2000

Here's what i'm using for a configuration file. I tried the cflags settings listed in the INSTALL file but this produced the same results.

#!/bin/sh
#
# Settings for a compat-mode driver for Dragonfire mud.
# by Nostradamus
# configure will strip this part from the script.
# --with-malloc=ptmalloc \
# --enable-share-variables=yes \
# --enable-use-pthreads=yes \
# export CFLAGS="-m64 -mtune=core2"
# export LDFLAGS="-m64 -mtune=core2"
# export EXTRA_CFLAGS=$CFLAGS

#--enable-use-mysql=/usr/lib/mysql \

./configure \
--prefix=/home/dragonfire \
--bindir=/home/dragonfire/bin \
--libdir=/home/dragonfire/lib \
--libexec=/home/dragonfire/libexec \
--enable-compat-mode \
--enable-erq=xerq \
--enable-lpc-nosave \
--enable-dynamic-costs \
--enable-opcprof \
--enable-verbose-opcprof \
--enable-use-structs \
--enable-use-new-inlines=yes \
--enable-use-system-crypt=no \
--enable-use-deprecated=no \
--enable-malloc-trace=yes \
--enable-use-pcre=yes \
--enable-use-alists=yes \
--enable-use-pgsql=no \
--enable-use-mccp=yes \
--enable-share-variables=no \
--enable-filename-spaces=yes \
--enable-malloc-lpc-trace=yes \
--with-read-file-max-size=200000 \
--with-max-byte-transfer=200000 \
--without-wizlist-file \
--with-optimize=no \
--with-master-name=secure/master \
--with-time-to-reset=900 \
--with-portno=1998 \
--with-udp-port=2000 \
--with-max-cost=2100000 \
--with-max-malloced=0 \
--with-min-malloced=0x80000 \
--with-min-small-malloced=0x80000 \
--with-otable-size=8192 \
--with-htable-size=32768 \
--with-apply-cache-bits=14 \
--with-time-to-swap=0 \
--with-time-to-swap-variables=0 \
--with-max_net_connects=100 \
--enable-debug \
--with-erq-debug \
--with-swap-file=DF_SWAP



This is written to the debug log after entering password info:
2009.04.13 23:10:34 Error in master_ob->preload()
2009.04.13 23:10:34 LDMud ready for users.
2009.04.13 23:10:43 New player at socket 7.
2009.04.13 23:10:43 Dont END OF RECORD
2009.04.13 23:10:43 Do STATUS
2009.04.13 23:10:43 Wont ENVIRON
2009.04.13 23:10:43 Will NAWS
2009.04.13 23:10:43 Will NEWENV
2009.04.13 23:10:43 Dont MUD COMPRESS2
2009.04.13 23:10:43 Will TERMINAL TYPE
2009.04.13 23:10:43 Will TSPEED
2009.04.13 23:10:43 Wont XDISPLOC
2009.04.13 23:10:43 Dont MUD EXTENSION
2009.04.13 23:10:43 Do SUPPRESS GO AHEAD
2009.04.13 23:10:43 Will LINEMODE
2009.04.13 23:10:43 Will BINARY
2009.04.13 23:10:44 Do ECHO

Attached Files: bt.full (11,051 bytes) 2009-04-14 10:10
http://ldmud.eu/file_download.php?file_id=206&type=bug
bt.full-dev (3,919 bytes) 2009-04-14 10:10
http://ldmud.eu/file_download.php?file_id=207&type=bug
0001-Removed-support-for-obsolete-platforms-in-hosts.patch (254,566 bytes) 2009-04-16 14:20
http://ldmud.eu/file_download.php?file_id=209&type=bug
0002-Removed-use-system-crypt-from-configure.patch (3,462 bytes) 2009-04-16 14:20
http://ldmud.eu/file_download.php?file_id=210&type=bug
Notes
(0001025)
wedsall   
2009-04-13 23:43   
Some extra debugging:

slaballoc: no reorder: this 00002b8f445428e8 free 22, no next
slaballoc: alloc (80 + 16) 96 bytes -> [3]
slaballoc: block 00002b8f44568ed0 from freelist (next 00002b8f44568f30), slab 00002b8f44567d60 free 15
slaballoc: alloc (120 + 16) 136 bytes -> [8]
slaballoc: freshmem 00002b8f444fd8d8 from 00002b8f444fc310..00002b8f44500688
slaballoc: free 00002b8f43552858, offset 861, small 1
slaballoc: -> slab 00002b8f43550d70 [6], freelist 00002b8f43552d80, 22 free
slaballoc: no reorder: this 00002b8f43550d70 free 23, no next
slaballoc: alloc (80 + 16) 96 bytes -> [3]
slaballoc: block 00002b8f44568f30 from freelist (next 00002b8f44568f90), slab 00002b8f44567d60 free 14
2009.04.13 23:41:57 [xerq] select() returns 1, time() 1239680517
2009.04.13 23:41:57 [xerq] New command from driver.
[xerq] read: Success
2009.04.13 23:41:57 [xerq] Demon exiting.
(0001026)
zesstra   
2009-04-14 04:54   
Well, thanks for the report. Unfortunately, this doesn't tell too much so far. We need at least a stack trace when the driver segfaults or a core dump. You could start the driver in a gdb session and list the stack trace after the segfault with 'bt full' or issue a 'ulimit -c unlimited' in the shell before you start the driver. Then a core dump will be written upon crashes in the / of the mudlib (which you can load into gdb and get the stack trace).

Some additional comments:
- The compiler settings from the INSTALL are an example from _my_ machine. The compiler settings you need for generating 64bit executables with your gcc may be different. Especially if you don't have any Intel Core-Duo processor, you should NOT use -mtune=core2.
- Are you using a plain 3.3.718 (without any patches/modifications)?
- Could you add the output of 'file' for the crashing ldmud executable and the ouput of 'gcc -v'?
- if you change compiler settings altering the architecture of the executable, please issue a 'make distclean' before calling 'configure'. Not doing this may create all sorts of problems leading to crashes.
- You may add a -ggdb3 for maximum debug information to the DEBUG variable in the Makefile.
- If the problem is completely reproducable, you could attempt to make a minimal test case (including minimal needed mudlib) so that we can try to reproduce it as well.
(0001027)
wedsall   
2009-04-14 09:22   
Hello!
 - Compiler settings. I'm not sure what to use, this is beyond me right now.
 - Version. I've used both a vanilla version and my own version with two patches. I am seeing the same crash on a vanilla 3.3.718 as my patched version. I will include results from both versions just in case.
 - ldmud: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.4, dynamically linked (uses shared libs), not stripped
   Using built-in specs.
Target: x86_64-suse-linux
Configured with: ../configure --enable-threads=posix --prefix=/usr --with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.2.1 --enable-ssp --disable-libssp --disable-libgcj --with-slibdir=/lib64 --with-system-zlib --enable-shared --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --program-suffix=-4.2 --enable-version-specific-runtime-libs --without-system-libunwind --with-cpu=generic --host=x86_64-suse-linux
Thread model: posix
gcc version 4.2.1 (SUSE Linux)
- Distclean - i will try this but i've used a brand new download of ldmud and recieved the same result.

- I will try the -ggdb3 next.
(0001028)
wedsall   
2009-04-14 09:23   
Here is the gdb output from the current crash, without the ggdb3 flag.

df:/home/dragonfire/bin # gdb -c ../lib/core ldmud
GNU gdb 6.6.50.20070726-cvs
Copyright (C) 2007 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-suse-linux"...
Using host libthread_db library "/lib64/libthread_db.so.1".
Reading symbols from /lib64/libnsl.so.1...done.
Loaded symbols for /lib64/libnsl.so.1
Reading symbols from /lib64/libm.so.6...done.
Loaded symbols for /lib64/libm.so.6
Reading symbols from /usr/lib64/libidn.so.11...done.
Loaded symbols for /usr/lib64/libidn.so.11
Reading symbols from /usr/lib64/libpcre.so.0...done.
Loaded symbols for /usr/lib64/libpcre.so.0
Reading symbols from /lib64/libz.so.1...done.
Loaded symbols for /lib64/libz.so.1
Reading symbols from /lib64/libc.so.6...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Core was generated by `/home/dragonfire/bin/ldmud --debug-file DF.debug.log'.
Program terminated with signal 11, Segmentation fault.
#0 0x00000000004930d0 in f_functionlist (sp=0x76a120) at object.c:1883
1883 flags = fun[j];
(gdb)
(0001029)
wedsall   
2009-04-14 09:27   
As I mentioned yesterday I have a development mudlib. I'm getting a different gdb result from this. Here it is:
df:/home/dragonfiredev/bin # gdb -c ../dev-lib/core ldmud
GNU gdb 6.6.50.20070726-cvs
Copyright (C) 2007 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-suse-linux"...
Using host libthread_db library "/lib64/libthread_db.so.1".

warning: core file may not match specified executable file.
Reading symbols from /lib64/libnsl.so.1...done.
Loaded symbols for /lib64/libnsl.so.1
Reading symbols from /lib64/libm.so.6...done.
Loaded symbols for /lib64/libm.so.6
Reading symbols from /usr/lib64/libidn.so.11...done.
Loaded symbols for /usr/lib64/libidn.so.11
Reading symbols from /usr/lib64/libpcre.so.0...done.
Loaded symbols for /usr/lib64/libpcre.so.0
Reading symbols from /usr/lib64/libmysqlclient.so.15...done.
Loaded symbols for /usr/lib64/libmysqlclient.so.15
Reading symbols from /lib64/libz.so.1...done.
Loaded symbols for /lib64/libz.so.1
Reading symbols from /lib64/libc.so.6...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/libcrypt.so.1...done.
Loaded symbols for /lib64/libcrypt.so.1
Reading symbols from /usr/lib64/libssl.so.0.9.8...done.
Loaded symbols for /usr/lib64/libssl.so.0.9.8
Reading symbols from /usr/lib64/libcrypto.so.0.9.8...done.
Loaded symbols for /usr/lib64/libcrypto.so.0.9.8
Reading symbols from /lib64/ld-linux-x86-64.so.2...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Reading symbols from /lib64/libdl.so.2...done.
Loaded symbols for /lib64/libdl.so.2
Core was generated by `/home/dragonfiredev/bin/dev-ldmud -d --debug-file /home/dragonfiredev/DF.debug.'.
Program terminated with signal 11, Segmentation fault.
#0 0x00000000004c6570 in crypt (buf=0x2b881f1eb061 "",
    salt=0x2b881f11a3fa "2wSDC4Eu8m3YM") at hosts/crypt.c:543
543 ll = out[0]; l2c(ll,b);
(0001030)
zesstra   
2009-04-14 09:35   
Ok, 'gcc -v' tells, that your gcc creates executables for the x86_64 architecture by default, without any special compiler settings/options. You can leave them just as they are and don't change anything. In fact, you have to change them if you want executables for the (32bit) i386 architecture, in many cases it will be -m32.

-ggdb3 won't change anything concerning the crash itself, but it adds information used in a debugger session (live or post-mortem by using a core dump). You may have to install 'gdb' for getting a stack trace then.
(0001031)
zesstra   
2009-04-14 09:56   
The crash in Note 0000624:0001028 seems to be the same one I described in bug 0000559. That one was fixed in revision 2492 in the trunk of the driver.

The other one in crypt() is unknown to me so far.
hosts/crypt.c implements crypt() in a portable way (e.g. for systems which don't have its own crypt()). But: most modern systems, and certainly your Suse-Linux include a crypt() implementation in its glibc. I suggest to use it by NOT using --enable-use-system-crypt=no. So either make it a --enable-use-system-crypt=yes or just delete the configure option from your settings. I guess, that crash was probably not noticed for a long time, because nearly nobody used the crypt()-implementation we include in the driver. (That said, it doesn't crash on my system.)

BTW: If you get a core dump, please keep exactly the same executable around which generated it (see gdb warning 'warning: core file may not match specified executable file.'). Otherwise a core dump looses much of its usefulness. (I usually archive the core dump and the corresponding executable in one directory or tar archive.)
(0001032)
wedsall   
2009-04-14 09:56   
(gdb) bt
#0 0x00000000004937e8 in f_functionlist (sp=0x76a3c0) at object.c:1883
0000001 0x0000000000455d88 in eval_instruction (
    first_instruction=0x2b2fa18c7baa "b\037", initial_sp=0x76a360)
    at interpret.c:8148
0000002 0x000000000046d1c5 in apply_low (fun=0x2b2fa1853ac0, ob=0x2b2fa18a6968,
    num_arg=0, b_ign_prot=false, allowRefs=false) at interpret.c:16949
0000003 0x000000000046d350 in int_apply (fun=0x2b2fa1853ac0, ob=0x2b2fa18a6968,
    num_arg=0, b_ign_prot=false, b_use_default=true) at interpret.c:17027
0000004 0x0000000000468c95 in eval_instruction (
    first_instruction=0x2b2fa18589db "b­", initial_sp=0x76a320)
    at interpret.c:16297
0000005 0x000000000046efb7 in int_call_lambda (lsvp=0x76a320, num_arg=0,
    allowRefs=false) at interpret.c:18030
0000006 0x0000000000473435 in v_funcall (sp=0x76a320, num_arg=1)
    at interpret.c:20451
0000007 0x00000000004563db in eval_instruction (
    first_instruction=0x2b2fa187702a "a\003\001\037", initial_sp=0x76a300)
    at interpret.c:8297
0000008 0x000000000046eb96 in int_call_lambda (lsvp=0x76a2b0, num_arg=3,
    allowRefs=false) at interpret.c:17913
0000009 0x0000000000473435 in v_funcall (sp=0x76a2e0, num_arg=4)
    at interpret.c:20451
0000010 0x00000000004563db in eval_instruction (
---Type <return> to continue, or q <return> to quit---
    first_instruction=0x2b2f9fb06bd3 "b­", initial_sp=0x76a290)
    at interpret.c:8297
0000011 0x000000000046efb7 in int_call_lambda (lsvp=0x8784e0, num_arg=0,
    allowRefs=false) at interpret.c:18030
0000012 0x0000000000492053 in reset_object (ob=0x2b2fa18a6968, arg=4)
    at object.c:880
0000013 0x00000000004ce529 in load_object (lname=0x7fff0b095f10 "std/room",
    create_super=true, depth=1, isMasterObj=false, chain=0x7fff0b095f70)
    at simulate.c:2158
#14 0x00000000004ce0f6 in load_object (lname=0x832640 "std/room/objects",
    create_super=false, depth=0, isMasterObj=false, chain=0x0)
    at simulate.c:2045
#15 0x00000000004cedc7 in lookfor_object (str=0x2b2f9fb04e90, bLoad=true)
    at simulate.c:2426
#16 0x00000000004d2c84 in f_load_object (sp=0x76a260) at simulate.c:4499
#17 0x0000000000455b86 in eval_instruction (
    first_instruction=0x2b2fa18774fa "a\001\001\037", initial_sp=0x76a250)
    at interpret.c:8098
#18 0x000000000046cdac in apply_low (fun=0x2b2f9faf9d38, ob=0x2b2f9fb21d20,
    num_arg=1, b_ign_prot=true, allowRefs=false) at interpret.c:16836
#19 0x000000000046d350 in int_apply (fun=0x2b2f9faf9d38, ob=0x2b2f9fb21d20,
    num_arg=1, b_ign_prot=true, b_use_default=false) at interpret.c:17027
#20 0x000000000046d7a0 in sapply_int (fun=0x2b2f9faf9d38, ob=0x2b2f9fb21d20,
---Type <return> to continue, or q <return> to quit---
    num_arg=1, b_find_static=true, b_use_default=false) at interpret.c:17188
#21 0x000000000046e015 in apply_master_ob (fun=0x2b2f9faf9d38, num_arg=1,
    external=false) at interpret.c:17491
#22 0x0000000000411254 in preload_objects (eflag=0) at backend.c:1288
#23 0x000000000047f1e6 in main (argc=3, argv=0x7fff0b098338) at main.c:620
(gdb)
(0001033)
wedsall   
2009-04-14 10:11   
uploaded a full backtrace from my production lib and from my dev lib since they are producing slightly different output.
(0001034)
zesstra   
2009-04-14 10:15   
Ok, I can reproduce the crash in the crypt() from hosts/crypt.c after all (did start the wrong executable in my first test *gna*), which is a NULL pointer dereference and doesn't seem to happen on the i386 platform. I will investigate it this evening.

For the moment as immediate bugfixes: use the system crypt() for this issue. For the other crash in f_functionlist() you may either use the current trunk in our svn or extract patch for r2492 from it. (If you don't know how to do this, I could send you the patch after work, but knowing our subversion repository may be advantagous anyway. *g*)
(0001035)
wedsall   
2009-04-14 13:26   
Im trying to use the latest trunk but it freaks out immediately on make.

It seems to not like lines like this "@cdef_use_gcrypt@ USE_GCRYPT" in config.h

df:/home/dragonfire/ldmud-3.3.718-latest/src # make
./mk-patchlevel.sh
gcc -std=gnu99 -I/usr/include/pgsql -I/usr/include/mysql -g -Wall -Wparentheses -Wshadow -DMUD_LIB='"/home/dragonfire/lib"' -DBINDIR='"/home/dragonfire/bin"' -DERQ_DIR='"/home/dragonfire/libexec"' -c -o access_check.o access_check.c
In file included from driver.h:15,
                 from access_check.c:92:
config.h:348: error: stray â@â in program


Am I missing a step in preparing the trunk version before compiling?
(0001036)
Gnomi   
2009-04-14 13:35   
There is a script called autogen.sh, that should be executed to regenerate the configure script.
(0001037)
zesstra   
2009-04-14 14:08   
des_set_key() assumes that longs are 4 byte long. If the longs are 8 bytes long, the function overwrites 128 bytes following one of its buffers. Unfortunately, a pointer is located after that buffer and overwritten. This leads to a crash upon dereferencing it.
des_set_key() is designed to work in 4-byte long blocks (Shifts, Ands) and uses 16 iterations to write a 128 char long buffer in two 4-char long writes per iteration. The immediate solution would be to use a datatype with a length of 4 instead of longs.

But as we think of removing hosts/ altogether for some time, I suggest not to fix this code, but remove it. POSIX requires a crypt(), so there should be no negative consequences to always use the system crypt().
(0001038)
wedsall   
2009-04-14 14:39   
Thanks for the responses.

After running autogen.sh my production lib will compile well but still crashes on crypt.

Zesstra I'm gathering that your solution is to use the system crypt but I'm not sure how to do this. Do I need to modify the crypt.c or modify my mudlib?
(0001039)
zesstra   
2009-04-14 15:07   
No, just delete the --enable-use-system-crypt=no from your configure call in the script you use to call configure.
(0001040)
wedsall   
2009-04-15 00:40   
This appears to have resolved my problems! The mud has been running error free for about 4 hours -- migrated the sql databases and tested those.

Thank you very much for your help and consulting.
(0001046)
zesstra   
2009-04-16 14:21   
I attached two patches, which removes hosts/.
(0001084)
zesstra   
2009-05-06 16:25   
The possibility for not using the system supplied crypt() (that means: our own from hosts/) was removed in r2565 along with the whole hosts/ directory.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
625 [LDMud 3.3] Portability minor N/A 2009-04-14 13:53 2009-05-06 16:24
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Remove hosts/ subdirectory
Description: The hosts/ subdirectory contains support for several non-POSIX platforms and a system-independent implementation of crypt().
Some months ago I asked on the mailing list, if somebody uses stuff from hosts/ and volounteers to maintain something there. 2 months ago I started a survey and asked who uses platforms supported via hosts/. Both questions did not turn up any users. (Windows is supported via Cygwin, which does not need anything from hosts/).
Additionally, the code in hosts/ was not maintained for a long time. Probably some parts don't even compile on current releases of the target platform or have runtime issues (see also 0000624). Anyway, we developers don't have any of the platforms available for developing.
I therefore suggest to remove the complete directory and all references to it.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001083)
zesstra   
2009-05-06 16:24   
Patches for removal were applied as r2565.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
617 [LDMud 3.3] Compilation, Installation feature N/A 2009-03-31 05:53 2009-05-05 15:50
Reporter: _xtian_ Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: relax syntax and warn about obvious coding errors?
Description: Since most of the MUD coders are not necessary experienced programmers, why not modify the compiler to catch some obvious mistakes. These could be issued as warnings or even compile-errors.

I just stumbled over:

  if (...);

There is no useful case for this statement, even if it is syntactically correct.
There surely are a lot of other items like this one.

What is the general opinion here? Should we adhere to syntactic rules or enhance useability?
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0001009)
Gnomi   
2009-03-31 06:01   
Just a few hours ago I stumbled upon the same.

But in a if-elseif-else chain it's only useless if it is the last statement that is empty. Also a foreach loop with an empty statement is useless.
(0001012)
zesstra   
2009-04-08 04:36   
Mhmm, isn't that actually making the syntax stricter? Ok, maybe not the syntax itself but I mean, we would make syntactically correct code to raise errors/warning upon compilation. That is not necessarily a bad thing, I appreciate if errors can be caught at compile-time, but I think the title of this issue is confusing in this context.
(0001041)
_xtian_   
2009-04-15 22:51   
Yes, the title is weird. I was thinking around the lines of "relaxing the necessity to adhere to syntactic correcteness" ... well, anyhow ...

Having given it some thought I would suggest to issue warnings for these cases and if #pragma pedantic is set - errors.
Also pragmas #warn/no_warn_common_mistakes to switch them on/off.

If the user can switch them off/on on a per-file basis, we can also think about issueing warnings for common mistake cases that could even have real uses, like:
probably: for(...;...;...);
and *maybe* while(...);
(0001043)
fufu   
2009-04-16 11:39   
Hmm, I'd be more likely to have an empty body in a for loop than in a while loop.

Anyway, as long as these warnings can be switched off, I'm happy.

We can also think about adding a keyword or pseudo efun for intentionally empty statements. I.e. for(;;) ; would give a warning while for(;;) nop; (or whatever) would not.
(0001044)
Gnomi   
2009-04-16 12:00   
There is a difference between statements that are guaranteed to be useless ('if(expr);' is always the same as 'expr;' as long as no 'else' is following) and statements that might be a mistake. I wouldn't lump them together.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
367 [LDMud 3.3] Efuns tweak always 2005-02-20 12:51 2009-05-05 15:50
Reporter: bubbs Platform:  
Assigned To: fufu OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: map(mixed *array, mapping mapp, int index)
Description: Currently, map(array, mapp) works nicely.

A logical extension is map(array, mapp, index), which would translate to a specified mapping value.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000980)
zesstra   
2009-03-04 17:55   
Maybe it is too late right now, but I think, I don't understand this right. If you want to deal with only one entry, why using map() at all? Could you give an example?
(0000982)
Gnomi   
2009-03-04 18:01   
The index is for mappings with a width > 1. Currently the value of the first column is used, with that parameter the values of column <index> will be taken.
(0000983)
bubbs   
2009-03-04 18:19   
(Last edited: 2009-03-04 18:24)
Yes, that's exactly it, Gnomi.

Example;
  mapping names =
    ([
      0: "zero"; "null",
      1: "one"; "eins",
      2: "two"; "zwei",
      3: "three"; "drei",
    ]);

  string *en_names = map(({ 2, 3, }), names, 0); // ({ "two", "three", })
  string *de_names = map(({ 2, 3, }), names, 1); // ({ "zwei", "drei", })

(0000992)
fufu   
2009-03-13 14:36   
This makes sense to me. I'll implement this if there are no objections.
(0000993)
zesstra   
2009-03-13 15:18   
No objection from me, would have taken it as soon I got rid of my other stuff. ;-)
(0001001)
fufu   
2009-03-15 09:11   
Done in svn rev. 2532

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
628 [LDMud 3.3] Portability major N/A 2009-04-19 15:34 2009-05-05 15:27
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: high OS Version: 10.5.x  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Inconsistent data for F_NUMBER is generated on LP64 systems
Description: F_NUMBER in interpret.c expects the number to be in the host format. It reads sizeof(p_int) chars following the F_NUMBER instruction into svp[1]->u.number.

Unfortunately, the compiler does generate two different F_NUMBER:
- L_NUMBER writes sizeof(p_int) chars into the bytecode after F_NUMBER.
- ins_number() writes a int32 into the bytecode after F_NUMBER.

I don't know why nobody noticed this problem, it is quite weird. ins_number() seems to be rarely used.
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files: 0001-Fix-F_NUMBER-generation.patch (4,152 bytes) 2009-04-19 16:17
http://ldmud.eu/file_download.php?file_id=224&type=bug
0002-Fixes-insert_pop_value.patch (5,334 bytes) 2009-05-05 14:46
http://ldmud.eu/file_download.php?file_id=230&type=bug
Notes
(0001059)
zesstra   
2009-04-19 16:18   
The patch adds ins_p_int(), upd_p_int() and read_p_int().
ins_number() now calls ins_p_int() upon generating the F_NUMBER instruction.
Additionally upon storing a number (L_NUMBER) and in the unary '-'
upd_p_int() is called instead of a direct memcpy(). (memcpy() is faster,
but I think it is much more risky to forget a place to change...)
(0001079)
zesstra   
2009-05-05 14:50   
Gnomi noticed, that insert_pop_value() is not working properly, because it did not take into account, that the operations have different payloads of data following. I attached a patch which should rectify this. Could someone have a short look? BTW: insert_pop_value() would now always set last_expression to -1, this may have side effects, I didn't notice. If this is the case, it has to be changed.
(0001080)
zesstra   
2009-05-05 15:27   
Ok, great. This issue should then be fixed by r2562 and r2563.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
601 [LDMud 3.3] Efuns feature N/A 2009-01-17 13:06 2009-05-04 13:49
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Add possibility to change limits for memory allocation (MAX_MALLOCED, SOFT_MALLOC_LIMIT) at runtime
Description: I am in the process of introducing a soft memory allocation limit (0000081). If exceeded the driver will call low_memory() in the mudlib master which can decide if there a need/possibilty to do something (e.g. perform garabge_collection() at a suitable time during the night).

The mudlib should be able to set the soft limit at runtime. And if it can set the soft limit, it should also be able to set the hard limit I believe.
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files: 0001-Added-new-efun-configure_driver.patch (6,847 bytes) 2009-04-19 18:11
http://ldmud.eu/file_download.php?file_id=225&type=bug
Notes
(0000919)
zesstra   
2009-01-17 13:06   
The question is, if we should directly go for a configure_driver() (originally planned for 3.5.x, see 0000596) or create a set_malloc_limits() in the meantime. Querying the limits can be easily done in debug_info() now, but for setting them we need to create the general configure efun first.
(0000920)
Gnomi   
2009-01-17 13:13   
I don't want to implement a function that will be deprecated soon. That's why I will implement a preliminary configure_interactive() in 3.3 for 0000297. (But we have to decide whether it should already handle all options or just the new one.)
(0000921)
zesstra   
2009-01-17 13:20   
I agree.
Then I suggest to create a preliminary configure_driver() as well, which will handle only new settings in 3.3 like these two limits. This seems to reasonable, because otherwise we would deprecate the existing functions already in 3.3 which I don't like.
(0001060)
zesstra   
2009-04-19 18:14   
The attached patch adds a basic configure_driver() efun which can configure the soft and hard memory limits.
The draft does not allow to set the limits separately, but expects them as array argument: ({soft limit, hard limit}). If that disturbs anyone, please say so. ;-)
(0001075)
zesstra   
2009-05-04 13:49   
Applied with minor codestyle changes as r2556.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
633 [LDMud 3.3] LPC Compiler/Preprocessor crash sometimes 2009-05-04 05:46 2009-05-04 07:23
Reporter: invisible Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version:  
Summary: Access of undefined/undeclared variable crashes 3.3.718 on amd64
Description: A call to a function, using an undeclared variable as argument *sometimes* (don't ask me why) crashes ldmud-3.3.718 compiled on amd64.

foo() - works (produces an "Undefined function 'foo' near ';'.", execution continues)

foo(bar) - crash after message "Variable bar not declared ! before ';'."

The segfault happens at line 10865 in prolang.y:
$$.type = V_VARIABLE(i)->type;

It seems, that V_VARIABLE(i) is NULL or another improper value when the variable is undefined. Strange thing: I'd expect this to crash *always* not only occasionally and not only on amd64.


The really annoing things about this bug are:

a) it happens only occasionally (some calls to "foo(bar)" just produce the error message compaining about the undefined variable 'bar' but the driver continues to work - as expected) - I really can't imagine why

b) it does *not* happen on our 'production'-server, running the very same version just compiled for i386 - again: shouldn't this always crash? Is there another path in the driver where V_VARIABLE(i) gets checked more thoroughly?

c) it is so simple to crash the driver; undeclared variables appear all the time while programming...
Tags:
Steps To Reproduce:
Additional Information: gdb output:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7f377f65a6e0 (LWP 5864)]
0x000000000048de3c in yyparse () at prolang.y:10865
10865 $$.type = V_VARIABLE(i)->type;
(gdb) bt
#0 0x000000000048de3c in yyparse () at prolang.y:10865
0000001 0x00000000004965fa in compile_file (fd=11,
    fname=0x7f377ce87767 "home/invisible/ccall.c",
    isMasterObj=<value optimized out>) at prolang.y:16823
0000002 0x00000000004a7c99 in load_object (lname=<value optimized out>,
    create_super=false, depth=0, isMasterObj=false, chain=0x0)
    at simulate.c:1981
0000003 0x00000000004a8494 in lookfor_object (str=<value optimized out>,
    bLoad=true) at simulate.c:2426
0000004 0x0000000000454229 in eval_instruction (
    first_instruction=<value optimized out>, initial_sp=<value optimized
out>)
    at interpret.c:16276
0000005 0x00000000004ab532 in catch_instruction (flags=0,
    offset=<value optimized out>, i_sp=0x7ad048,
    i_pc=0x7f377cfe2a2f "a\036\003\n »b´b{\004(j\v\n\212\036\004*Â¥\t",
    i_fp=<value optimized out>, reserve_cost=10000, i_context=0x0)
    at simulate.c:449
0000006 0x000000000044c52c in eval_instruction (
    first_instruction=<value optimized out>, initial_sp=<value optimized
out>)
    at interpret.c:9506
0000007 0x000000000045a113 in int_call_lambda (lsvp=<value optimized out>,
    num_arg=1, allowRefs=false) at interpret.c:17913
0000008 0x000000000045a7fe in v_funcall (sp=0x736370, num_arg=2)
    at interpret.c:20451
0000009 0x00000000004507aa in eval_instruction (
    first_instruction=<value optimized out>, initial_sp=<value optimized
out>)
    at interpret.c:8297
0000010 0x0000000000459418 in apply_low (fun=<value optimized out>,
    ob=0x7f377ce2b0e8, num_arg=1, b_ign_prot=false, allowRefs=false)
    at interpret.c:16836
0000011 0x000000000044a58d in int_apply (fun=0x34, ob=0x7fff87675cce,
    num_arg=2094053465, b_ign_prot=<value optimized out>,
b_use_default=true)
    at interpret.c:17027
0000012 0x000000000044b195 in sapply_int (fun=0x7f377d102ef0, ob=0x7f377ce2b0e8,
    num_arg=1, b_find_static=122, b_use_default=true) at interpret.c:17188
0000013 0x0000000000405dcd in parse_command (
    buff=0x7fff87679020 "xcall #foo(barbaz)", from_efun=false)
    at actions.c:1102
#14 0x000000000040773a in execute_command (
    str=0x7fff87679020 "xcall #foo(barbaz)", ob=0x7f377ce2b0e8)
#15 0x000000000040e96d in backend () at backend.c:673
#16 0x000000000046849d in main (argc=<value optimized out>,
    argv=<value optimized out>) at main.c:625
(gdb)


You can download the coredump at
http://xover.mud.at/~invisible/temp/ldmud-3.3.718-core (25MB) (program
compiled via 'sh settings/beutelland', original from 3.3.718 +
"enable_use_mccp=yes", plus "-ggdb3" added to $DEBUG in the Makefile)
Attached Files: r2499.diff (4,944 bytes) 2009-05-04 06:10
http://ldmud.eu/file_download.php?file_id=228&type=bug
Notes
(0001070)
zesstra   
2009-05-04 05:58   
Could you make the exact binary which wrote the core also available for download? (Otherwise the core dump is not very useful.)
(0001071)
Gnomi   
2009-05-04 06:12   
I believe this bug is already fixed in r2499. I attached the patch, could you give it a try.
(0001073)
invisible   
2009-05-04 06:20   
Binary can be found at http://xover.mud.at/~invisible/temp/ldmud-3.3.718-debug.

But I'll try the patch this week someday.
(0001074)
invisible   
2009-05-04 06:30   
Ok, found time right away... this patch does indeed fix the issue. Thanks a lot!

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
602 [LDMud 3.3] Efuns major always 2009-01-17 18:13 2009-04-14 14:11
Reporter: wedsall Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.718  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: db_conv_string bugging over 27 characters
Description: Hello list,
 I'm about to log this into mantis but wanted to post also.

In 3.3.717 I started using the mysql features of ldmud. They've been working well until I upgraded to 3.3.718.

This reboot (using 3.3.718 now) I'm getting bugs with db_conv_string returning strange ascii characters.

Example: db_conv_string("domains/areas/apollo/floor1/entr_castle")
LPC result: " "D
Ô Ô

I will also attach a screenshot.


This seems to happen on any string I use over 27 characters!

lpc db_conv_string("testtesttesttesttesttesttesttesttesttest")
LPC result: ""DP 㵥
testtesttesttesttesttesttesttest"


uuga @ dragonfire
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: example_uugabug.png (12,623 bytes) 2009-01-17 18:13
http://ldmud.eu/file_download.php?file_id=191&type=bug
png

pkg-mysql.diff (781 bytes) 2009-01-18 07:49
http://ldmud.eu/file_download.php?file_id=194&type=bug
Notes
(0000923)
zesstra   
2009-01-17 18:24   
Thanks for your report. Gna. I guess, I found the problem. Could you please try the attached patch and confirm if it works?
(0000925)
wedsall   
2009-01-17 19:43   
Trying this on my dev side.


Before patch:
lpc db_conv_string("testytestytestytestytestytestytestytesty")
LPC result: "¼¢ø>


After patch:> lpc db_conv_string("testytestytestytestytestytestytestytesty")
LPC result: "testytestytestytestytestytestytestytesty"


Looks good!
(0000926)
peng   
2009-01-17 19:46   
can confirm bug and solution. fast work, zeestra.
(0000927)
zesstra   
2009-01-18 07:59   
BTW: the patch from last night was only the quick (and dirty) solution. In rare circumstances it can result in memory leaks. I updated it to use an error handler.
Fixed in r2506.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
611 [LDMud 3.3] Runtime crash always 2009-03-10 16:03 2009-03-12 18:08
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version: 3.3.718  
Product Build: r2524 Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Crash in remove_from_free_list() during restore_object()
Description: When compiled for x86_64 (-m64 -mtune=core2), the driver crashes upon loading a specific savefile on my system. On a i386 platform or with a different savefile there is no problem.
It seems to be some kind of memory problem/corruption.

2009.03.10 20:44:37 Seeding PRNG from /dev/urandom.
2009.03.10 20:44:37 LDMud 3.3.718 (Build $Revision$) (stable)
2009.03.10 20:44:37 Hostname 'phoenix' address '192.168.178.28'
2009.03.10 20:44:37 UDP port 4246 already bound!
2009.03.10 20:44:37 No simul_efun
2009.03.10 20:45:00 remove_from_free_list: block 0x101be2100, magic match failed: expected 3752850158, found 0
2009.03.10 20:45:00 Current object was secure/errord
2009.03.10 20:46:51 LDMud aborting on fatal error.

I have prepared a stripped mudlib and the savefile as test case, but I would not like to publish the savefile at this point as there may be some private data in it.
The problem occurs also in older versions (tested 100 revisions back) of the driver but not with standard configure settings, therefore I will attach my machine.h and config.h as well for the record.
Tags:
Steps To Reproduce: export CFLAGS="-m64 -mtune=core2 -ggdb3 -O0"
export LDFLAGS="-m64 -mtune=core2 -ggdb3 -O0"
export EXTRA_CFLAGS=$CFLAGS

(use attached machine.h and config.h)
make
./ldmud -m /path/to/test/case 4713
Additional Information: (gdb) bt full
#0 fatal (fmt=0x10011a950 "remove_from_free_list: block %p, magic match failed: expected %lu, found %lu\n") at simulate.c:651
    va = {{
    gp_offset = 48,
    fp_offset = 48,
    overflow_arg_area = 0x7fff5fbfb4a8,
    reg_save_area = 0x7fff5fbfb3d0
  }}
    ts = 0x1001406a0 "2009.03.10 20:46:51"
0000001 0x00000001000f9770 in remove_from_free_list (ptr=0x101be2100) at slaballoc.c:2309
    p = (struct free_block *) 0x101ba2000
    q = (struct free_block *) 0x7fff5fbfb560
    r = (struct free_block *) 0x40100
    s = (struct free_block *) 0x101ba1ff8
    t = (struct free_block *) 0x101be20c8
0000002 0x00000001000faa39 in add_large_free (ptr=0x101ba2000, block_size=32800) at slaballoc.c:3037
No locals.
0000003 0x00000001000fae4a in large_malloc (size=1749, force_more=false) at slaballoc.c:3293
    chunk_size = 262400
    block_size = 32800
    extra = 64
    real_size = 4323311736
    ptr = (word_t *) 0x101ba2000
    orig_size = 13968
    mess = "HARD_MALLOC_LIMIT reached.\n"
0000004 0x00000001000f89b2 in mem_alloc (size=96) at slaballoc.c:1719
    numObjects = 145
    slabSize = 13968
    slab = (mslab_t *) 0x7fff5fbfb7a0
    block = (word_t *) 0x0
    ix = 3
0000005 0x00000001000fc795 in xalloc_traced (size=80, malloc_trace_file=0x100111b30 "mapping.c", malloc_trace_line=335) at xalloc.c:565
    p = (word_t *) 0x101b5d8a0
0000006 0x0000000100086d09 in new_map_chain (m=0x101b48f60) at mapping.c:335
    rc = (map_chain_t *) 0xb
0000007 0x00000001000868c1 in _get_map_lvalue (m=0x101b48f60, map_index=0x7fff5fbfb7a0, need_lvalue=true, check_size=false) at mapping.c:1007
    mc = (map_chain_t *) 0x0
    hm = (mapping_hash_t *) 0x101b0dbb8
    entry = (svalue_t *) 0x0
    idx = -1
    local_const0 = {
  type = 0,
  x = {
    exponent = 0,
    closure_type = 0,
    quotes = 0,
    num_arg = 0,
    extern_args = 0,
    generic = 0
  },
  u = {
    str = 0x0,
    charp = 0x0,
    number = 0,
    ob = 0x0,
    vec = 0x0,
    strct = 0x0,
    map = 0x0,
    lambda = 0x0,
    mantissa = 0,
    cb = 0x0,
    generic = 0x0,
    lvalue = 0x0,
    protected_lvalue = 0x0,
    protected_char_lvalue = 0x0,
    protected_range_lvalue = 0x0,
    error_handler = 0
  }
}
0000008 0x00000001000a27e5 in restore_mapping (svp=0x101b41e40, str=0x7fff5fbfbc68) at object.c:7416
    z = (mapping_t *) 0x101b48f60
    key = {
  type = 3,
  x = {
    exponent = 32352,
    closure_type = 32352,
    quotes = 32352,
    num_arg = 32352,
    extern_args = 32352,
    generic = 32352
  },
  u = {
    str = 0x101023f30,
    charp = 0x101023f30 "?",
    number = 4311891760,
    ob = 0x101023f30,
    vec = 0x101023f30,
    strct = 0x101023f30,
    map = 0x101023f30,
    lambda = 0x101023f30,
    mantissa = 4311891760,
    cb = 0x101023f30,
    generic = 0x101023f30,
    lvalue = 0x101023f30,
    protected_lvalue = 0x101023f30,
    protected_char_lvalue = 0x101023f30,
    protected_range_lvalue = 0x101023f30,
    error_handler = 0x101023f30
  }
}
    data = (svalue_t *) 0x101b41970
    i = 1
    tmp_par = {
  str = 0x101b5d957 ",]),\"GUILD.magie_sp\":([\"2ab8fcc56cf505567837f5a565c51760\":([\"F_UID\":\"GUILD.magie_sp\",\"F_CLI\":\"konzentriere\",\"F_MSG\":\"Numeric overflow: 1235742139 + 1235742515\\n\",\"F_OBJ\":\"spellbooks/magie_sp\",\"F_TYPE\""...,
  num_values = 1
}
    siz = 4
0000009 0x00000001000a15b4 in restore_svalue (svp=0x101b41e40, pt=0x7fff5fbfbc68, delimiter=44 ',') at object.c:8330
    cp = 0x101b5d507 "([F_UID"
0000010 0x00000001000a2868 in restore_mapping (svp=0x101b41ea0, str=0x7fff5fbfbc68) at object.c:7430
    z = (mapping_t *) 0x101b49040
    key = {
  type = 0,
  x = {
    exponent = -26192,
    closure_type = -26192,
    quotes = -26192,
    num_arg = -26192,
    extern_args = -26192,
    generic = -26192
  },
  u = {
    str = 0x10101ccd8,
    charp = 0x10101ccd8 "\003",
    number = 4311862488,
    ob = 0x10101ccd8,
    vec = 0x10101ccd8,
    strct = 0x10101ccd8,
    map = 0x10101ccd8,
    lambda = 0x10101ccd8,
    mantissa = 4311862488,
    cb = 0x10101ccd8,
    generic = 0x10101ccd8,
    lvalue = 0x10101ccd8,
    protected_lvalue = 0x10101ccd8,
    protected_char_lvalue = 0x10101ccd8,
    protected_range_lvalue = 0x10101ccd8,
    error_handler = 0x10101ccd8
  }
}
    data = (svalue_t *) 0x101b41e50
    i = 0
    tmp_par = {
  str = 0x101b5d95a ",\"GUILD.magie_sp\":([\"2ab8fcc56cf505567837f5a565c51760\":([\"F_UID\":\"GUILD.magie_sp\",\"F_CLI\":\"konzentriere\",\"F_MSG\":\"Numeric overflow: 1235742139 + 1235742515\\n\",\"F_OBJ\":\"spellbooks/magie_sp\",\"F_TYPE\":1,"...,
  num_values = 1
}
    siz = 0
0000011 0x00000001000a15b4 in restore_svalue (svp=0x101b41ea0, pt=0x7fff5fbfbc68, delimiter=44 ',') at object.c:8330
    cp = 0x101b5d4e2 "([8d0dafe4d88b33055fe33bf6444d2cb5"
0000012 0x00000001000a2868 in restore_mapping (svp=0x101028000, str=0x7fff5fbfbc68) at object.c:7430
    z = (mapping_t *) 0x101018aa0
    key = {
  type = 0,
  x = {
    exponent = 21232,
    closure_type = 21232,
    quotes = 21232,
    num_arg = 21232,
    extern_args = 21232,
    generic = 21232
  },
  u = {
    str = 0x101ae2978,
    charp = 0x101ae2978 "\005",
    number = 4323158392,
    ob = 0x101ae2978,
    vec = 0x101ae2978,
    strct = 0x101ae2978,
    map = 0x101ae2978,
    lambda = 0x101ae2978,
    mantissa = 4323158392,
    cb = 0x101ae2978,
    generic = 0x101ae2978,
    lvalue = 0x101ae2978,
    protected_lvalue = 0x101ae2978,
    protected_char_lvalue = 0x101ae2978,
    protected_range_lvalue = 0x101ae2978,
    error_handler = 0x101ae2978
  }
}
    data = (svalue_t *) 0x101b41eb0
    i = 0
    tmp_par = {
  str = 0x101b6064a ",2:([\"wurzel\":([\"c0241c77a1f505027d6d323292ad0e4f\":([\"F_UID\":\"wurzel\",\"F_MSG\":\"Call from destructed object 'players/wurzel/obj/aids#4828017' ignored.\\n\",\"F_OBJ\":\"/players/wurzel/obj/aids#4828017\",\"F_T"...,
  num_values = 1
}
    siz = 6
0000013 0x00000001000a15b4 in restore_svalue (svp=0x101028000, pt=0x7fff5fbfbc68, delimiter=44 ',') at object.c:8330
    cp = 0x101b5104b "([rimus"
#14 0x00000001000a2868 in restore_mapping (svp=0x1010240d0, str=0x7fff5fbfbc68) at object.c:7430
    z = (mapping_t *) 0x101018b10
    key = {
  type = 0,
  x = {
    exponent = 2,
    closure_type = 2,
    quotes = 2,
    num_arg = 2,
    extern_args = 2,
    generic = 2
  },
  u = {
    str = 0x1,
    charp = 0x1 <Address 0x1 out of bounds>,
    number = 1,
    ob = 0x1,
    vec = 0x1,
    strct = 0x1,
    map = 0x1,
    lambda = 0x1,
    mantissa = 1,
    cb = 0x1,
    generic = 0x1,
    lvalue = 0x1,
    protected_lvalue = 0x1,
    protected_char_lvalue = 0x1,
    protected_range_lvalue = 0x1,
    error_handler = 0x1
  }
}
    data = (svalue_t *) 0x101028010
    i = 0
    tmp_par = {
  str = 0x101ba1eb3 "\n",
  num_values = 1
}
    siz = 3
#15 0x00000001000a15b4 in restore_svalue (svp=0x1010240d0, pt=0x7fff5fbfbc68, delimiter=10 '\n') at object.c:8330
    cp = 0x101b51047 "([1:([rimus"
#16 0x00000001000a3b38 in f_restore_object (sp=0x100171000) at object.c:9004
    v = (svalue_t *) 0x1010240d0
    pt = 0x101b5d8ac "\"8d0dafe4d88b33055fe33bf6444d2cb5\",\"F_MODSTAMP\":1234487099,\"F_LOADNAME\":\"/d/wald/seleven/nelfen/npc/bewohner/fuerst\",\"F_READSTAMP\":1236199850,\"F_CREATESTAMP\":1234487099,]),]),\"GUILD.magie_sp\":([\"2ab8f"...
    restored_version = 1
    name = 0x101031ad8 "secure/ARCH/errord.o"
    file = 0x101018c7a "/secure/ARCH/errord"
    lineno = 2
    var = (string_t *) 0x101028108
    buff = 0x101b51040 "errors"
    cur = 0x101b51040 "errors"
    space = 0x101b51046 ""
    ob = (object_t *) 0x101b0ee88
    len = 18
    f = (FILE *) 0x7fff700754d8
    st = {
  st_dev = 234881029,
  st_ino = 13515213,
  st_mode = 33184,
  st_nlink = 1,
  st_uid = 1000,
  st_gid = 1000,
  st_rdev = 0,
  st_atimespec = {
    tv_sec = 1236713868,
    tv_nsec = 0
  },
  st_mtimespec = {
    tv_sec = 1236681948,
    tv_nsec = 0
  },
  st_ctimespec = {
    tv_sec = 1236708856,
    tv_nsec = 0
  },
  st_size = 331399,
  st_blocks = 648,
  st_blksize = 4096,
  st_flags = 0,
  st_gen = 0,
  st_lspare = 0,
  st_qspare = {0, 0}
}
    arg = (svalue_t *) 0x100170ff0
    var_rest = 3
    num_var = 3
    rover = (variable_t *) 0x101b0eda0
    rcp = (restore_cleanup_t *) 0x101018bf0
    ctx = (struct restore_context_s *) 0x101027f88
    nesting = 1
#17 0x0000000100055d9d in eval_instruction (first_instruction=0x101b0ed2a "?\003\034\003Q\\\n", initial_sp=0x100170fe0) at interpret.c:8103
    code = 68
    pc = (bytecode_p) 0x101b0ed34 "k\037\020?"
    fp = (svalue_t *) 0x100170ff0
    sp = (svalue_t *) 0x100170ff0
    num_arg = -1
    instruction = 296
    full_instr = 296
    expected_stack = (svalue_t *) 0x0
    ap = (svalue_t *) 0x100170ff0
    use_ap = false
    off_tab = {0, 8, 24, 56, 120, 248, 504, 1016, 2040, 4088, 8184, 16376, 32760, 65528, 131064, 262136, 524280, 1048568, 2097144, 4194296}
#18 0x000000010006e28f in apply_low (fun=0x101027088, ob=0x101b0ee88, num_arg=1, b_ign_prot=true, allowRefs=false) at interpret.c:16954
    flags = 24
    funstart = (fun_hdr_p) 0x101b0ed28 ""
    fx = 0
    progp = (program_t *) 0x101b0ec60
    save_csp = (struct control_stack *) 0x1001905c0
    ix = 29065
#19 0x000000010006e449 in int_apply (fun=0x101027088, ob=0x101b0ee88, num_arg=1, b_ign_prot=true, b_use_default=true) at interpret.c:17032
No locals.
#20 0x000000010006e901 in sapply_int (fun=0x101027088, ob=0x101b0ee88, num_arg=1, b_find_static=true, b_use_default=true) at interpret.c:17193
    expected_sp = (svalue_t *) 0x100170fe0
#21 0x000000010009606a in reset_object (ob=0x101b0ee88, arg=5) at object.c:899
No locals.
#22 0x00000001000dcef9 in load_object (lname=0x10042a980 "secure/errord", create_super=false, depth=0, isMasterObj=false, chain=0x0) at simulate.c:2152
    svp = (svalue_t *) 0x101024100
    j = -1
    save_current = (object_t *) 0x101ae4878
    fd = 5
    ob = (object_t *) 0x101b0ee88
    save_command_giver = (object_t *) 0x0
    i = 12
    c_st = {
  st_dev = 234881029,
  st_ino = 13515208,
  st_mode = 33188,
  st_nlink = 1,
  st_uid = 1000,
  st_gid = 1000,
  st_rdev = 0,
  st_atimespec = {
    tv_sec = 1236713853,
    tv_nsec = 0
  },
  st_mtimespec = {
    tv_sec = 1236710176,
    tv_nsec = 0
  },
  st_ctimespec = {
    tv_sec = 1236710176,
    tv_nsec = 0
  },
  st_size = 831,
  st_blocks = 8,
  st_blksize = 4096,
  st_flags = 0,
  st_gen = 0,
  st_lspare = 0,
  st_qspare = {0, 0}
}
    name_length = 13
    name = 0x10100dee8 "/secure/errord"
    fname = 0x10100def8 "secure/errord.c"
    prog = (program_t *) 0x101b0ec60
    nlink = {
  prev = 0x0,
  name = 0x10100dee9 "secure/errord"
}
#23 0x00000001000dd7fc in lookfor_object (str=0x101ae0c38, bLoad=true) at simulate.c:2420
    ob = (object_t *) 0x0
    pName = 0x10042a980 "secure/errord"
    isMasterObj = false
#24 0x00000001000e1a0e in f_load_object (sp=0x100170fd0) at simulate.c:4493
    ob = (object_t *) 0x200000000
#25 0x0000000100055d9d in eval_instruction (first_instruction=0x101b0c5c6 "\036", initial_sp=0x100170fc0) at interpret.c:8103
    code = 36
    pc = (bytecode_p) 0x101b0c5ca "?b\\\031"
    fp = (svalue_t *) 0x100170fb0
    sp = (svalue_t *) 0x100170fd0
    num_arg = -1
    instruction = 264
    full_instr = 264
    expected_stack = (svalue_t *) 0x0
    ap = (svalue_t *) 0x100170fb0
    use_ap = false
    off_tab = {0, 8, 24, 56, 120, 248, 504, 1016, 2040, 4088, 8184, 16376, 32760, 65528, 131064, 262136, 524280, 1048568, 2097144, 4194296}
#26 0x00000001000d9484 in catch_instruction (flags=0, offset=5, i_sp=0x10046f350, i_pc=0x101b0c5c6 "\036", i_fp=0x100170fb0, reserve_cost=4000, i_context=0x0) at simulate.c:449
    rc = false
    old_out_of_memory = false
    new_pc = (bytecode_p) 0x101b0c5cb "b\\\031"
#27 0x00000001000582f1 in eval_instruction (first_instruction=0x101b0c5c2 "a\037", initial_sp=0x100170fb0) at interpret.c:9511
    offset = 5
    flags = 0
    reserve_cost = 4000
    pc = (bytecode_p) 0x101b0c5c6 "\036"
    fp = (svalue_t *) 0x100170fb0
    sp = (svalue_t *) 0x100170fc0
    num_arg = -1
    instruction = 31
    full_instr = 31
    expected_stack = (svalue_t *) 0x0
    ap = (svalue_t *) 0x100170fd0
    use_ap = false
    off_tab = {0, 8, 24, 56, 120, 248, 504, 1016, 2040, 4088, 8184, 16376, 32760, 65528, 131064, 262136, 524280, 1048568, 2097144, 4194296}
#28 0x000000010006e28f in apply_low (fun=0x101004898, ob=0x101ae4878, num_arg=1, b_ign_prot=true, allowRefs=false) at interpret.c:16954
    flags = 16777392
    funstart = (fun_hdr_p) 0x101b0c5c0 "\001"
    fx = 8
    progp = (program_t *) 0x101b0c460
    save_csp = (struct control_stack *) 0x1001904c0
    ix = 18842
#29 0x000000010006e449 in int_apply (fun=0x101004898, ob=0x101ae4878, num_arg=1, b_ign_prot=true, b_use_default=false) at interpret.c:17032
No locals.
#30 0x000000010006e901 in sapply_int (fun=0x101004898, ob=0x101ae4878, num_arg=1, b_find_static=true, b_use_default=false) at interpret.c:17193
    expected_sp = (svalue_t *) 0x100170fa0
#31 0x000000010006f326 in apply_master_ob (fun=0x101004898, num_arg=1, external=false) at interpret.c:17503
    reserve_used = false
    error_recovery_info = {
  rt = {
    last = 0x100140700,
    type = 2
  },
  flags = 1606413488,
  con = {
    text = {1511344, 1, 1606413664, 32767, 1606413424, 32767, 0, 0, 0, 0, 0, 0, 0, 0, 455262, 1, 530, 0, 8112, 1606353791, 0, 32767, 1, 1572864, 1, 0, 0, 28199032, 1, 1606413712, 32767, 28199032, 1, 16904192, 1, 1606413632, 32767}
  }
}
    save_sp = (svalue_t *) 0x100170fb0
    save_csp = (struct control_stack *) 0x100190440
    result = (svalue_t *) 0x10000e6fb
    eval_cost_reserve = 1024
#32 0x000000010000e65e in preload_objects (eflag=0) at backend.c:1293
    prefiles = (vector_t *) 0x1010249c0
    ret = (svalue_t *) 0x100136e00
    ix = 0
    ix0 = 0
    num_prefiles = 1
#33 0x0000000100082333 in main (argc=4, argv=0x7fff5fbff250) at main.c:630
    i = 5
    p = 0x7fff5fbff1f4 "\005"
    set = 8192
    rc = 0


Trace dump:
secure/master secure/master.c line 144
0x101b0c87a: 10 0 cstring0 (0: -1) line 144
0x101b0c87c: 24 return (1: 0)
0x101b0c52a: 10 0 cstring0 (0: 0) line 8
0x101b0c52c: 309 81 seteuid (1: 1)
0x101b0c52e: 92 pop_value (1: 1)
0x101b0c52f: 18 19 clit (0: 0) line 9
0x101b0c531: 10 1 cstring0 (1: 1)
0x101b0c533: 366 36 set_driver_hook (2: 2) line 16
0x101b0c535: 18 12 clit (0: 0) line 17
0x101b0c537: 10 2 cstring0 (1: 1)
0x101b0c539: 10 3 cstring0 (2: 2)
0x101b0c53b: 10 4 cstring0 (3: 3)
0x101b0c53d: 166 3 aggregate (4: 4)
0x101b0c540: 366 36 set_driver_hook (2: 2)
0x101b0c542: 18 6 clit (0: 0) line 18
0x101b0c544: 10 5 cstring0 (1: 1)
0x101b0c546: 366 36 set_driver_hook (2: 2)
0x101b0c548: 18 5 clit (0: 0) line 19
0x101b0c54a: 10 5 cstring0 (1: 1)
0x101b0c54c: 366 36 set_driver_hook (2: 2)
0x101b0c54e: 18 4 clit (0: 0) line 20
0x101b0c550: 10 6 cstring0 (1: 1)
0x101b0c552: 366 36 set_driver_hook (2: 2)
0x101b0c554: 18 2 clit (0: 0) line 21
0x101b0c556: 184 no_warn_deprecated (1: 1)
0x101b0c557: 22 2 closure (1: 1)
0x101b0c55c: 366 36 set_driver_hook (2: 2)
0x101b0c55e: 97 save_arg_frame (0: 0) line 23
0x101b0c55f: 10 7 cstring0 (1: 1)
0x101b0c561: 292 64 quote (2: 2)
0x101b0c563: 15 const0 (2: 2)
0x101b0c564: 374 44 symbol_function (3: 3)
0x101b0c566: 10 8 cstring0 (2: 2)
0x101b0c568: 411 21 funcall (3: 3)
0x101b0c56a: 98 restore_arg_frame (2: 2)
0x101b0c56b: 106 branch_when_zero (1: 1)
0x101b0c57e: 25 return0 (0: 0) line 24
secure/master program deallocated line 0
0x7fff5fbfecf0: 392 0 allocate (1: 0) line 0
0x7fff5fbfecf2: 24 return (1: 0)
secure/master secure/master.c line 29
0x101b0c59a: 10 0 cstring0 (0: 0) line 29
0x101b0c59c: 309 81 seteuid (1: 1)
0x101b0c59e: 92 pop_value (1: 1)
0x101b0c59f: 10 10 cstring0 (0: 0) line 31
0x101b0c5a1: 166 1 aggregate (1: 1)
0x101b0c5a4: 24 return (1: 1)
0x101b0c5c2: 97 save_arg_frame (0: 0) line 35
0x101b0c5c3: 31 1280 catch (1: 1)
0x101b0c5c6: 30 0 local (1: 1)
0x101b0c5c8: 264 load_object (2: 2)
0x101b0c8e2: 97 save_arg_frame (0: 5) line 150
0x101b0c8e3: 30 0 local (1: 6)
0x101b0c8e5: 171 previous_object0 (2: 7)
0x101b0c8e6: 110 call_function (3: 8)
0x101b0c7e2: 96 514 clear_locals (0: 10) line 114
0x101b0c7e5: 30 0 local (0: 10) line 117
0x101b0c7e7: 201 stringp (1: 11)
0x101b0c7e8: 60 ! (1: 11)
0x101b0c7e9: 39 4 || (1: 11)
0x101b0c7eb: 30 1 local (0: 10)
0x101b0c7ed: 196 objectp (1: 11)
0x101b0c7ee: 60 ! (1: 11)
0x101b0c7ef: 106 branch_when_zero (1: 11)
0x101b0c7f3: 97 save_arg_frame (0: 10) line 120
0x101b0c7f4: 30 0 local (1: 11)
0x101b0c7f6: 110 call_function (2: 12)
0x101b0c5ea: 96 769 clear_locals (0: 16) line 39
0x101b0c5ed: 30 0 local (0: 16) line 42
0x101b0c5ef: 196 objectp (1: 17)
0x101b0c5f0: 106 branch_when_zero (1: 17)
0x101b0c601: 30 0 local (0: 16) line 44
0x101b0c603: 201 stringp (1: 17)
0x101b0c604: 106 13 branch_when_zero (1: 17)
0x101b0c606: 97 save_arg_frame (0: 16) line 45
0x101b0c607: 30 0 local (1: 17)
0x101b0c609: 15 const0 (2: 18)
0x101b0c60a: 110 call_function (3: 19)
secure/master secure/master/file_access.c line 6
0x10103f9f2: 96 514 clear_locals (0: 22) line 6
0x10103f9f5: 30 0 local (0: 22) line 9
0x10103f9f7: 107 branch_when_non_zero (1: 23)
0x10103f9fe: 30 0 local (0: 22) line 11
0x10103fa00: 15 const0 (1: 23)
0x10103fa01: 184 no_warn_deprecated (2: 24)
0x10103fa02: 61 index (2: 24)
0x10103fa03: 28 switch (1: 23)
0x10103faaa: 30 1 local (0: 22) line 29
0x10103faac: 38 -12543 && (1: 23)
0x10103faaf: 38 && (1: 23)
0x10103fab7: 38 && (1: 23)
0x10103fac1: 106 branch_when_zero (1: 23)
0x10103fae2: 30 0 local (0: 22) line 32
0x10103fae4: 10 0 cstring0 (1: 23)
0x10103fae6: 341 11 explode (2: 24)
0x10103fae8: 10 1 cstring0 (1: 23)
0x10103faea: 10 2 cstring0 (2: 24)
0x10103faec: 166 2 aggregate (3: 25)
0x10103faef: 43 - (2: 24)
0x10103faf0: 123 2 push_local_variable_lvalue (1: 23)
0x10103faf2: 41 (void)= (2: 24) line 33
0x10103faf3: 27 break (0: 22)
0x10103fb1a: 105 branch (0: 22) line 34
0x10103fb30: 97 save_arg_frame (0: 22)
0x10103fb31: 30 2 local (1: 23)
0x10103fb33: 10 7 cstring0 (2: 24)
0x10103fb35: 427 37 member (3: 25)
0x10103fb37: 98 restore_arg_frame (2: 24)
0x10103fb38: 123 3 push_local_variable_lvalue (1: 23)
0x10103fb3a: 40 = (2: 24)
0x10103fb3b: 17 nconst1 (1: 23)
0x10103fb3c: 52 != (2: 24)
0x10103fb3d: 109 34 bbranch_when_non_zero (1: 23)
0x10103fb3f: 30 2 local (0: 22) line 36
0x10103fb41: 24 return (1: 23)
secure/master secure/master.c line 45
0x101b0c60d: 98 restore_arg_frame (2: 18) line 45
0x101b0c60e: 123 1 push_local_variable_lvalue (1: 17)
0x101b0c610: 41 (void)= (2: 18)
0x101b0c611: 105 403376643 branch (0: 16) line 46
0x101b0c616: 30 1 local (0: 16) line 48
0x101b0c618: 200 sizeof (1: 17)
0x101b0c619: 123 3 push_local_variable_lvalue (1: 17)
0x101b0c61b: 41 (void)= (2: 18)
0x101b0c61c: 30 3 local (0: 16) line 49
0x101b0c61e: 18 2 clit (1: 17)
0x101b0c620: 49 < (2: 18)
0x101b0c621: 106 403376643 branch_when_zero (1: 17)
0x101b0c626: 30 1 local (0: 16) line 51
0x101b0c628: 15 const0 (1: 17)
0x101b0c629: 184 no_warn_deprecated (2: 18)
0x101b0c62a: 61 index (2: 18)
0x101b0c62b: 28 switch (1: 17)
0x101b0c6ed: 10 0 cstring0 (0: 16) line 78
0x101b0c6ef: 24 return (1: 17) line 82
0x101b0c7f9: 98 restore_arg_frame (2: 12) line 120
0x101b0c7fa: 123 2 push_local_variable_lvalue (1: 11)
0x101b0c7fc: 40 = (2: 12)
0x101b0c7fd: 107 branch_when_non_zero (1: 11)
0x101b0c801: 30 0 local (0: 10) line 123
0x101b0c803: 15 const0 (1: 11)
0x101b0c804: 18 2 clit (2: 12)
0x101b0c806: 66 .. (3: 13)
0x101b0c807: 10 39 cstring0 (1: 11)
0x101b0c809: 51 == (2: 12)
0x101b0c80a: 39 9 || (1: 11)
0x101b0c80c: 30 0 local (0: 10)
0x101b0c80e: 15 const0 (1: 11)
0x101b0c80f: 18 3 clit (2: 12)
0x101b0c811: 66 .. (3: 13)
0x101b0c812: 10 40 cstring0 (1: 11)
0x101b0c814: 51 == (2: 12)
0x101b0c815: 106 branch_when_zero (1: 11)
0x101b0c819: 30 2 local (0: 10) line 126
0x101b0c81b: 10 0 cstring0 (1: 11)
0x101b0c81d: 51 == (2: 12)
0x101b0c81e: 38 4 && (1: 11)
0x101b0c820: 30 1 local (0: 10)
0x101b0c822: 206 this_object (1: 11)
0x101b0c823: 51 == (2: 12)
0x101b0c824: 106 3 branch_when_zero (1: 11)
0x101b0c826: 10 0 cstring0 (0: 10)
0x101b0c828: 24 return (1: 11)
0x101b0c8e9: 98 restore_arg_frame (2: 7) line 150
0x101b0c8ea: 24 return (1: 6)
secure/errord secure/errord.c line 23
0x101b0ed2a: 206 this_object (0: 3) line 23
0x101b0ed2b: 256 28 getuid (1: 4)
0x101b0ed2d: 309 81 seteuid (1: 4)
0x101b0ed2f: 92 pop_value (1: 4)
0x101b0ed30: 10 0 cstring0 (0: 3) line 24
0x101b0ed32: 296 restore_object (1: 4)
secure/master secure/master/file_access.c line 41
0x10103fb62: 30 0 local (0: 9) line 41
0x10103fb64: 24 return (1: 10)
0x101b0ed34: 107 31 16 168 0 1 18 2
       3 ' preload' in ' secure/master.c' (' secure/master') line 35
    4120 ' CATCH' in (' secure/master')
    4129 ' create' in ' secure/errord.c' (' secure/errord') line 24
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files: config.h (20,629 bytes) 2009-03-10 16:05
http://ldmud.eu/file_download.php?file_id=199&type=bug
machine.h (13,611 bytes) 2009-03-10 16:06
http://ldmud.eu/file_download.php?file_id=200&type=bug
Notes
(0000990)
zesstra   
2009-03-12 04:56   
Gnomi and me traced this issue in some long debug session yesterday and found the bug. The size of word_t was not taken into account in several places in esbrk() in slaballoc.c and smalloc.c. ;-) I will provide a patch this evening.

Note: This is actually not a portability issue, it can happen on any platform where sizeof(word_t) == sizeof(void *) != 1.
(0000991)
zesstra   
2009-03-12 16:24   
Patches for slaballoc.c and smalloc.c containing the fixes for this bug are in r2528. Great to have at least one and possibly more memory related crashes less. :-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
498 [LDMud 3.3] Efuns minor always 2007-01-17 03:57 2009-03-10 16:25
Reporter: fippo Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.713  
Product Build: Resolution: fixed  
Projection: minor fix      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: idna_stringprep doesn't work
Description: Missing free_svalue...

I wonder why I did not notice that earlier...
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: pkg-idna.patch (480 bytes) 2007-01-17 03:57
http://ldmud.eu/file_download.php?file_id=95&type=bug
0001-Fixed-freeing-of-the-arguments-of-f_idna_stringprop.patch (1,539 bytes) 2009-03-09 15:00
http://ldmud.eu/file_download.php?file_id=198&type=bug
Notes
(0000974)
zesstra   
2009-03-04 16:56   
Gna. And I wonder, why nobody seems to have noticed this issue until now.
The third argument does not need a free_svalue(), because it is just a number, but the stackpointer has to be decreased.
BTW: I think, the first argument (string) is not freed as well.
(0000984)
zesstra   
2009-03-09 15:02   
I modified fippos patch a little bit and changed the two free_svalue of T_NUMBER arguments into sp--. Additionally I added free'ing of the argument string before putting the result string on the stack and removed putting a number on the stack before calling errorf(), because it is anyway without effect.

My system does not support IDNA right now. Could somebody please review/test the attached patch? ;-)
(0000986)
fippo   
2009-03-10 07:35   
(Last edited: 2009-03-10 07:35)
Minor bug: you decrement the sp in the beginning of the argflags block, but it is decremented again at the end of the block.
Seems to be working after fixing that. Otoh, it was worked for me before :-)

p.s.: we don't use that stuff at all since it was renamed to idna_stringprep and our preprocessor directives expect stringprep, silently falling back to lower_case if there is no such efun...

(0000987)
zesstra   
2009-03-10 08:20   
Mhmm. I am confused. I don't have a double decrement in the argflags block, there is only the one at the beginning. Did you apply both patches?
(0000988)
fippo   
2009-03-10 08:31   
psyclpc has the first patch already applied (which has a free_svalue(sp--) at the end), which lead to the double decrement when applying your patch.
(0000989)
zesstra   
2009-03-10 16:25   
This should then be fixed in r2525.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
593 [LDMud 3.3] Compilation, Installation feature always 2009-01-11 15:41 2009-03-03 18:29
Reporter: Gnomi Platform: i686  
Assigned To: zesstra OS: Debian GNU/Linux  
Priority: low OS Version: 4.0  
Status: resolved Product Version: 3.3.717  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Make COMMAND_FOR_OBJECT_BUFSIZE configurable
Description: COMMAND_FOR_OBJECT_BUFSIZE is now fixed at 1000 bytes. It should be configurable and be given to LPC via a permanent define. (I need the define to restrict player inputs to that length.)
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files:
Notes
(0000968)
zesstra   
2009-03-03 18:29   
Done in r2524.
COMMAND_FOR_OBJECT_BUFSIZE was renamed to MAX_COMMAND_LENGTH, made configurable and a __MAX_COMMAND_LENGTH__ (MAX_COMMAND_LENGTH-1) as permanent Define in LPC was introduced.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
81 [LDMud 3.3] Runtime feature N/A 2004-07-12 22:16 2009-02-28 17:14
Reporter: lars Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Better feedback on low memory situations.
Description: When the user/master/system reserve is freed (or reallocated), the master lfun low_memory() should be called, given as argument which reserves are currently unavailable. If the function returns 0, the standard low-memory handling (gc + reallocation attempt) is done. If the function returns 1, the driver assumes that the mudlib took care of things and will just attempt to reallocate the memory.

In addition, a soft max-malloc limit is required - again, if it is exceeded, the low_memory() lfun is called.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: low_memory.diff (33,505 bytes) 2009-01-18 11:54
http://ldmud.eu/file_download.php?file_id=195&type=bug
Notes
(0000869)
zesstra   
2009-01-08 08:06   
I will have a look at this and check if it seems safe to for 3.3.719 or if we should postpone to 3.5. Right now, it doesn't seem to complicated.
(0000870)
Gnomi   
2009-01-08 08:12   
Why should low_memory() return a value? The only thing it does is to prevent a GC run, is this such a good idea?
(0000871)
zesstra   
2009-01-08 08:28   
Im also still unsure, if it is a good idea to prevent it. But on the other hand, consider following (rather constructed) situation:
low_memory() is called and the mudlib decides a) that it would be better to perform the garbage_collection later because it is 19:00 and there are many players playing and b) it has some big objects and it can destruct them and free its memory. Then the mudlib would try to perform a GC during the next night when it disturbs fewer people.
But I think, in this case, the driver should make the GC anyway if the reserves could not be re-allocated (on the other hand: this could be even automatic: call low_memory() -> check if reserves can be re-allocated -> finish or do GC).

And taking this a step further:
It would be probably better to introduce the soft max-malloc (like a low watermark, while max-malloc would be the high watermark), call then low_memory() when hitting soft-max-malloc. The mudlib can then decide to initiate a GC at a convenient time in the near future. If max-malloc is hit before that time, the driver enforces the GC as usual.
(0000873)
Gnomi   
2009-01-08 08:33   
I agree.
(0000922)
zesstra   
2009-01-17 17:24   
I used 'soft-malloc-limit' and SOFT_MALLOC_LIMIT. For the sake of consistency, I would actually suggest to rename max-malloced to hard-malloc-limit and MAX_MALLOCED to HARD_MALLOC_LIMIT... (Renaming the variable max_malloced is not that important, though no big effort.)

The patch is not quite ready, but the basic strategy is to check for the soft malloc limit once per backend cycle (not in every xalloc), that seems completely sufficient for me. If the limit is exceeded, low_memory() is called in the master once. After that another call is only done if the malloced memory shrinks below the soft limit (or the soft limit is raised accordingly).
Additionally I plan to call low_memory() as well, when the hard limit is reached, directly before the GC from the backend. That way, the mudlib master can inform users (the GC is not preventable).
Signature of low_memory(): void low_memory(int what, int limit, int memory_consumption);
(0000928)
zesstra   
2009-01-18 11:58   
Ok, first draft attached. Please comment. ;-)
I renamed the max-malloc to hard-malloc-limit and added the soft-malloc-limit. (The settings files of the various muds are already adapted.)
The soft limit is checked once per backend cycle and the low_memory() function is called as described in previous note.
I added get and set functions for the limits to ensure that the soft-limit is not >= hard-limit and that the hard-limit cannot be set lower then the already allocated memory, because that might lead to an immediate crash. This gets important once the limits can be changed at runtime.

The documentation is included.

An LPC side interface for querying and setting the limits is not in the patch. I will add them once this is finished.
(0000962)
zesstra   
2009-02-28 17:14   
Ok, patch for this is committed in r2523.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
477 [LDMud 3.3] Efuns feature always 2006-06-28 12:59 2009-01-17 11:12
Reporter: fufu Platform:  
Assigned To: fufu OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version:  
Summary: add get_eval_number() efun
Description: int get_eval_number()
Return the current evaluation number. It's incremented for each top-level call. [...]

The intended purpose of this function is to find out if something has already been done for the current command, heart_beat, call_out or whatever. Control flow in mudlibs is often complicated and adding the necessary infrastructure to a mudlib to answer this question is error-prone and tedious. In the driver it's just a few lines of code.
Tags:
Steps To Reproduce:
Additional Information: patch attached. The documentation assumes that the patch in 0000476 has been applied.
Attached Files: get_eval_number.patch (2,838 bytes) 2006-06-28 12:59
http://ldmud.eu/file_download.php?file_id=88&type=bug
Notes
(0000650)
fufu   
2008-07-02 04:31   
Should be nonintrusive enough for 3.3, I believe. Is it considered useful by anybody else?
(0000652)
Gnomi   
2008-07-02 04:50   
I didn't have any need for such a number yet, but I don't object.
(0000653)
zesstra   
2008-07-02 04:57   
Same for me, as yet I don't have a real need, but I can imagine to use it at some point in the future.
BTW: We have to keep in mind the overflow of the counter (see other statistics overflow bugs).
(0000877)
Gnomi   
2009-01-13 08:06   
Can this go into 3.3.719? (I need it for 0000535.)
(0000878)
zesstra   
2009-01-13 08:32   
The counter in the current patch is an unsigned long. The comments and documentation speak about a 32bit integer. I think we should be more precise in the code and use uint32(_t) or change the documentation. Or maybe even better use the to-be-created statistic counter type, see 0000521.
The number is stored in an svalue so the LPC side sees negative numbers (probably no problem). But depending on the exact type we use it may lead to a host-system dependent behaviour in LPC.
(0000879)
Gnomi   
2009-01-13 14:32   
As this counter also (or primarily) goes to LPC it should be of the same type as the LPC int (but maybe only using the positive range).

I don't see a problem with overflows. They will happen, but this number is used to distinguish between threads in one cycle, so that it is improbable to get the same number for different threads. To distinguish over a longer period you should remember the time() too. (To make that clear we could reset the eval number at each cycle?)
(0000881)
zesstra   
2009-01-13 15:26   
Actually, the idea of resetting it in each cycle occurred to me as well because then I (wizard) don't have to bother about checking for the overflow (when the number gets actually smaller). But I was not sure, if the application may need it to increase over a longer period than a cycle.
Concerning using p_int: yes, you are probably right.
(0000882)
fufu   
2009-01-13 16:40   
My original intended use case was to detect whether a function is called twice in the same evaluation. Having false positives with a /very/ low probability would be acceptable. Resetting the counter on each cycle would increase that probability dramatically, so I'd like to avoid it.

I also intended the counters to be compared for equality only. Ordering events (which would make < and <= useful) wasn't an application I had in mind originally. But timestamps can be implemented fairly easily even in the presence of overflows with an sefun:

int last; /* last value from get_eval_number() */
int overflows; /* number of overflows seen by timestamp */

/* assumption: get_eval_timestamp() gets called at least once per __INT_MAX__ top level evaluations */
mixed get_eval_timestamp()
{
    int stamp = get_eval_number();
    if (stamp < last) overflows++;
    last = stamp;
    return ({ overflows, stamp });
}

or, if you want to include the current time:

int then; /* last seen time() */
int last; /* last seen eval number */

/* assumption: fewer than __INT_MAX__ top level evaluations per backend cycle */
mixed get_eval_timestamp()
{
    int stamp = get_eval_number() & __INT_MAX__;
    int now = time();
    if (now != then) {
        then = now;
        last = stamp;
    }
    stamp = (stamp - last) & __INT_MAX__;
    return ({ now, stamp });
}

As for the type, yes, p_int seems to be the right one.
(0000883)
Gnomi   
2009-01-13 16:45   
Agreed.
(0000884)
zesstra   
2009-01-13 16:53   
I am just a bit confused. Isn't impossible that two function calls are in the same top-level evaluation if it is not the same backend cycle? Or better: what do I miss? ;-)
(0000885)
Gnomi   
2009-01-13 16:56   
Fuchur wants to compare the eval_number only (without regard to time()), and without time() you don't know wether you are in the same backend cycle.
(0000886)
zesstra   
2009-01-13 17:08   
Ok, right. I had in my mind a check like
if (debug_info(DINFO_DATA,DID_STATUS,DID_ST_HBEAT_CALLS_TOTAL) && last_eval_no != get_eval_number())
(0000915)
fufu   
2009-01-17 08:40   
Done in svn rev 2501.
(0000918)
fufu   
2009-01-17 11:12   
Zesstra pointed out that in light of 0000596, querying the counter should be done with debug_info instead of a new efun. I've changed this in svn rev 2505.

The new interface is debug_info(DINFO_EVAL_NUMBER)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
473 [LDMud 3.3] Efuns trivial always 2006-06-06 02:27 2009-01-17 10:52
Reporter: Fiona Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.713  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: trim() does not trim \0
Description: trim(str, TRIM_BOTH, "\0") works just fine, but
trim(str, TRIM_BOTH, 0) states that "0 is not a character"

more or less true, but I think it should work anyhow.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000858)
zesstra   
2009-01-08 05:38   
Ok, as far as I see, should be harmless to just disallow number < 0 instead of <= 0. Will do so in 3.3.719.
(0000906)
zesstra   
2009-01-16 14:05   
As trim can already handle "\0", the patch would be to just relax the argument checks:

Index: efuns.c
===================================================================
--- efuns.c (Revision 2491)
+++ efuns.c (Arbeitskopie)
@@ -1616,7 +1616,7 @@
     {
         if (argp[2].type == T_NUMBER)
         {
- if (argp[2].u.number <= 0 || argp[2].u.number >= 1 << CHAR_BIT)
+ if (argp[2].u.number < 0 || argp[2].u.number >= 1 << CHAR_BIT)
                 errorf("Bad argument 3 to trim(): %"PRIdPINT
                        " is not a character\n", argp[2].u.number);
             def_ch[0] = (char)argp[2].u.number;
(0000916)
zesstra   
2009-01-17 10:52   
Changed check for argument values in v_trim() in r2503.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
600 [LDMud] Runtime minor have not tried 2009-01-17 08:47 2009-01-17 08:48
Reporter: fufu Platform:  
Assigned To: OS:  
Priority: low OS Version:  
Status: new Product Version: 3.3.718  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: stale_erq callbacks triggered by attach_erq_demon are treated like new evaluations
Description: stop_erq() in comm.c always resets the eval cost and uses callback_master when executing the stale_erq callback. As a result, if attach_erq_demon() is called to replace an existing erq demon, eval numbers may be incorrect and evaluation costs are reset for the original evaluation as well.

Probably not a big deal: attach_erq_demon is a privileged function.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
599 [LDMud 3.3] Compilation, Installation feature N/A 2009-01-16 18:31 2009-01-16 18:32
Reporter: peng Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.3.718  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: patch to allow cross-compiling
Description: With this patch its possible to cross-compile the driver like in the appended shell-script.
Tags: ldmud-extensions
Steps To Reproduce:
Additional Information:
Attached Files: cross_compiling.diff (10,643 bytes) 2009-01-16 18:31
http://ldmud.eu/file_download.php?file_id=187&type=bug
build_win_and_linux.sh (365 bytes) 2009-01-16 18:32
http://ldmud.eu/file_download.php?file_id=188&type=bug
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
592 [LDMud 3.3] Documentation text always 2009-01-11 11:44 2009-01-16 15:12
Reporter: Sorcerer Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.716  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: documentation of read_file() is misleading
Description: The man-page for read_file() states:
[...]
If <start> is not given or 0, the file is read from the
beginning, else the efun skips the given number of lines and
starts reading from the next one.
[...]

This should be (to be consistent with actual behavior):
[...]
If <start> is not given or 0, the file is read from the
beginning, else the efun starts reading at the beginning of
line <start>.
[...]

The German manpage should be updated accordingly.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000875)
Gnomi   
2009-01-11 12:03   
I like the documented behavior better than the actual behavior. But sadly correcting the actual efun would break a lot of code...
(0000876)
zesstra   
2009-01-11 13:01   
Most of the read_file() calls in MG just read in the whole file. But even so there are still plenty left.
I don't have any preference about the 'start' semantic where the first line to be read is given vs. the 'skiplines' semantic where the number of lines to be skipped is specified. I personally am quite sure it is not worth a lot of work to change the semantics now...
(0000887)
zesstra   
2009-01-13 18:22   
If nobody vetoes, I will change the documentation... ;-)
(0000909)
zesstra   
2009-01-16 15:12   
Changed in r2495, thank you. :-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
558 [LDMud 3.3] Compilation, Installation minor always 2008-08-07 09:09 2009-01-16 14:52
Reporter: zesstra Platform: i686  
Assigned To: zesstra OS: GNU/Linux  
Priority: low OS Version: 4.0  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Too large ITABLE_SIZE leads to errors finding identifiers in the ident_table.
Description: free_shared_identifier() in the lexer doesn't find identifiers in the ident_table if the ident_table is too big.
I made some experiments with its size (config.h.in states it should be chosen several times smaller or equal to the string hash table size). Choosing some value well above 32768 leads the testsuite to fail completely. Note that choosing the size equal to HTABLE_SIZE does not work right now if the HTABLE_SIZE is 65536. ;-)

The reason for this is the fact that ident_s->hash is of type short:
    short hash; /* Hashvalue of this identifier */

We should either change the type here (and check stuff like explicit casts of the hash to short, as in lookfor_shared_identifier()) or enforce an ITABLE_SIZE of <= 32768 by some precompiler check and update the comment in config.h.in.
Tags:
Steps To Reproduce: Set ITABLE_SIZE in config.h to 65536, recompile and execute the testsuite.
Additional Information: Testsuite log:
[...]
2008.08.07 14:41:26 free_shared_identifier: name 'str' not found!
2008.08.07 14:41:26 Current object was <null>
2008.08.07 14:41:27 Failed to load master object 't-mantis'.
Test t-mantis.c FAILED.
The following tests FAILED:

    t-0000398
    t-0000486.c
    t-0000488.c
    t-0000523.c
    t-0000524.c
    t-0000532.c
    t-0000534.c
    t-0000548
    t-030925
    t-040413
    t-041124
    t-efuns.c
    t-errors.c
    t-mantis.c
System Description MorgenGrauen server
Debian Etch.
Attached Files:
Notes
(0000854)
zesstra   
2009-01-08 04:56   
Any preferences for dealing with this? Enforcing a max of SHORT_MAX would be the easiest, 32k hash chains sound like a lot.
But on the other hand the ident_table seems to be a global table of all identifiers in the game (or am I wrong here?). A clean solution would be to use a specific hash type as well, maybe with an automatic selection of the underlying basic type according to ITABLE_SIZE?
(0000856)
Gnomi   
2009-01-08 05:19   
The ident_table contains all global identifiers (efuns and permanent defines) as well as the identifiers of a compiled program that are removed from the ident_table after compilation. 32k seems enough for now, so I'm fine with both solutions.
(0000859)
zesstra   
2009-01-08 05:46   
Ok. Then I will limit ITABLE_SIZE for 3.3.x and have a second look concerning hashes and hash types in 3.5.x during harmonizing all the other hashes. (0000564, 0000518).
(0000907)
zesstra   
2009-01-16 14:37   
Ok, the immediate issue should be solved by r2494.
I will probably open a separate bug in 3.5 for the issue of changing the hash.
(0000908)
zesstra   
2009-01-16 14:52   
I just thought again about the ident_t hashes. identhash() already uses the hash functions from hash.c and as 32k hashchains should be really sufficient for the fore-seeable future, there is IMHO no real demand for changing things, as long as the limit is documented. I added it to /doc/driver/limitations.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
559 [LDMud 3.3] Portability crash always 2008-08-09 19:45 2009-01-14 16:32
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Crash in functionlist() (64 bit issue)
Description: There is a crash in f_functionlist(), presumably on 64 bit systems.
As we had a reboot and major mudlib update (with plenty of own problems) today I hadn't had the time to look into it, but the crash occurs in line 1877:
1871 /* If its a cross-defined function, get the flags from
1872 * real definition and let j point to it.
1873 */
1874 if ( !~(flags | ~(NAME_INHERITED|NAME_CROSS_DEFINED) ) ) {
1875 active_flags |= NAME_CROSS_DEFINED;
1876 j = (long)CROSSDEF_NAME_OFFSET(flags);
1877 flags = fun[j];
1878 j += i;

CROSSDEF_NAME_OFFSET seems to calculate a wrong offset j (s. additional information as well).
Tags:
Steps To Reproduce: Compile the driver for an LP64 platform and execute
functionlist(find_object("/some/object"),RETURN_FUNCTION_NAME)
where /some/object should have some cross-defined inherited function.
Additional Information: Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000503436e3c
0x00000001000a4224 in f_functionlist (sp=0x10017ff10) at object.c:1877
1877 flags = fun[j];
(gdb) bt full
#0 0x00000001000a4224 in f_functionlist (sp=0x10017ff10) at object.c:1877
    funstart = (fun_hdr_p) 0x10345e6a8 "\001"
    active_flags = 2148139008
    ob = (object_t *) 0x1034479a0
    mode_flags = 1
    prog = (program_t *) 0x103432380
    num_functions = 597
    vis_tags = 0x7fff5fbf9ca0 "\005\005\005\005\005\005\005\001\005\005\005\005\005", '\001' <repeats 12 times>, "\005\005\001\001\005\005\005\005\005\005\005\005\005\005", '\001' <repeats 29 times>, "\005\001", '\005' <repeats 16 times>, '\001' <repeats 24 times>, '\005' <repeats 11 times>, "\001", '\005' <repeats 18 times>, "\001", '\005' <repeats 19 times>, "\001\001\001\005", '\001' <repeats 11 times>, "\005\005\001\001\001\001\001\001\001\001\005\005\005\005\005\005\005\005\001\001\001\001\001\001\001"...
    list = (vector_t *) 0x104e52220
    svp = (svalue_t *) 0x104e544e0
    fun = (uint32 *) 0x1034373fc
    defprog = (program_t *) 0x103432380
    flags = 2148138640
    ixp = (short unsigned int *) 0x103436990
    i = 553
    j = 4294966928
[...]
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0000850)
zesstra   
2009-01-04 18:09   
Ok... I had a second look:
(All on an LP64 machine -> sizeof(long)==8)

CROSSDEF_NAME_OFFSET is:
#define CROSSDEF_NAME_OFFSET(flags) \
     (((flags) & INHERIT_MASK) - ((INHERIT_MASK + 1) >> 1))

flags was 2215247613, so:
    (2215247613 & 262143) - ((262143 +1) >> 1)
which should be -259.
BUT: in functionlist() flags is a uint32, so the -259 are actually 4294967037. Now, these are implicitly converted to long, used for indexing and - ZAP.

Most other users of CROSSDEF_NAME_OFFSET use it with a signed int which result in the correct -259.

Gnomi pointed out an interesting part in interpret.c (setup_new_frame1() and eval_instruction()). It uses a uint32 flags as well, so the CROSSDEF_NAME_OFFSET define also calculates to 4294967037. BUT: in interpret.c the result is implicitly converted to signed int before using it. 4294967037 is larger than INT32_MAX, so during the conversion, it wraps around and is interpreted as -259 which again works (more by chance, I would say)...

So... Another case for not using defines. ;-)
(0000891)
zesstra   
2009-01-14 16:32   
This should be fixed by r2492. That patch introduces a properly typed CROSSDEF_NAME_OFFSET (and others).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
525 [LDMud 3.3] Runtime minor always 2008-01-25 17:43 2009-01-13 15:11
Reporter: Coogan Platform:  
Assigned To: zesstra OS:  
Priority: low OS Version:  
Status: resolved Product Version: 3.3.715  
Product Build: Resolution: fixed  
Projection: minor fix      
ETA: none Fixed in Version: 3.3.719  
    Target Version: 3.3.719  
Summary: Allow objects with empty names (again)
Description: In Tubmud, we use the file '/.c' for the very important archwizard-meeting-room. Therefore, the current "solution" of bug 0000500 is suboptimal.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000585)
Coogan   
2008-01-25 17:44   
subject is mis-typed, it should be 0000500.
(0000860)
zesstra   
2009-01-08 06:00   
I had a discussion with Gnomi about the issue of objects with empty names. His opinion is, that there is no conceptual issue preventing this and any problems should be fixed. Its OK for me, but please keep in mind, that there maybe problems. If in doubt, you might want to dis-allow to create /.c in your mudlib and restrict rename_object().
(0000880)
zesstra   
2009-01-13 15:11   
Resolved by r2486.
However, please keep in mind, that there *may* be other issues with empty object names. Use them at your own risk.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
48 [LDMud 3.5] Runtime feature N/A 2004-04-03 12:09 2009-01-08 08:10
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Use Root-Pointer table to avoid swapping objects during GC.
Description: Install a root-pointer table (hashed over the pointer targets) in which every entry has a refcount and a pointer to the associated target.

For every entity referenced from a swapped out object (strings, mappings, vectors) establish a root-pointer entry pointing to the entity. The refcount counts how many of such external references exist to the entity.

This way during a GC it is no longer necessary to swap in all objects just in order to count the references - reducing the time and memory needed, and reducing the fragility of the GC process.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000045)
lars   
2004-04-04 03:34   
Instead of 'root pointer' this should be called 'proxy'.

The module would offer two main methods:

proxy_t * handoff_ref (void * entity, int entity_type)

  Hand the ownership of the reference to <entity> over to the proxy table, and receives the pointer to the proxy responsible in return.

void * retrieve_ref (proxy_t * root_ptr)

  Retrieve the ownership of the reference to <entity> from the named proxy. The returned pointer to the <entity> can be different from the pointer the proxy was created for.

For this to work, the proxy_t would have to store the hash index in the proxy table.

-------------

This approach offers another benefit: once the proxy holds the only remaining reference to the entity, the entity could be swapped out. This way the complexity of the variable swapping in the swapper could be reduced, and at the same time more data becomes eligible for swapping. This could even be generalized to the normal program swapping.

Problematic however would be mappings (object/closure keys can get stale or require resorting), and maybe alists. Such entities would have to have a flag or special type (T_MAPPING | T_MOD_REF) so that the GC knows that it would have to swap these entities back in in order to remove the references to destructed objects. Without entity-swapping this wouldn't be a problem as such entities would stay resident (the swapper refuses to swap them out even if there is just one ref left).

Things to check first, before implementing the swapability: how many proxies would there be in a normal mud, and how many of these would be eligible for swapping? Also, add a time measurement to the GC.
(0000059)
lars   
2004-05-10 12:20   
In order to do this, the program structure should be split into two parts (header and dynamic data) - this is already a TODO in exec.h .
(0000060)
lars   
2004-05-10 12:33   
The proxy module should also keep condensed string_t* and struct_type_t* tables, referenced from program_t* structures, to keep track of function names (always tabled) and structure references from swapped-out programs. Using the generic proxy types for this would incur too much overhead.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
57 [LDMud 3.5] Runtime feature N/A 2004-05-10 12:32 2009-01-08 08:08
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Indirectly reference string literals
Description: In programs, use a string literal indirection to access strings:

struct stringlit_s {
  ptrdiff_t start_index;
  size_t len;
  string_t * cache;
}

struct stringlit_s * string_literals;
unsigned char * string_literal_data;

where .start_index is an offset into string_literal_data where the .len string bytes can be found. Once a string literal has been looked up, the created string structure is stored in .cache .

A second set of these structures/types is used to store the include filenames (this could be combined with the linenumber datablock). Here it would be useful to create datablock for the filenames at the time of swap-out, so that while the object is first in memory, the filenames are not duplicated.

This way it will be possible to swap out the string literal data and include filenames instead of holding them in memory all the time. It would even possible, once the strings had been swapped out once, to create strings directly from the swap

  string_t * swap_get_string(swap_offset, len)

instead of swapping all the data back in when the program is swapped in.

Another side effect is that a GC doesn't need to keep track of a program's string literals.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
62 [LDMud 3.5] Implementation feature N/A 2004-05-20 22:18 2009-01-08 07:19
Reporter: lars Platform:  
Assigned To: OS:  
Priority: low OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: TRACE_CODE can be a runtime feature
Description: It is possible to store the TRACECODE flag (on/off) in a variable, avoiding speed loss by copying it into a local variable in eval_instruction().

In a more elaborate version, the tracecode activation and trace buffer length could be completely controlled from the mudlib; avoiding re-compilations.
Tags:
Steps To Reproduce:
Additional Information: Test run on an 8-CPU AIX box:
#undef TRACECODE: 5100 dhry/s
#define TRACECODE: 4000 dhry/s

TRACECODE global inactive: 5050 dhry/s
TRACECODE global active: 3850 dhry/s

TRACECODE local inactive: 5100 dhry/s
TRACECODE local active: 3900 dhry/s
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
474 [LDMud 3.5] Runtime feature always 2006-06-11 14:36 2009-01-08 06:50
Reporter: Zarquon1 Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.3.712  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: only static function should be callable on not fully loaded and initialized objects
Description: if you call a function of an not initialized object the function could not use the variables because the are all NULL,
so i think its good if only static functions should be called on non-initilized objects and the non-static are only callable if the object ist fully setup
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
337 [LDMud 3.5] LPC Language feature N/A 2005-01-06 17:45 2009-01-08 06:41
Reporter: Gawain Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.3  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: bigint patch for 3.3
Description: this is a patch i wrote some time ago to bring bigints to lpc.
unfortunately i have currently no time available to work on it.
perhaps someone want to take over.

the patch introduces a new datatype "bigint" to lpc.
the operations + and - are working, others have to be implemented.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: bigint.diff (26,199 bytes) 2005-01-06 17:45
http://ldmud.eu/file_download.php?file_id=52&type=bug
bigint_test.c (704 bytes) 2005-01-06 17:49
http://ldmud.eu/file_download.php?file_id=53&type=bug
Notes
(0000289)
Gawain   
2005-01-06 17:48   
this is a small object to test compilation and functionality.
(0000861)
zesstra   
2009-01-08 06:41   
I would suggest to postpone this to 3.5 and do some cleanup of the type stuff before (non-optional structs) to limit the number of #ifdefs there.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
255 [LDMud 3.3] Efuns feature N/A 2004-11-27 00:07 2009-01-08 05:37
Reporter: lars Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: present_clone() should allow 'id <n>' form
Description: Short: Extension for present_clone()
From: Andy <Andreas.Klauer@epost.de>
Date: Mon, 23 Jul 2001 21:37:21 +0200
Type: Feature
State: New

Hi Lars,

bei present() gibt es die Form "<id> <n>" fuer den String, um zu pruefen, ob es
ein n-tes Objekt gibt, das auf <id> passt.

Bei present_clone ist es leider nicht moeglich, eine solche Nummer anzugeben.
Das finde ich schade, da ich diese Funktion oft verwende (schliesslich ist sie
ja zum einen viel billiger als present, zum anderen braucht man dem Objekt dann
keine zusaetzliche ID geben...).

Wie waere es mit einem extra-Argument int number nach environment (um die
Kompatibilitaet zu wahren).

Als neuer Parameter deswegen, damit man im Falle dass man ein Objekt uebergibt,
diese Nummer dennoch mit angeben kann.

Man koennte auch bei einem String die Form "<id> <n>" belassen und nur bei
uebergebenem Objekt einen Zusatzparameter number zulassen.

Ich faende es jedenfalls schoen, wenn man die Funktion auf diese Weise
erweitern wuerde und sie somit gleichwertig mit present() machen wuerde.

Waere auch gut, wenn diese Funktion etwas bekannter werden wuerde, da meistens
present dazu verwendet wird, um zu schauen, ob ein Objekt im reset geklont
werden muss oder nicht (was dazu dann noch schieflaeuft, wenn ein anderes
Objekt diese id besitzt...)

Gruss
Menaures@UNItopia
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000855)
zesstra   
2009-01-08 05:04   
Ah, should be fixed by r2461.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
566 [LDMud 3.5] Implementation minor N/A 2008-09-09 16:16 2009-01-06 08:23
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: assigned Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Replace Code-Defines by static inline functions
Description: There are a lot of macros in the driver for convenience, which evaluate to some value or do some little things and are often called, e.g.
#define mstrsize(s) \
    ((s)->size)
from mstrings.c.

I would like to change these defines to static inline functions. Modern compilers are good at inlining (they would even inline without requesting it by 'inline') and the runtime behaviour is identical to the preprocessor macros.
But functions have (at least) three big advantages:
a) they are visible to the compiler and thus the debugger.
b) for debugging it is possible to disable inlining and/or set breakpoints (which you can't in case of preprocessor macros).
c) type safety: functions have explicit types for their arguments and return values and the compiler can check them, which it can't in case of macros. Additionally it is much easier for the programmer to keep track of types and the code is less error-prone.

Example for c):
If I don't know the type of s->size, I have to do a tedious search for the type and definition of s.
A function: static inline size_t mstrsize(string_t *s) {return s->size;}
is much easier in this respect and the compiler can issue warning if foo in mstrsize(foo) is not a pointer to string_t or if len in len=mstrsize(foo) is of an incompatible type.


I suggest to change all macros, which do not change local variables bit by bit to static inlines functions.


side remark:
even for numerical constants defines are not really needed and have again the disadvantage that the define in not visible in the debugger. If you use 'static const long LIMIT 2' the generated code is _exactly the same_ as if you use '#define LIMIT 2L'. (static ensures that the compiler doesn't emit a symbol LIMIT in the data segment.)
So I would even recommend using consts for numerical constants as well, there is no speed or memory penalty (in modern compilers).
Tags:
Steps To Reproduce:
Additional Information: http://www.fefe.de/know-your-compiler.pdf
http://www.greenend.org.uk/rjk/2003/03/inline.html
http://gcc.gnu.org/onlinedocs/gcc/Inline.html
Attached Files: comm.c.diff (3,720 bytes) 2008-09-10 16:15
http://ldmud.eu/file_download.php?file_id=152&type=bug
alloc.diff (12,762 bytes) 2008-09-10 17:39
http://ldmud.eu/file_download.php?file_id=153&type=bug
sprintf.c.diff (14,198 bytes) 2008-09-11 15:50
http://ldmud.eu/file_download.php?file_id=154&type=bug
Notes
(0000768)
zesstra   
2008-09-09 16:50   
Ah, I just had a look at the linked talk again. FTR: it actually recommends to use only "static" because the compiler will then inline small functions or functions which are called only once anyway. That is probably even true...
(0000769)
Largo   
2008-09-09 17:00   
d) expression safety:

BLUBB(foo++)
#define BLUBB(x) ((x) + (x)) vs.
inline int BLUBB(int x) { return x+x; }
(0000826)
zesstra   
2008-12-23 08:19   
Uh, thank you Largo. I didn't even notice that you attached patches here (probably best to attach a note as well). I will have a look during the next days.
(0000835)
zesstra   
2008-12-29 06:09   
The patches seem to be fine for me with one small change: inline -> static INLINE to prevent gcc from emitting a stand-alone copy of the function, if it sucessfually inlines it everywhere. (INLINE as Makro for now, until we eventually require (most of) C99 in 3.5.x)
Actually, 'static' alone may be fully sufficient because the compiler usually decides itself if it honors the request for inlining or not. But I guess, it does not harm either as kind of hint for the programmer.

There is another possibility: to declare the function as 'extern inline' in all but one compilation unit, but it is a little more complicated to do so and I am not sure if it is worth the effort.
(0000853)
zesstra   
2009-01-06 08:23   
The #defines in bytecode.h are also a good candidate for this, especially in the light that we have to check the types very carefully on LP64 platforms. If we use typed functions the compiler might help us (like in 0000559).

Unfortunately, some of them increment/decrement an argument:
#define STORE_CODE(p,c) (*(p)++ = (c))

A possibility is to use a pointer to pointer as argument:
static INLINE bytecode_t store_code (bytecode_p *p, bytecode_t c) {
    *((*p)++) = c;
    return c;
}
together with a #define STORE_CODE(p,c) store_code (&(p),(c))

Or we can get rid of the macro altogether with something like:
%s/STORE_CODE(\(.*\), \(.*\))/store_code\(\&\(\1\), \(\2\)\)/gc
in vim which I would actually prefer.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
591 [LDMud 3.5] Implementation feature N/A 2009-01-05 12:44 2009-01-05 12:44
Reporter: zesstra Platform: x86_64  
Assigned To: OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: sprintf should use dynamic buffers
Description: sprintf uses currently a static buffer (usually 128kb) for creating its result strings. Especially when working in array mode this can be really unconvenient because usually it is not exactly known how much text is in the array.

In the longer run it should be changed to use the dynamic string buffers in the driver to create its result.
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
515 [LDMud 3.3] Other feature N/A 2007-09-14 04:37 2009-01-04 14:34
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: Seeding the PRG with a more reliable source of randomness
Description: Currently the random number generator ist seeded with the system clock at driver startup. This enables people guessing the seed. While this is probably not a big problem in case of a mud, IMHO it is still desirable to enable users to seed the PRG from /dev/urandom or /dev/urandom. (I know, it is possible to seed with a user-defined seed, but this is limited to a single 32-bit value.)
I will attach a small patch, which introduces a command-line argument to choose whether to seed from the current driver time/system clock or with 624 32-bit values from /dev/random or /dev/urandom.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: randomseed.diff (7,117 bytes) 2007-09-14 15:38
http://ldmud.eu/file_download.php?file_id=105&type=bug
Notes
(0000541)
zesstra   
2007-09-14 15:37   
Ok, my suggested patch does the following:
- rename random_seed(uint32) to random_seed_from_int(uint32)
- introduce random_seed(ph_uint mode): Seeds the PRG from current_time (mode==0), from /dev/random (mode==1) or from /dev/urandom (mode==2). If /dev/(u)random doesn't supply the 624 uint32 values, current_time will be used as fallback.
- move debug messages concerning the seeding of the PRG from main.c to random.c (seed_random_from_int() and seed_random()).
- removes now unneeded static uint32 random_seed from main.c
- add command-line option --randominit which takes 0|1|2.
- adds --randominit to doc/driver/invocation

The default behaviour of the driver should not be changed by this, /dev/(u)random will only be used if specified at command-line. --random-seed is also usable as before.
BTW: The last one of --randominit or -random-seed in the arguments wins.
(0000848)
zesstra   
2009-01-04 14:34   
Combined patch with SFMT (0000527) committed as r2470.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
519 [LDMud 3.3] Efuns feature N/A 2007-09-24 09:41 2009-01-03 12:04
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: present_clone(): deep-inventory search and search for <object> no. x
Description: Recently I discussed with Honey@Silberland the efun present_clone() and we both missed one or two features for a better replacement of present().
The suggestion it to give the efun additional optional arguments and enable it to
a) perform a deep-inventory search in the given environment
b) enable it to find object no. x, e.g. present_clone("/obj/bottle", this_player(), 4) for finding the forth bottle in the inventory of TP.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: present_clone.diff (5,749 bytes) 2008-12-31 08:28
http://ldmud.eu/file_download.php?file_id=177&type=bug
Notes
(0000642)
Gnomi   
2008-07-01 05:23   
Searching for a n-th object like the present efun is a good idea.

Regarding a) we have to decide how far we want to extend present(_clone). In UNItopia we have one big simul-efun (http://www.unitopia.de/doc/efun/a-m/cond_deep_present.html) that does two forms of deep searching and allows to filter the results using a closure, both could be integrated into these efuns. I'm just not sure whether we should bloat present(_clone) or keep them simple.
(0000686)
zesstra   
2008-07-08 17:02   
After some consideration I think, we should implement b) and leave a deep search to the mudlib to keep the interface simpler. (Or use a separate deep_present_clone().) Three optional arguments don't do any good for keeping it clear.
I suggest to match the interface of present_clone() with that of present(), with the exception that something like "bottle 42" is not accepted but has to be given in form of present_clone("bottle", 42):
        object present(string str)
        object present(string str, int n)
        object present(string str, object env)
        object present(string str, int n, object env)

        object present(object ob)
        object present(object ob, object env)
(0000695)
Gnomi   
2008-07-09 02:48   
Agreed.
(0000805)
zesstra   
2008-10-08 17:18   
I prepared a patch for present_clone() which introduces an optional third argument to specify to search for the <n>th object in the given environment. The second argument remains optional as well and defaults to this_object().
The interface would be:
object present_clone(string str [, object env, [int n]])
object present_clone(object obj [, object env, [int n]])

n as second argument would be nicer because it would be the same interface as present() has, but I guess to much code would have to be changed. Therefore I am suggesting to use it as third argument.
(0000806)
Gnomi   
2008-10-08 17:29   
What kind of code has to be changed? A number as a second argument is now illegal, so there should be no problem with current LPC code.
(0000807)
zesstra   
2008-10-08 18:04   
Ok, you are right, if we accept
object present_clone(string|object, object|int|void, object|void);
we may sort it out in the efun.
I had
object present_clone(string|object, int|void, object|void);
in mind which breaks the current interface.

Personally I don't like it very much if arguments can have several different semantics, because it 'dilutes' the interface and makes it somewhat arbitrary, therefore I did not think of this. It complicates argument checks as well and I actually perceive the function as more complex zu remember. But there may be other optinions about this.
(0000830)
zesstra   
2008-12-26 12:04   
Ok, call for last comments please. ;-) As I said, I don't like it very much to give arguments more meanings than necessary and personally I prefer
    object present_clone(string|object, int|void, object|void)

But if people are wishing otherwise, I can live with a different interface as well.
(0000831)
Gnomi   
2008-12-26 17:44   
object present_clone(string|object, int|void, object|void) breaks the current interface, so I don't like that. I'd like to have present_clone() similar to present(). It wouldn't be intuitive if present("id", where) works and present_clone("id", where) doesn't, or if the same arguments got another order in present_clone() than in present(). It is not nice to implement in the driver but I think a plausible interface towards LPC is more important.

And remembering the function as present_clone(string str [, int n] [, object where]) is not hard. And it's not unprecedented that arguments in the middle can be optional (e.g. function_exists, input_to).
(0000833)
zesstra   
2008-12-29 05:40   
Gna. My mistake.
I actually meant object present_clone(string|object, object|void, int|void), which does not break the current interface.
You are advocating for
  object present_clone(string|object, object|int|void, int|void)
then?
My critique on this is just that the semantic of the second argument is less defined and the driver can't detect some programming mistakes during the syntax checks any more. And unless I am still not really awake, something like present_clone("bla",ob) can be nasty, if <ob> is destructed and there actually is a different "bla" in this_object().
(0000836)
fufu   
2008-12-29 06:47   
We can fix the present_clone("foo", 0) ambiguity in two ways:

- present_clone(string|object [, int n] [, object env]), where n is not allowed to be 0, or
- present_clone(string|object [, object env [, int n]]), where env can be 0.

I like the first one slightly better because it mimics present().

(I'd like to forbid passing 0 for n in present as well, but it's far too late for that.)
(0000838)
Gnomi   
2008-12-29 10:10   
I'm in favor of disallowing 0 as <n> or <env>. Searching the 0th element doesn't make any sense and a destructed object is usually not accepted by any efun.
(0000839)
zesstra   
2008-12-29 13:08   
I favor the second possibility (mainly because of the better type-safety (at compile-time) and more stringend interface), but you two are the majority.
But: Searching for the 0th element can make perfect sense (like when indexing arrays), it is just a convention where to start counting. Starting with 1 and accepting 0 as alias to 1 as present() does is of course not very reasonable.

BTW: there are some efuns which accept destructed objects or 0 (e.g. living(), clonep(), object_name(), program_name() and of course present()). Should we think about changing them?
(0000844)
zesstra   
2008-12-31 08:40   
I applied a patch which implements the
  object present_clone(string|object, object|int|void, int|void)
interface. Preliminary testing looks good, but I have to go now and will test a little bit more while I am away.
(0000845)
zesstra   
2009-01-03 12:04   
Slightly improved version of the patch (stricter checks for the count argument) plus documentation changes commited as r2461.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
586 [LDMud] Efuns feature N/A 2008-12-12 17:18 2008-12-29 18:15
Reporter: fufu Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.3  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Allow querying single stack frames using debug_info(DINFO_TRACE)
Description: There is some demand for efuns like previous_function(), previous_program() and a variant of previous_object that reflects the actual control stack. In principle, debug_info(DINFO_TRACE, DIT_CURRENT) provides this information already, but it only allows to query the whole stack trace at once, and building that isn't exactly cheap.

Proposal: Add an extra (optional) argument to debug_info: debug_info(DINFO_TRACE, DIT_CURRENT, n) would return the current (n=0), calling (n=1), and so on stack frame info, or 0 if the stack depth is exceeded.

For consistency this should also be implemented for DIT_ERROR and DIT_UNCAUGHT_ERROR. Interestingly, performance is not an issue in those cases: The array is built when the error happens, and debug_info() just returns a reference to that.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000842)
zesstra   
2008-12-29 18:15   
In 0000569 was suggested to add a flag in the stack trace to indicate if the function call was a call_other (inter-object call) or a intra-object function call. I think, we should keep track of this suggestion here.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
573 [LDMud 3.3] Efuns feature N/A 2008-09-13 16:04 2008-12-14 16:13
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: low OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: Efun returning the current depth of the control stack
Description: I would like to discuss an efun (or extension of debug_info) which just returns the current (control) stack depth.
We have some recursive functions in the lib where it would be nice to detect if it approaches the maximum recursion depth (__MAX_RECURSION__). That way it could terminate in a controlled way or maybe event switch to a different (non-recursive) strategy.
A possible alternative may be to catch() the recursive calls and react on errors, but I don't like that very much because then it is only one level below the limit, and the return value has to be parsed in order to find out the type of error. Additionally it might spam the error log (or one misses other errors in the recursive function).
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: stack_depth.diff (1,835 bytes) 2008-10-05 12:55
http://ldmud.eu/file_download.php?file_id=167&type=bug
stack_depth-V2.diff (2,177 bytes) 2008-12-12 17:26
http://ldmud.eu/file_download.php?file_id=173&type=bug
Notes
(0000804)
zesstra   
2008-10-05 12:56   
The attached patch introduces an efun stack_depth(), which just returns the number of frames used on the control stack.
Please comment, especially if you would prefer to have the functionality in debug_info() (or not at all).
(0000814)
zesstra   
2008-12-12 17:28   
We just had a discussion on -d-code about this and agreed to put this functionality into debug_info().
I revised the patch and uploaded it as stack_depth-V2.diff. The control stack depth is returned upon calling debug_info(DINFO_TRACE,DIT_CURRENT_DEPTH).
(0000818)
zesstra   
2008-12-14 16:13   
Applied in r2447. ;-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
516 [LDMud 3.3] Efuns feature N/A 2007-09-14 16:51 2008-12-12 16:20
Reporter: zesstra Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: Additional efuns for date/time conversion to strings and calculating a unix timestamp
Description: I (and probably other wizards too) often miss 2 efuns concerning date and time:
1a) an efun to convert a timestamp to a string with the possibility to specify a format string (like strftime() in libc).
1b) this efun should be able to use languages other than english (e.g. for weekday names)
(Both could be done as sefun, but I think, that is a really ineffective choice (see below))

2) an efun to convert a date/time into the corresponding unix timestamp (mktime() in libc). This is probably less often used but it is a serious problem, if you have to do it. Many wizards write some lfuns for this, but it is really easy to miss something like leapyears/leapseconds this way.

I would suggest:
1a) The driver already uses strftime() from libc. We could give ctime() a second optional argument for specifying a format string. That string would be passed through to strftime(), which provides the full flexibility of strftime() for ingame use.
1b) strftime() honours Locales. The driver may set the Locale category for time/date handling from the environment variable LC_TIME/LC_ALL through calling setlocale() at driver start. A new efun ltime() could use strftime() with the "correct" local Locale set (e.g. de_DE, es_ES). In case of ctime() the driver could temporarily switch to the standard "C" locale. This way we have the classical ctime() and a localized ltime() for non-english muds.

2) There ist a libc-function called mktime(), which does exactly this. It should be simple to create an efun mktime(), which gets an array of ints like the one localtime() returns. The efun creates a corresponding tm struct, calls mktime() and returns the time stamp.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: mktime_strftime_v1.diff (14,698 bytes) 2007-09-20 10:33
http://ldmud.eu/file_download.php?file_id=110&type=bug
mktime.diff (3,544 bytes) 2008-05-18 18:41
http://ldmud.eu/file_download.php?file_id=125&type=bug
strftime.diff (10,044 bytes) 2008-05-18 18:42
http://ldmud.eu/file_download.php?file_id=126&type=bug
strftime_cached.diff (13,011 bytes) 2008-05-18 18:42
http://ldmud.eu/file_download.php?file_id=127&type=bug
mktime_strftime_noncached.diff (12,561 bytes) 2008-05-18 18:42
http://ldmud.eu/file_download.php?file_id=128&type=bug
mktime_strftime_cached.diff (15,527 bytes) 2008-05-18 18:42
http://ldmud.eu/file_download.php?file_id=129&type=bug
Notes
(0000544)
zesstra   
2007-09-20 10:34   
I uploaded a patch with the 2 new efuns: mktime() and strftime(). The patch got a bit larger than expected. ;-)

1. mktime() takes an array like the one localtime() returns and converts it to a timestamp by calling the libc mktime().

2. strftime() is varargs and takes up to 3 arguments: format string, timestamp and a flag specifying the locale to use ("C" or the one specified by the environment variable LC_TIME/LC_ALL). This efun will not take a utime argument, because you would have to implement a specific format identifier for the microseconds and parse the strings yourself, which probably should better be done in an sefun.

For strftime() I made some changes to port.c|h:
a) New function: char *time_fstring (mp_int t, const char* str, Bool localized).
If localization ist not requested, the locale is temporarily changed to the "C" locale and set back before leaving the function. I chose it this way, because the f_ctime()-Result ist cached, while the one for v_strftime() is not (at the moment).
b) time_string() was removed, f_ctime() now calls time_fstring() with the appropriate arguments.
c) utime_string() should have cached the result, but that didn't work because the variables weren't static. (same in time_string()) As it is quite unlikely, that the microsecond value does not change from one call to the other, I think it is not worth trying to cache the result and removed caching altogether from that function.

Changes in efuns.c|h
a) new efuns
b) ctime() calls time_fstring().
c) ctime() now caches the result as tabled string in the efun. Consecutive calls with the same time argument to ctime() use about 20% of the first call.

Changes to main.c
a) activating the LC_TIME locale category and setting it to the locale specified by LC_ALL/LC_TIME.

Potential Todos:
1. time_fstring() should be able to use format string longer than 511 Chars.
2. Caching for v_strftime(). This probably requires implementing some kind of GC support and initialization function in efuns.c.

I will create manpages for the efuns soon and attach them. If you like to have a look at the changes, the new efuns and/or try the patch, please do and comment. ;-)
(0000545)
zesstra   
2007-09-30 16:49   
I just want to note, that the caching in the suggested patch behaves rather badly with the garbage collector. I have removed the caching for now from my code at home until I have time to write some caching mechanism which actually works with the GC. If you are interested, I can upload the non-caching functions in the meantime.
(0000622)
zesstra   
2008-05-18 18:43   
I prepared a new set of patches (applying cleanly against r2364). I splitted the patch into two and added a cache mechanism to ctime() which actually works this time. ;-)

mktime.diff: only the efun mktime()
strfime.diff: only the efun strftime() (including changes to port.c|h and ctime())
strfime_cached.diff: only the efun strftime(), cached version (including changes to port.c|h and ctime())

For convenience, because the 2 separate patches do not apply cleanly, I revised the combined patches:
mktime_strftime_noncached.diff: mktime() and strftime(), non-caching ctime()
mktime_strftime_cached.diff: mktime() and strftime(), caching ctime()


Note: The cache for ctime() was formerly in time_string() in port.c. I removed it there and put it a level higher in the efun, which spares the driver for searching the string hash table for the cached result from time_string() in port.c.
Comparison of 300k ctime() calls:
old: 752 ms
new, cached: 85 ms

Note2: For compatibilty with the garbage collector I added clear_ref_from_efuns() and count_ref_from_efuns() to efuns.c and call them from gcollect.c for counting the refs to the ctime cache.
(0000803)
zesstra   
2008-10-04 18:12   
I would like to include these efuns in the next release. We have them in use in Morgengrauen for about a year, the current versions for about 2 months. I still have to prepare the english manpages. Are there any objections against these 2 new efuns?
(0000813)
zesstra   
2008-12-12 16:20   
Applied latest patches, added german and english manpages and committed as r2440 (3.3.718).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
539 [LDMud 3.2] LPC Compiler/Preprocessor minor always 2008-05-08 10:22 2008-09-22 02:45
Reporter: Coogan Platform:  
Assigned To: Gnomi OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.13  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.2.16  
    Target Version:  
Summary: Missing initialization of local variables in some cases
Description: This is a copy of bug 0000537, as it also applies to the current 3.2 series of the driver.
The test fragment

  int a;
  { int b = 42; }
  int c;
  printf("%d\n", c);

returns 42, not 0.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000789)
Gnomi   
2008-09-22 02:45   
Fixed in r2428.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
563 [LDMud 3.3] Documentation trivial N/A 2008-09-06 11:09 2008-09-21 13:21
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.718  
    Target Version:  
Summary: Misleading info on __LPC_ARRAY_CALLS__ in german Manpage of call_other
Description: The german manpage states
        Damit auch Arrays von Objekten akzeptiert werden, muss das Makro
        __LPC_ARRAY_CALLS__ gesetzt sein.
which can be interpreted as:
        If arrays of objects should be accepted, the macro __LPC_ARRAY_CALLS__
        has to be set.
I suggest to change that to
        Falls Arrays von Objekten akzeptiert werden, ist das Makro
        __LPC_ARRAY_CALLS__ gesetzt.

Does anyone object?
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0000787)
zesstra   
2008-09-21 13:21   
Changed in r2415

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
571 [LDMud 3.5] Portability minor N/A 2008-09-11 09:52 2008-09-11 09:52
Reporter: zesstra Platform:  
Assigned To: OS:  
Priority: none OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Using strerror() to get meaningful error messages from errno
Description: Some parts of the driver (e.g. comm.c, ERQ daemon) use switch(errno) to convert errno to some error message. Some don't even bother with that at just output the plain errno (e.g. swap.c).
I suggest to use strerror(errno) in the long run for this. It is easier and probably more portable. It could ease debugging, because if someone reports 'errno 104' in a bug report, it has no real meaning in itself. One has to look up the 104 in /usr/include/*/errno.h on the same system the error occurred. (E.g. ECONNRESET is 104 on Linux, but 54 on MacOS X/Darwin).
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
567 [LDMud 3.5] Implementation minor N/A 2008-09-09 18:09 2008-09-10 17:45
Reporter: zesstra Platform:  
Assigned To: OS:  
Priority: low OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: sprintf() with fixed sized buffers should be avoided - use snprintf()
Description: Stuff like:
 char buff[80];
 sprintf(buff, "%ld", argp->u.number);
 if (buff[sizeof(buff)-1] != '\0')
   fatal();
from interpret.c should be avoided.

Instead something like
 char buff[80];
 if (snprintf(buff, 80, "%ld", argp->u.number) >= 80)
    errorf();
would be much safer (both for preventing crashes as well as buffer overflow exploits).

I admit, this is not the best example, as p_int in string representation will not exceed 79 characters for any near future, but take it as a matter of principle. ;-)
We should always use snprintf() instead of sprintf() for writing into buffers.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000780)
zesstra   
2008-09-10 17:45   
Quite similar: strcpy() -> strncpy()

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
395 [LDMud 3.3] Efuns feature N/A 2005-07-16 06:03 2008-09-09 05:30
Reporter: Sorcerer Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: acknowledged Product Version: 3.3  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: Raise privilege violation for set_this_player
Description: I would like to suggest to have efun::set_this_player() raise a privilege violation.
Since unrestricted access to this efun allows to easily bypass mudlib security it would be nice to have it "by default forbidden" instead of "by default allowed" as is the case in the current implementation which requires an explicit definition of a nomask simul_efun to disable/restrict the use.
Additionally I consider it a good idea to have the control over potentially dangerous efuns in one place - e.g. in the MASTER->privilege_violation().
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000655)
zesstra   
2008-07-02 05:17   
Actually, I like this, as it should not be too complicated.
(0000735)
zesstra   
2008-07-16 17:47   
(Last edited: 2008-07-16 18:17)
Does anyone think this is a bad idea? If not, I will have a look at it.

(0000763)
zesstra   
2008-09-07 10:04   
I had a look at this issue. While adding the privilege violation would be easy, it has one problem: the move hook in the master usually uses set_this_player() before calling the init()s. The lambda implementing the move hook is bound to the moved object or this_object(), which is most often a non-privileged object. If set_this_player() is disabled/restricted in simul_efun.c the lambda in the master can still use efun::set_this_player() (because the lambda is compiled by the master and not the object it is bound to) and circumvent the restriction.
Checking the privilege violation would then have to include the possibility to check which program (blueprint object) contained the call to set_this_player()...
Additionally, when I think of the potentially large number of calls to set_this_player() during moves into full environments, I don't know if it would be a good idea to add an additional master apply each time... What do you think?
(0000764)
Sorcerer   
2008-09-08 04:47   
While I really like the idea of having a privilege-violation for set_this_player(), I agree that especially functions concerned with moving objects around should be kept free of any unnecessary overhead.
So if there is no easy way to "label" efuns contained in code compiled by the master object as being privileged, probably it is better to keep this the "old way".
(0000765)
zesstra   
2008-09-08 08:02   
Mhmm. Don't know if it would be reasonable to check for something like current_lambda.u.lambda.prog_ob.name or current_prog->name in f_set_this_player() and only call privilege_violation() if that is not the master object... Seems to me a bit ugly though, because it is a deviation from the usual privilege checking. Mudlib programmers have to be careful who gets a reference to unbound lambdas compiled in the master, but that is no change to the current situation.
(0000766)
Gnomi   
2008-09-09 04:39   
Maybe we can design the privilege check similar to the "nomask simul_efun" privilege violations. These are raised by the compiler when a call to an efun is detected, where a nomask simul_efun of the same name exists. For set_this_player this could also be done, even if there is no nomask simul_efun. (Privilege checking at compile time and not runtime.) But nevertheless it would be quite unusual and the difference has to be made clear in the documentation.
(0000767)
zesstra   
2008-09-09 05:18   
Ok, that would be a better solution, especially in terms of runtime behaviour.
But I am not familiar enough with the LPC compiler for messing around with it right now and would like to leave that to you or Fuchur.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
475 [LDMud 3.3] Runtime minor always 2006-06-25 15:33 2008-08-05 08:02
Reporter: fufu Platform:  
Assigned To: fufu OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3.712  
Product Build: Resolution: not fixable  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: adding m_allocate-d mappings with += is different from adding with +
Description: Consider this code:

  mixed x = m_allocate(100,2); x += ([2:3;4;5]);
  mixed y = m_allocate(100,2); y = y + ([2:3;4;5]);

The first line results in an error, saying the mapping width doesn't match. The second line results in y containing mapping of width 3. As x is empty, the first line should work as well.
Tags:
Steps To Reproduce:
Additional Information: add_to_mapping() in mapping.c tests for empty mappings with
    0 == m2->num_entries && NULL == m2->hash
For m_allocate-d mappings, hash is empty but not 0.

Why is the hash tested at all? 3.2 doesn't have that check.

Attachment: patch to remove the NULL == m[1,2]->hash tests
Attached Files: empty-mapping-check-fix.patch (716 bytes) 2006-06-25 15:33
http://ldmud.eu/file_download.php?file_id=86&type=bug
Notes
(0000508)
Sorcerer   
2006-06-26 03:54   
While I agree that both code examples should be treated alike I would prefer in either case an error to be thrown:
if one really decides to use prior knowledge to avoid malloc overhead he should stick to the pre-set dimensions. Using m_allocate() instead of just initializing an empty mapping ([]) gives additional information which should be evaluated by the driver to avoid inconsistent use of variables.
(0000509)
fufu   
2006-06-26 04:27   
I think what you want is covered by issue 291. I agree in principle, but this would be a incompatible change and requires more work than fixing this bug.
(0000513)
Coogan   
2006-07-18 13:07   
This "mixed" behaviour also applies for 3.2.12 release, where I'd like to have it fixed, too.
I agree to Sorcerer: In case the first mapping was created either with m_allocate() or with ([:x]), the knowledge about the width of the mapping should be used consequently in any checks about different mapping widths. I doubt that it would break code, esp. as persons who pre-set a mapping dimension [should] _know_ what dimension they need later.
(0000753)
fufu   
2008-08-04 23:05   
I still stand by my previous analysis -- the ->hash check is meant to identify mappings allocated by m_alloc(), but it's unreliable:

- it does not catch mappings created with m_allocate(0, width), or ([:width]).
- if the mapping gets compacted, the hashed part will go away.

The proper fix for this is to implement 0000291.

In the meantime, I'd still like to remove those ->hash checks.
(0000754)
Gnomi   
2008-08-05 03:29   
I agree.
(0000755)
fufu   
2008-08-05 07:58   
On second thought, the checks are necessary. If the mapping is a protector mapping and it has a hashed part, then the hashed part might be non-empty, even though the mapping itself is empty. In that case simply changing the num_values field of the mapping will cause trouble later, when the mapping's 'deleted' entries are freed.

So I'll leave the code as is and close this bug.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
472 [LDMud 3.3] Implementation minor always 2006-06-05 12:29 2008-07-26 14:18
Reporter: fufu Platform:  
Assigned To: fufu OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: say(), tell_room(), printf() and tell_object() efuns truncate output on \0
Description: For example, printf("a\00morestuff") results in just a being sent. write() is fine -- the output is amorestuff. As far as I can see, the \0 is filtered because it's not in my telnet's character set.
Tags:
Steps To Reproduce:
Additional Information: In fact, printf() goes through tell_object() for printing stuff; the attached patch fixes tell_object(), tell_room() and say().
Attached Files: fmt_string.patch (558 bytes) 2008-07-09 12:50
http://ldmud.eu/file_download.php?file_id=139&type=bug
Notes
(0000691)
zesstra   
2008-07-08 18:13   
Mhmm, the patch seems to be OK for me.
(0000702)
Gnomi   
2008-07-09 10:28   
For me, too.
(0000706)
fufu   
2008-07-09 12:51   
This is trivial with the new patch for 0000471.
(0000752)
fufu   
2008-07-26 14:18   
fixed in commit 2396

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
471 [LDMud 3.3] Implementation feature always 2006-06-05 12:20 2008-07-26 14:17
Reporter: fufu Platform:  
Assigned To: fufu OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: use tell_object_str() function in e_say() and e_tell_room()
Description: (was: The tell_object_str() function in object.c (and object.h) is unused and can be removed.)
See Gnomi's comment below.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: use-tell_object.patch (3,955 bytes) 2008-07-09 12:43
http://ldmud.eu/file_download.php?file_id=138&type=bug
Notes
(0000687)
zesstra   
2008-07-08 17:06   
I agree. Does anybody object to remove the function?
(0000696)
Gnomi   
2008-07-09 02:55   
I vote for actually using this function.

e_say() and e_tell_room() do exactly the same thing as tell_object_str(), so if they would call tell_object_str instead we would have less double code.
(0000699)
zesstra   
2008-07-09 03:45   
Good point, that is even better. ;-) Removing duplicate code is always nice.
In this case, this is related to Fuchurs Bug 0000472.
(0000705)
fufu   
2008-07-09 12:44   
In fact, we can do both:
e_say and e_tell_room extract their string from a string_t, only to let tell_object_str create a new one if the target is an npc. It's better to use tell_object.
This makes tell_object_str superfluous again.
(see patch)
(0000719)
Gnomi   
2008-07-10 10:28   
Looks good.
(0000721)
zesstra   
2008-07-10 16:24   
Good idea. :)
(0000751)
fufu   
2008-07-26 14:17   
fixed in commit 2395

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
554 [LDMud 3.3] Portability minor N/A 2008-07-12 18:17 2008-07-18 15:30
Reporter: zesstra Platform: x86_64  
Assigned To: zesstra OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: port.h should use stdint.h, inttypes.h and stdbool.h if available
Description: stdint.h (required by C99) makes several interesting types available, among them intptr_t which is exactly what we need to p_int. If these headers are available on a system, port.h should use them and otherwise fall back to the current scheme for determining the correct types.
Additionally, port.h should define the system-dependent prefix for printing p_int (e.g. a long int needs 'l' as prefix: %ld), which is on some systems available from inttypes.h. This prefix can then be used in sprintf.c (s. 0000528)
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files: port.diff (19,476 bytes) 2008-07-14 18:23
http://ldmud.eu/file_download.php?file_id=145&type=bug
Notes
(0000726)
zesstra   
2008-07-13 14:17   
I worked a little on port.h and autoconf this weekend and prepared a little patch.

Changes to autoconf:
* removed check for values.h from configure.in and not used HAVE_VALUES from port.h - obsoleted by limits+float.h (was TODO)
* removed self-written check for ANSI-C89 compliant compiler and used AC_PROG_CC_STDC.
* removed self-written checks for uint32_t, ssize_t, size_t, off_t, long long and added the corresponding autoconf macros
* removed obsolete AC_HEADER_STDC
* added checks for C99 datatypes: (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t, (u)inptr_t, (u)intmax_t.
* added size checks for intptr_t, intmax_t, long long
* added some checks for compiler charactestics: stringenize operator in preprocessor, typeof. (check for restrict due to problems with mk_func.c still disabled)
* added header check for stdbool.h
* changed obsolete AC_CONFIG_HEADER to AC_CONFIG_HEADERS

Changes to port.h
* fixed PHINT_MIN, PHINT_MAX and PHUINT_MAX in port.h. If SIZEOF_CHAR_P == 4 they were defined to SHORT_MAX, SHORT_MIN, USHORT_MAX, which should be SHRT_MIN, SHRT_MAX, USHRT_MAX.
* fixed selection of ph_int (short is not guaranteed to be 2 bytes)
* use inttypes.h and stdint.h if available.
* use stdbool.h and _Bool for our own Bool if available.
* removed own typedef for ssize_t as autoconf will provide is with a suitable ssize_t if the standard headers don't have one, which is anyway very unlikely.
* added PRI_PINT_PREFIX containing a length prefix used in sprintf.c for calling the system sprintf() and MAX_PRI_PINT_PREFIX_LENGTH for buffer allocation in sprintf.c

After the changes I found some inconsistent declarations (int/Bool), which I changed in SVN yesterday.
(0000727)
zesstra   
2008-07-14 18:23   
Tests on glibc based ILP32 platforms showed a problem with the patch from yesterday:
warning: format '%ld' expects type 'long int', but argument 3 has type 'p_i
nt'
The problem is, that on these systems intptr_t is typedef'ed to int instead of long, but the format specifier ist hard-coded. This version of the patch includes a hack which avoids to use intptr_t on systems where sizeof(int)==sizeof(char*) so that we don't use a intptr_t which may be typedef'ed to int. This hack has to be removed once bug 0000556 is resolved.

Additionally this introduces defines to the correct format specifiers for sprintf() & Co for p_(u)int, ph_(u)int and mp_(u)int which will be needed for resolving 0000556. (There might still some format specifiers missing.)
(0000747)
zesstra   
2008-07-17 15:04   
Are there some more issues with the current version? (On platforms I have available, there are right now no problems, Im aware of.) I would like to use the printing format specifiers, the question is, if these changes are acceptable for now... If not, I would add only the the format specifiers to the current port.h for the time being.
(0000749)
zesstra   
2008-07-18 15:30   
I applied the latest patch and additionally the corresponding defines for the sscanf() format specifiers (which happen to be identical right now). This closes this for now.
Once we got rid of all the hard-coded sprintf("%ld",(m)p_int) we should remove the hack which prevents intptr_t being used on systems where sizeof(int)==sizeof(char*).
And at some point in the future we should decide if we start to require a C99 compliant build environment and get rid of quite a lot checks in port.h (e.g. in 3.5).

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
248 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-26 23:58 2008-07-18 13:10
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Safe recompile of objects
Description: hort: Safe recompile of objects
From: Lars Duening <lars@bearnip.com>
Date: Sat, 26 May 2001 01:26:13 -0600
Type: Feature
State: New

Acius wrote on Sunday, May 20 2001, 00:46:08:

>I hope that my explanation was not too garbled, it's late. And While
>we're talking about adding efun's, how about an update_object(string
>path) efun that:
>* Compiles the .c file at "path"
>* If path has an error, report the error and *do nothing to the existing
>object associated with that path*.
>* If path does not have an error, destruct the existing blueprint object
> for path and then load in the new one.

You can have the efun take a parameter: recompile-and-load, or just recompile
to check the syntax.

Be careful with inherits, though.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000744)
zesstra   
2008-07-17 07:09   
I'm am interested in such a feature, although I don't know yet, what has to be changed (load_object() probably, we don't want to duplicate all that code in it) for making something like this work.
Alternatively, an efun implementing an LPC syntax check might be possible, although it is not the same and compiling a program just for testing it and compiling it again shortly after this can be quite a waste of time.
(0000748)
bubbs   
2008-07-18 13:10   
You can simulate this in the mudlib, using rename_object() in the master destruct applies. At least you could with 3.2.

Nonetheless, it would be useful to do this without such hacks; our mudlib only used it for simul_efun protection.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
468 [LDMud 3.3] Compilation, Installation minor always 2006-05-19 15:55 2008-07-16 15:57
Reporter: lynx Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: MAX_OUTCONN is not good for deployment
Description: MAX_OUTCONN needs to be configurable in setting
files, because when users log into psyced, we
often need to connect N jabber and psyc servers
at once. we are currently using a MAX_OUTCONN
of 30, not 5, and we may need to raise it more.
we cannot ask end users to patch the comm.c file,
so please integrate it into the setting mechanism.
what about the name "with_max_connects_outgoing".
Tags:
Steps To Reproduce:
Additional Information: here's a possible comment line for setting files:

# Maximum number of contemporary asynchronous connect() attempts
with_max_connects_outgoing=30
Attached Files: max_outconn.diff (2,375 bytes) 2008-07-08 11:44
http://ldmud.eu/file_download.php?file_id=135&type=bug
Notes
(0000534)
lynx   
2007-05-04 13:02   
I added this stuff to configure.in

AC_INT_VAL_FROM_WITH(max_net_connects)
AC_SUBST(val_max_net_connects)
AC_MY_ARG_WITH(max_net_connects,20,,)

and

/* maximum number of currently outgoing connections which are
 * not yet fully established
 * psyced needs a quite large value here
 */
#define MAX_OUTCONN @val_max_net_connects@

to config.h.in

that's it.
(0000675)
zesstra   
2008-07-08 11:48   
This is actually a TODO in comm.c. I prepared a small patch (See max_outconn.diff).
Do you think, we should enforce a MAX_OUTCONN > 0 in comm.c by some precompiler check? Values <0 should lead to compilation errors and my guess is, that it should be possible to run a driver with net_connect() disabled...
(0000730)
zesstra   
2008-07-16 15:57   
Applied patch without enforcing MAX_OUTCONN > 0 in r2388.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
556 [LDMud 3.3] Portability minor N/A 2008-07-14 16:13 2008-07-14 18:57
Reporter: zesstra Platform: x86_64  
Assigned To: OS: MacOS X  
Priority: low OS Version: 10.5.x  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: major rework      
ETA: > 1 month Fixed in Version:  
    Target Version:  
Summary: Change code which assumes that p_int and mp_int are always a long.
Description: Currently the driver contains a lot of code like sprintf("%ld",p_int) which assumes, that p_int is always a long.
This surfaced in testing the proposed changes from 0000554. On some systems intptr_t is typdef'ed to an int instead of long (glibc on ILP32 platforms).
According to gcc warnings there are 425 of such issues in the driver code (see attached log).
For the sake of portability, printf() should only be used directly with hard-coded format specifiers if the type of its argument is guarenteed (e.g. %ld and long), but not if the type is typedef'ed/aliased to in a system-dependent manner (e.g. p_int).
Right now it seems not to be an immediate problem, as on most platforms in use for the driver a long apparantly has the needed length for p_int, therefore setting this to a low priority. (On systems with sizeof(int)==sizeof(char*) && sizeof(long) > sizeof(int) the driver will crash in its current state.)
The problem can be solved by using a #define from port.h as format specifier (like the ones from inttypes.h, e.g. PRIdPTR) for our own typedef'ed types, e.g. PRI_PINT_PREFIX.

Do you have any opinions about how we should handle this? It seems pretty much obvious, that we can't easily change this immediately but it will take time. Or should we ignore it pretty much because working on this has a bad 'return of investment'?
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files: p_int-type-warnings.log (40,684 bytes) 2008-07-14 16:14
http://ldmud.eu/file_download.php?file_id=144&type=bug
mp_int-type-warning.log (6,007 bytes) 2008-07-14 18:57
http://ldmud.eu/file_download.php?file_id=146&type=bug
Notes
(0000728)
zesstra   
2008-07-14 18:53   
Additionally there cases like these:
efuns.c:8038: warning: format '%6ld' expects type 'long int', but argument 3 has type 'mp_int'

Here the driver expects that mp_int is always a long. In the given case above mp_int is of type long long, because I experimentally used intmax_t for mp_int. Right now, this is mostly prevented in port.h by specifically using the same type as p_int (which is nearly always long, see description).
Unfortunately this prevents us from using the intmax_t for mp_int which is nowadays available on most systems.
The first priority should be on fixing these hard-coded specifiers for mp_ints, so that we may use long longs (e.g. for the statistics counters). A log of compiler warnings (60) will be attached.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
543 [LDMud 3.3] Efuns feature always 2008-07-01 03:10 2008-07-10 04:00
Reporter: Gnomi Platform: i686  
Assigned To: Gnomi OS: Debian GNU/Linux  
Priority: normal OS Version: 4.0  
Status: resolved Product Version: 3.3.716  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: Mudlib controlled sqlite pragmas
Description: This is a patch that calls master->privilege_violation for each sqlite pragma, so that the mudlib can decide whether to allow or disallow. The current behavior is to allow 'pragma synchronous' and disallow all other. (This is a TODO item in pkg-sqlite.c.)

In UNItopia we used this patch for a year. The only drawback I can see is that it makes secure_apply_error visible to all the other files, but I wanted to avoid duplicate code and I do need such a function for error handling.
Tags:
Steps To Reproduce:
Additional Information:
System Description
Attached Files: sqlite_pragma.diff (5,184 bytes) 2008-07-01 03:10
http://ldmud.eu/file_download.php?file_id=130&type=bug
Notes
(0000688)
zesstra   
2008-07-08 17:45   
Seems to me OK as well. Did you know if secure_apply_error() was actually inlined until now or did you recognize any impact? But anyway I guess, it would be neglectable.
I think, the thing missing is the documentation (doc/master/privilege_violation). ;-)
(0000703)
Gnomi   
2008-07-09 10:39   
I doesn't look like it was inlined before. But errors in master applies should be rare, so it doesn't matter much.

Oh, documentation, right. I'll try. :-)
(0000712)
Gnomi   
2008-07-10 04:00   
Committed as r2378.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
470 [LDMud 3.3] Compilation, Installation trivial always 2006-06-05 12:17 2008-07-09 10:11
Reporter: fufu Platform:  
Assigned To: fufu OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.3.717  
    Target Version:  
Summary: make install prints duplicate messages at end
Description: to reproduce

$ make install
[...]
echo "To install header files, use 'make install-headers'."
To install header files, use 'make install-headers'.
echo "To install utility programs (incl. erq), use 'make install-utils'."
To install utility programs (incl. erq), use 'make install-utils'.
echo "To install everything in one go, use 'make install-all'."
To install everything in one go, use 'make install-all'.
$
Tags:
Steps To Reproduce:
Additional Information: patch attached
Attached Files: clean_makefile.diff (749 bytes) 2006-06-05 12:17
http://ldmud.eu/file_download.php?file_id=84&type=bug
Notes
(0000700)
fufu   
2008-07-09 09:09   
fixed in SVN 2376

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
549 [LDMud] Compilation, Installation major always 2008-07-08 13:44 2008-07-08 16:17
Reporter: zortek Platform:  
Assigned To: zesstra OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: no change required  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: mregex.c compilation failure since updating to
Description: mregex.c: In function ârx_execâ:
mregex.c:704: error: stray â@â in program
mregex.c:704: error: stray â@â in program
mregex.c:704: error: âval_pcre_recursion_limitâ undeclared (first use in this function)
mregex.c:704: error: (Each undeclared identifier is reported only once
mregex.c:704: error: for each function it appears in.)
mregex.c: In function rx_exec_str:
mregex.c:777: error: stray @ in program
mregex.c:777: error: stray @ in program
mregex.c:777: error: val_pcre_recursion_limit undeclared (first use in this function)
make: *** [mregex.o] Error 1
Tags:
Steps To Reproduce:
Additional Information: mregex.c
698 #ifdef LD_PCRE_RECURSION_LIMIT
699 #ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
700 pHints->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
701 pHints->match_limit_recursion = LD_PCRE_RECURSION_LIMIT;
702 #else
703 pHints->flags |= PCRE_EXTRA_MATCH_LIMIT;
704 pHints->match_limit = LD_PCRE_RECURSION_LIMIT;
705 #endif /* PCRE_EXTRA_MATCH_LIMIT_RECURSION */
706 #else /* LD_PCRE_RECURSION_LIMIT */
707 #ifdef PCRE_EXTRA_MATCH_LIMIT_RECURSION
708 pHints->flags &= ~PCRE_EXTRA_MATCH_LIMIT_RECURSION
709 #else
710 pHints->flags &= ~PCRE_EXTRA_MATCH_LIMIT;
711 #endif /* PCRE_EXTRA_MATCH_LIMIT_RECURSION */
712 #endif /* LD_PCRE_RECURSION_LIMIT */
config.h
437 /* Limit the amount of recursion in the PCRE code. Setting it to low will
438 * prevent certain regexps to be executed properly, setting it too high can
439 * cause that regexps to crash the driver. Set it according to the
440 * available maximum stack size for the driver process. (Rule of thumb:
441 * The memory used for a recursion on the stack seems to be within 466 and
442 * 1008 bytes. If you have 8M of stack size, reserve half of it for LPC
443 * recursions and choose about 3000 - 4000.) In doubt, increase the stack
444 * size limit for the driver process with ulimit & Co.)
445 * Defaults to 3000
446 */
447 #define LD_PCRE_RECURSION_LIMIT @val_pcre_recursion_limit@
Attached Files:
Notes
(0000676)
zortek   
2008-07-08 13:52   
config.h isn't having the default 3000 plugged in from config.h.in, I'm checking to see if it was my fat-finger mistake on configure.
(0000677)
zesstra   
2008-07-08 15:44   
This is caused by an outdated 'configure'. This file is auto-generated from autoconf/configure.in. We decided to update the configure in the svn repository only for releases, because we don't want to clutter the code changes with a bunch of automatically generated autoconf stuff.
Please run 'autoconf autoconf/configure.in > configure' in your src/ directory. That will give you an up-to-date configure. Then re-run configure with your desired settings and re-compile.
Does that solve your problem?
(0000679)
zortek   
2008-07-08 16:13   
Resolved. Thanks.
(0000680)
zesstra   
2008-07-08 16:17   
Great. :-)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
547 [LDMud 3.3] Portability crash always 2008-07-02 15:42 2008-07-02 17:35
Reporter: zesstra Platform: x86_64  
Assigned To: OS: MacOS X  
Priority: normal OS Version: 10.5.x  
Status: resolved Product Version: 3.3.716  
Product Build: r2370 Resolution: no change required  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: possible crash upon (first) memory allocation (x86_64)
Description: A binary compiled for x86_64 on MacOS 10.5.3 crashes while allocating the first chunk of memory with
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000001008c6104

Stacktrace:
(gdb) bt full
#0 0x0000000100115150 in add_large_free (ptr=0x100846004, block_size=65568) at slaballoc.c:3031
No locals.
0000001 0x00000001001155a3 in large_malloc (size=2960, force_more=0) at slaballoc.c:3289
    chunk_size = 262272
    block_size = 65568
    extra = 0
    real_size = 8
    ptr = (word_t *) 0x100846004
    orig_size = 11828
0000002 0x0000000100112ca1 in mem_alloc (size=64) at slaballoc.c:1717
    numObjects = 184
    slabSize = 11828
    slab = (mslab_t *) 0x0
    block = (word_t *) 0x0
    ix = 7
0000003 0x00000001001172ce in xalloc_traced (size=56, malloc_trace_file=0x1001281eb "main.c", malloc_trace_line=404) at xalloc.c:540
    p = (word_t *) 0x10012a7aa
0000004 0x00000001000905f0 in main (argc=2, argv=0x7fff5fbff858) at main.c:404
    buf = "__DEBUG_LOG__=\"/phoenix.debug.log\"", '\0' <repeats 261 times>
    name = 0x7fff5fbff3f0 "phoenix.debug.log\""
    tmp = (struct lpc_predef_s *) 0x0
    i = 246
    p = 0x7fff5fbff7f4 "\366"
    set = 8192
    rc = 0

add_large_free() tries to join neighbouring free blocks and the first thing is:
    /* If the next block is free, coagulate */
    if (!(*(ptr+block_size) & THIS_BLOCK))
    {
        remove_from_free_list(ptr+block_size);
        block_size += (ptr+block_size)[M_LSIZE];
    }

(gdb) print ptr+block_size
$2 = (word_t *) 0x1008c6104
(gdb) print *(ptr+block_size)
Cannot access memory at address 0x1008c6104

There is no memory mapped at 0x1008c6104 (see below the relevant part of the process address space) as the allocated block is the first allocated block.
MALLOC_LARGE 0000000100846000-0000000100847000 [ 4K] rw-/rwx SM=COW
MALLOC_LARGE 0000000100847000-0000000100887000 [ 256K] rw-/rwx SM=ZER
MALLOC_TINY 0000000100900000-0000000100901000 [ 4K] rw-/rwx SM=COW
Tags:
Steps To Reproduce:
Additional Information:
System Description Homemud / Entwicklungssystem (64 bit)
Attached Files:
Notes
(0000664)
zesstra   
2008-07-02 17:35   
Ok, after some discussion with Gnomi and searching through stuff, the problem is caused by wrong values for SIZEOF_CHAR_P and SIZEOF_LONG in machine.h and therefore some configure problem. Was then solved by the right target and host options for configure... (Why did that work a few weeks ago with the old configure script...?)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
399 [LDMud 3.3] Compilation, Installation minor always 2005-08-29 07:32 2007-10-07 18:44
Reporter: boggle Platform:  
Assigned To: lars OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.3  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: erq doenst compile
Description: erq doenst compile.

mac os x 10.4.2.

gcc-3.3.

psycmuve-cvs, ldmud-3.3-709.

similar problems with ldmud-3.3-705 and gcc-4.0.
Tags:
Steps To Reproduce:
Additional Information: after fixining #include <malloc.h> to #include <memory.h>

gcc-3.3 -I/usr/local/mysql/include -O2 -g -fstrength-reduce -fno-force-mem -fno-force-addr -DMUD_LIB='"/Volumes/Data/PsycMUVE/world"' -DBINDIR='"/Volumes/Data/PsycMUVE/bin"' -DERQ_DIR='"/Volumes/Data/PsycMUVE/run"' -I/Volumes/Data/Sources/psycMUVE-cvs-05-04-15/3-3/src erq.c -o erq -lm -lresolv
In file included from erq.c:109:
srv.c:22: error: parse error before "HEADER"
srv.c:22: warning: no semicolon at end of struct or union
srv.c:24: error: parse error before '}' token
srv.c:24: warning: data definition has no type or storage class
srv.c: In function `getsrv':
srv.c:72: error: parse error before "answer"
srv.c:76: error: `HEADER' undeclared (first use in this function)
srv.c:76: error: (Each undeclared identifier is reported only once
srv.c:76: error: for each function it appears in.)
srv.c:76: error: `hp' undeclared (first use in this function)
srv.c:111: error: `C_IN' undeclared (first use in this function)
srv.c:111: error: `answer' undeclared (first use in this function)
srv.c:121: error: parse error before ')' token
srv.c:133: error: `QFIXEDSZ' undeclared (first use in this function)
erq.c: At top level:
erq.c:269: error: conflicting types for `buf'
srv.c:23: error: previous declaration of `buf'
erq.c: In function `start_subserver':
erq.c:869: error: `ERQ_MAX_REPLY' undeclared (first use in this function)
erq.c: In function `main':
erq.c:1819: error: `ERQ_MAX_REPLY' undeclared (first use in this function)
Attached Files:
Notes
(0000386)
boggle   
2005-08-29 07:40   
solved the issue myself, three changes, all to srv.c

1. as already mentioned: #include <memory.h> instead of malloc.h
2. #include <arpa/nameser_compat.h> instead of #include <arpa/nameser.h>
3. #include "../../config.h"

does the trick on a mac.
(0000387)
tobij   
2005-08-29 07:53   
this only concerns a psycmuve erq-enhancement.

but boggles hints seem to solve the problems which prevented the srv-addons from going into the distribution, so probably ...
(0000389)
lynx   
2005-09-08 04:23   
thanx boggle.. great news to have this fixed
(0000390)
echox   
2005-09-27 13:48   
Sorry guys, but this doesn't work for me.

Mac OS X 10.4.2
powerpc-apple-darwin8-gcc-4.0.0 (GCC) 4.0.0 20041026 (Apple Computer, Inc. build 4061)
psycMUVE-cvs-05-09-23

First tried to compile the gamma release but got the errors descriped here.
Then added the fix from boggle but I get still this:

[stuff]
Making erq.
gcc -O2 -g -fstrength-reduce -fno-force-mem -fno-force-addr -DMUD_LIB='"/Users/echox/psycmuve/world"' -DBINDIR='"/Users/echox/psycmuve/bin"' -DERQ_DIR='"/Users/echox/psycmuve/run"' -I/Users/echox/src/psyc/psycMUVE-cvs-05-09-23/3-3/src erq.c -o erq -lm -lresolv
In file included from erq.c:109:
srv.c:29: error: parse error before "HEADER"
srv.c:29: warning: no semicolon at end of struct or union
srv.c:31: error: parse error before '}' token
srv.c:31: warning: data definition has no type or storage class
srv.c: In function 'getsrv':
srv.c:79: error: parse error before "answer"
srv.c:83: error: 'HEADER' undeclared (first use in this function)
srv.c:83: error: (Each undeclared identifier is reported only once
srv.c:83: error: for each function it appears in.)
srv.c:83: error: 'hp' undeclared (first use in this function)
srv.c:118: error: 'C_IN' undeclared (first use in this function)
srv.c:118: error: 'answer' undeclared (first use in this function)
srv.c:128: error: parse error before ')' token
srv.c:140: error: 'QFIXEDSZ' undeclared (first use in this function)
erq.c: At top level:
erq.c:269: error: conflicting types for 'buf'
srv.c:30: error: previous declaration of 'buf' was here
erq.c: In function 'main':
erq.c:1819: warning: pointer targets in passing argument 6 of 'recvfrom' differ in signedness
erq.c:2541: warning: pointer targets in passing argument 3 of 'accept' differ in signedness
make[2]: *** [erq] Error 1
make[1]: *** [subs] Error 2
make: *** [utils] Error 2
cp: 3-3/src/util/erq/erq: No such file or directory
[/stuff]
(0000537)
lynx   
2007-05-04 17:40   
Recent Mac OS X seems to have solved this issue.
ERQ with SRV support compiles without problems.
(0000562)
lars   
2007-10-07 18:44   
Apparently the problem vanished by itself.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
58 [LDMud 3.3] Runtime crash unable to reproduce 2004-05-11 08:07 2007-10-07 00:22
Reporter: lars Platform:  
Assigned To: lars OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: unable to reproduce  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: 3.3.538 crashes on illegal array references.
Description: Evermore (040510) crashed on an 'array += array' operation.

The array in question is a reference to an array stored in a mapping (rules["default"][0]["north"][0]), and all its three entries are supposed to be array references, but point into random memory. It looks like the referenced arrays were freed prematurely, but there is no corresponding entry in the GC log.

Previous drivers were 3.3.535 and 3.3.537, and the problem did not occur.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: lpmud.log.538 (14,051 bytes) 2004-05-11 08:07
http://ldmud.eu/file_download.php?file_id=2&type=bug
Notes
(0000558)
lars   
2007-10-07 00:22   
An old issue and it involves memory management - at this point of time, unless it is still happening, there aren't many things to look into.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
491 [LDMud 3.2] LPC Compiler/Preprocessor crash always 2006-11-12 22:45 2007-10-06 21:30
Reporter: zippo Platform:  
Assigned To: lars OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.13  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version: 3.2.16  
    Target Version:  
Summary: x86_64 crasher before it's done loading
Description: This is for 3.2.14.

% gdb --core=core.1 ~/bin/ldmud-3_2_14_EOTL_0
Using host libthread_db library "/lib/libthread_db.so.1".

warning: core file may not match specified executable file.
Core was generated by `/home/mud/bin/ldmud-3_2_14_EOTL_0 --debug-file ../Debug.log.p --gcollect-outfd'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libnsl.so.1...done.
Loaded symbols for /lib/libnsl.so.1
Reading symbols from /lib/libm.so.6...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libcrypt.so.1...done.
Loaded symbols for /lib/libcrypt.so.1
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux-x86-64.so.2...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Reading symbols from /lib/libnss_files.so.2...done.
Loaded symbols for /lib/libnss_files.so.2
#0 0x000000000048aa86 in read_long (offset=140733193388032) at prolang.y:1403
1403 GET_LONG(l, dest);
(gdb) bt
#0 0x000000000048aa86 in read_long (offset=140733193388032) at prolang.y:1403
0000001 0x0000000000493399 in yyparse () at prolang.y:4930
0000002 0x000000000049074e in compile_file (fd=7) at prolang.y:12804
0000003 0x00000000004a76c5 in load_object (lname=0x6fa0e0 "secure/simul_efun/simul_efun", create_super=0, depth=0,
    chain=0x0) at simulate.c:1876
0000004 0x00000000004a8243 in lookfor_object (str=0x9a3c6d0 "/secure/simul_efun/simul_efun", bLoad=1) at simulate.c:2289
0000005 0x0000000000454053 in eval_instruction (
    first_instruction=0xbe237f "\a9\a:\205\002\002\001d\001&Y4\a;ô\a<\034\001(\a7(ô\035", initial_sp=0x601ee0)
    at interpret.c:15732
0000006 0x00000000004a54b6 in catch_instruction (flags=0, offset=8, i_sp=0x73dc70,
    i_pc=0xbe237f "\a9\a:\205\002\002\001d\001&Y4\a;ô\a<\034\001(\a7(ô\035", i_fp=0x601ed0) at simulate.c:478
0000007 0x0000000000441b4f in eval_instruction (first_instruction=0xbe2373 "S", initial_sp=0x601ee0) at interpret.c:7908
0000008 0x000000000045f64c in apply_low (fun=0xa233c0 "get_simul_efun", ob=0xbaf5a0, num_arg=0, b_ign_prot=1)
    at interpret.c:21684
0000009 0x000000000045f89f in sapply_int (fun=0xa233c0 "get_simul_efun", ob=0xbaf5a0, num_arg=0, b_find_static=1)
    at interpret.c:21796
0000010 0x000000000045fe9f in apply_master_ob (fun=0xa233c0 "get_simul_efun", num_arg=0, external=0) at interpret.c:22084
0000011 0x00000000004aedd1 in get_simul_efun_object (require=1) at simul_efun.c:200
0000012 0x0000000000472194 in main (argc=5, argv=0x7fff16c736d8) at main.c:506
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000520)
zippo   
2006-11-13 18:15   
/* Function : strfage **
** Arguments : string fmt is the format string as described in **
** documentation, time is a integer representing how many **
** seconds. **
** Description: string_time() meets strftime(). **
** Returns : Return a string based on a time value given. If no **
** string is found, 0 is returned. */
string
strfage(string fmt, int t)
{
  int days, hours, minutes, seconds, i, j, k;
  string out;
  if( !stringp(fmt) )
  {
    raise_error("Bad argument 1 to strfage.\n");
    return 0;
  }
  out = "";
  days = t / ( 60 * 60 * 24 );
  t %= ( 60 * 60 * 24 );
  hours = t / ( 60 * 60 );
  t %= ( 60 * 60 );
  minutes = t / 60;
  seconds = t % 60;
  for(i=0,j=strlen(fmt);i<j;i++)
  {
    if( fmt[i] != '%' )
    {
      out += sprintf("%c", fmt[i]);
      continue;
    }
    switch( fmt[i+1] )
    {
      case '%' : out += "%";
                 break;
      case 'D' : if( fmt[i+2] != '[' )
                 {
                   if(days==1) out += " day ";
                   else if(days>1) out += " days ";
                 }
                 else
                 {
                   k = strstr(fmt, "]", i);
                   if(k==-1) raise_error("ERROR strfage(): Error in "
                     "format string.\n");
                   else if(days) out += fmt[i+3..k-1];
                   i = k-1;
                 }
                 break;
      case 'd' : if(days) out += to_string(days);
                 break;
      case 'H' : if( fmt[i+2] != '[' )
                 {
                   if(hours==1) out += " hour ";
                   else if(hours>1) out += " hours ";
                 }
                 else
                 {
                   k = strstr(fmt, "]", i);
                   if(k==-1) raise_error("ERROR strfage(): Error in "
                     "format string.\n");
                   else if(hours) out += fmt[i+3..k-1];
                   i = k-1;
                 }
                 break;
      case 'h' : if(hours) out += to_string(hours);
                 break;
      case 'M' : if( fmt[i+2] != '[' )
                 {
                   if(minutes==1) out += " minute ";
                   else if(minutes>1) out += " minutes ";
                 }
                 else
                 {
                   k = strstr(fmt, "]", i);
                   if(k==-1) raise_error("ERROR strfage(): Error in "
                     "format string.\n");
                   else if(minutes) out += fmt[i+3..k-1];
                   i = k-1;
                 }
                 break;
      case 'm' : if(minutes) out += to_string(minutes);
                 break;
      case 'S' : if( fmt[i+2] != '[' )
                 {
                   if(seconds==1) out += " second";
                   else if(seconds>1) out += " seconds";
                 }
                 else
                 {
                   k = strstr(fmt, "]", i);
                   if(k==-1) raise_error("ERROR strfage(): Error in "
                     "format string.\n");
                   else if(seconds) out += fmt[i+3..k-1];
                   i = k-1;
                 }
                 break;
      case 's' : if(seconds) out += to_string(seconds);
                 break;
      default : raise_error("Incorrect type " + sprintf("%c", fmt[i]) +
                  " to strfage.\n");
                return 0;
                break;
    }
    i++;
  }
  return out;
}
(0000521)
zippo   
2006-11-13 18:16   
It barfs at the end of this function. Still digging...
(0000522)
zippo   
2006-11-13 18:39   
upd_long() and read_long() both say, in the comments, that they are dealing with 4-byte numbers, but SIZEOF_LONG on my platform is 8.
(0000523)
zippo   
2006-11-13 18:42   
Indeed, this fixed it for me:

Index: prolang.y
===================================================================
RCS file: /home/mud/cvsroot/driver/src/prolang.y,v
retrieving revision 1.1.1.16
diff -u -r1.1.1.16 prolang.y
--- prolang.y 24 Aug 2005 15:46:06 -0000 1.1.1.16
+++ prolang.y 13 Nov 2006 23:39:49 -0000
@@ -1375,7 +1375,7 @@

 /*-------------------------------------------------------------------------*/
 static void
-upd_long (mp_uint offset, long l)
+upd_long (mp_uint offset, int l)

 /* Store the 4-byte number <l> at <offset> in the A_PROGRAM are in
  * a fixed byteorder.
@@ -1389,7 +1389,7 @@
 } /* upd_long() */

 /*-------------------------------------------------------------------------*/
-static long
+static int
 read_long (mp_uint offset)

 /* Return the 4-byte number stored at <offset> in the A_PROGRAM area.
(0000552)
lars   
2007-10-06 21:30   
Actually, the type int32 was introduced for that purpose. Ironically, the method ins_long() already used the right type.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
480 [LDMud 3.2] Compilation, Installation minor always 2006-07-19 18:45 2007-10-06 20:58
Reporter: Coogan Platform:  
Assigned To: lars OS:  
Priority: normal OS Version:  
Status: resolved Product Version: 3.2.13  
Product Build: Resolution: unable to reproduce  
Projection: none      
ETA: none Fixed in Version: 3.2.16  
    Target Version:  
Summary: OPTIMIZE var is not properly created
Description: After configure, the Makefile contains that line:
OPTIMIZE= $(med_OPTIMIZE)

The correct line would be:
OPTIMIZE= $(MED_OPTIMIZE)

That the driver build that way will look different from the expected driver, is obvious. The bug didn't happen in 3.2.12-dev.724.
Tags:
Steps To Reproduce:
Additional Information: This affects version 3.2.14 (!), but it's not possible to select this version from the drop-down-menue.
Attached Files:
Notes
(0000550)
lars   
2007-10-06 20:58   
I can't reproduce the problem.

Looking at the configure script, the variable used to create the Makefile (val_optimize) is made all-uppercase.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
481 [LDMud 3.2] Other minor always 2006-07-19 18:47 2007-10-06 20:52
Reporter: Coogan Platform:  
Assigned To: lars OS:  
Priority: normal OS Version:  
Status: resolved Product Version:  
Product Build: Resolution: fixed  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: latest release in 3.2 is not selectable in mantis
Description: When reporting a bug for 3.2.14 it became obvious, that the latest release 3.2.14 is not availabe in the drop-down menue 'Product Version' yet.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000549)
lars   
2007-10-06 20:52   
Added the recent versions.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
428 [LDMud 3.3] Efuns feature N/A 2005-12-23 04:11 2007-05-04 17:15
Reporter: hkremss Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: more detailed return codes for filesys efuns
Description: Last week one of our wizards had problems with a wizard tool. The tool could not create a file somewhere in his home. The default error message was something like 'Could not write file for some reason, maybe missing access rights.', the only message the tool creates, if write_file(E) fails. He was not able to find the reason and noone else was online to help. The reason for this message is (from write_file(E) manpage) 'Returns 0 for failure and 1 for success.' The same thing for rm(E), mkdir(E), rmdir(E), rename(E), copy_file(E). Only file_size(E) has two different error return codes. I think it would be great to have either more detailed return codes for all file system efuns or a last_error() efun to get more detailed information.
This is a feature request.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000536)
lynx   
2007-05-04 17:15   
I once added an f_errno efun which simply returned C's errno.
Dirty, but useful. I don't have it at hand, but it was trivial and not elegant.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
445 [LDMud] Efuns feature N/A 2006-02-28 18:53 2006-03-04 22:59
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: New input_to() flags: amount of data
Description: Add flags to input_to() to direct the driver to return 'x' number of bytes from the socket, or all there is. Kind of a 'binary input_to()'.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000491)
lars   
2006-03-04 22:59   
Phillipp also wishes this: kannst Du
dann gleich das Framework für "schieb alles an nen C-Level XML-Parser"
mitschreiben? Den ganzen Rest den man dann für XML-Sockets (hey..
vielleicht will ja nen Mud nen Flash-Client schreiben um trendiger zu
sein :-) noch braucht, hab ich fast fertig.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
461 [LDMud] Efuns feature N/A 2006-03-01 15:34 2006-03-01 15:34
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: regexp() and sscanf() aren't binary string proof.
Description: ;; TODO: The regexp() functions and sscanf() should be able to handle '\0' as
;; TODO:: data byte, not as terminator.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
460 [LDMud] Networking feature N/A 2006-03-01 15:33 2006-03-01 15:33
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Determine which objects have ERQ callbacks pending
Description: That's it.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
459 [LDMud] Networking feature N/A 2006-03-01 15:32 2006-03-01 15:32
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Notify the ERQ about destructed objects
Description: ;; TODO: When the callback object for an ERQ callback is destructed, the
;; TODO:: driver should inform the ERQ. This way, the ERQ can for example
;; TODO:: close an existing TCP connection.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
457 [LDMud] Efuns feature N/A 2006-03-01 15:28 2006-03-01 15:28
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: General efuns for color-keyed strings
Description: Like cstrlen() etc. Maybe have a dedicated internatl string type for it?
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
453 [LDMud] LPC Compiler/Preprocessor feature N/A 2006-03-01 15:23 2006-03-01 15:23
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Omit argument names in prototypes, and for unused parameters
Description: ;; TODO: Prototypes with unnamed arguments (currently the arg names are required).
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
452 [LDMud] Efuns feature always 2006-03-01 15:22 2006-03-01 15:22
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: replace() efun like in Pike
Description: ;; TODO: Like Pike: replace() http://pike.ida.liu.se/generated/manual/ref/chapter_17.html
;; TODO:: See Zonk's "Wunschzettel"
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
451 [LDMud] Efuns feature N/A 2006-03-01 15:21 2006-03-01 15:21
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: ed() should be able to replace CRs by LFs.
Description: ;; TODO: Modify ed() 'M' command to replace all CRs by LFs. Slightly
;; TODO:: complex as it requires breaking up the lines.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
450 [LDMud] Efuns feature N/A 2006-03-01 15:21 2006-03-01 15:21
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: set_wizlist_score() to implement the WIZLIST reading from the mudlib.
Description: ;; TODO: set_wizlist_score() to manually add name:score pairs to the wizlist,
;; TODO:: to be used to read the WIZLIST file from the mudlib.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
448 [LDMud] Implementation feature N/A 2006-03-01 15:18 2006-03-01 15:18
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Closure callbacks should throw an error on destructed objects
Description: ;; TODO: Closure-Callbacks (like in call_out()s) should throw an error
;; TODO:: when set up with an destructed current object (or no object for
;; TODO:: unbound_lambdas). This requires symbolic return values from
;; TODO:: all the setup_callback functions, as the positive values already
;; TODO:: signal errors in the arguments.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
366 [LDMud] Efuns feature always 2005-02-20 12:49 2005-02-20 12:58
Reporter: bubbs Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: sort() efun
Description: Implement a mapping aware sort() efun.

sort() would sort arrays and mappings, but always return an array.

In the case of arrays, it would act like sort_array().

In the case of mappings, if no index is specified, then sort the mapping keys.
Alternatively, specify an index to sort on mapping values.

Optionally, use #'> as the default sorting function.
Tags:
Steps To Reproduce:
Additional Information: sort(mixed *array)
- would return sort_array(array, #'>)

sort(mixed *array, string|closure func, ...)
- would return sort_array(array, func, ...)

sort(mapping mapp)
- would return sort_array(m_indices(mapp), #'>)

sort(mapping mapp, string|closure func, ...)
- would return sort_array(m_indices(mapp), func, ...)

sort(mapping mapp, int index)
- would return the keys of the mapping mapp, ordered by:
    ( mapp[key1, index] > mapp[key2, index] ).

sort(mapping mapp, int index, string|closure func, ...)
- would return the keys of the mapping mapp, ordered by:
    funcall(func, mapp[key1, index], mapp[key2, index], ... ).
  Effectively,
    map(sort(mapp, index, func...), mapp) == sort(m_values(mapp, index), func...)
Attached Files:
Notes
(0000331)
bubbs   
2005-02-20 12:58   
Correction:
  Effectively,
    map(sort(mapp, index, func...), mapp) == sort(m_values(mapp, index), func...)

Should be:
  Effectively,
    map(sort(mapp, index, func...), mapp, index) == sort_array(m_values(mapp, index), func...)

Except map(mixed *, mapping, int) doesn't work - see other issue.

Additionally, I should be clear that sort(mapping, ...) ALWAYS returns the keys of the mapping.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
365 [LDMud] LPC Language feature N/A 2005-02-19 15:12 2005-02-19 15:12
Reporter: _xtian_ Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: noshadow modifier
Description: A modifier for just disallowing shadowing of a function.
"nomask" also disallowes redefinition of the function, but in cases this can
be too strict.

If I have code, that I don't want to slow down by always doing a
  this_object()->myfun()
and additionally want to make clear in the declaration of myfun() that
shadowing will not be permitted, but redefining in a child is possible, that
this is intended so by design and not was not a lapse, I have no way to state
my intentions as of now.

thx (obviously this is low priority but would be nice), xtian
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
194 [LDMud] Other feature N/A 2004-11-26 22:33 2005-02-10 07:17
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: top-like feature
Description: Short: Top for LDMud
Date: 990211
Type Feature
State: Unclassified

Having a efun returning a 'top' like statistic, both per-object and per-user,
would be nice. Major undertaking, though.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000329)
menaures   
2005-02-10 07:17   
I wrote a 'top' in LPC some time ago... all it could to was show eval usage on a per-UID basis. It polled wizlist_info() [WL_COST] to get the required information. For memory usage statistics and more I wrote some tools in LPC as well that use OBJ_DUMP data.

The code is rather crude, though. Nevertheless, it's proof that it can be done if you put some effort into it. No need for major undertakings in the driver...

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
352 [LDMud] LPC Compiler/Preprocessor feature always 2005-01-23 21:03 2005-01-23 21:03
Reporter: bubbs Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: pragmas to enforce/restrict catch modifiers
Description: Is there any chance of pragmas (or some other mechanism) to enforce or restrict the use of catch(; ) modifiers ?

On my mud, I would very much like to have the 'publish' modifier on by default, and to never allow the 'nolog' modifier.
Tags:
Steps To Reproduce:
Additional Information: #pragma catch_publish
#pragma catch_no_publish

#pragma catch_nolog
#pragma catch_no_nolog

#pragma no_* ?

All these 'no's are confusing, I admit. However, the naming system is entirely consistant.
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
239 [LDMud] Efuns feature N/A 2004-11-26 23:52 2004-12-13 09:49
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Path finding algorithms
Description: Short: LDMUD - Driver - Idea: Short(est) Path Algorithms
From: Andy <Andreas.Klauer@epost.de>
To: lars@bearnip.com
Date: Wed, 7 Mar 2001 23:11:03 +0100
Type: Feature
State: New

Hi Lars,

for a long time, finding a short(est) path from one point to another was a
great problem for many computer games. Today it isn't a problem anymore for
games, since fast and efficient algorithms for almost every situation can be
found on the net, and newer machines are fast enough to compute those paths in
real-time.

In MUDs, finding a short(est) path is still a great problem, but it becomes (at
least I think so) more and more important, because players want to have more
intelligent NPCs, Monsters that follow and hunt players, NPCs in towns who
arent always in the same room... and also special units, like horses who follow
a road by themselves, or ships which connect different continents.

Some wizards in UNItopia had these problems and tried to do these shortest path
algorithms in LPC. It works, but its very slow... some load all rooms and make
a database of all exits of the rooms once, which takes loads of RAM... others
load and check rooms in runtime, thats very slow.

Other problems, like the ships, can't be solved at all... in UNItopia, the
ships make large 'hops' (because its not the best thing to load 1000 rooms for
every player who wants to drive 1000 sea-miles with his ship...). But that has
the effect, that on some places players can 'hop' with their ships over land.

LPC is just not fast enough to make a really efficient short(est) path
algorithm... additionally, in LPC you normally have (as long as you don't have
a master which saves a whole database...) to load a whole room first before you
can see wether a unit (ship, for example) can enter the room or not.

So, my idea was, that it could be possible to implement a short(est) path
routine into the driver. Because most muds use the standard 8 directions:
north, west, south, east, northeast, ..., and most of the time there are
just 2 cases: something can move there oder not, something like a 2dimensional
bitmatrix would be a great thing, and useable in most muds for most of these
problems.

A map of a town could then look like the following:
00000000000000000000000
00001001001000000000000
00011111111000010000000
00000000001111110000000
01000000110000011111111
01010001100010010000000 (the 1 are the positions where players can walk on...)
11111111100011110000000
00010001000010010000000
00010001110000011111111
00000001000000000000000
00000001000000000000000

Or, for an island a ship cant drive on, it could look like this:
00001000000000000000000
00111001100000100000000
00011111110000111110000
00000011110101111111000
00000001111111111100000
00011111111111111111000 (the 1 are land mass where ships can't drive on)
01111111110000000000000
00011111111111000000000
00000011111100000000000
00000000001111110000000
00000000000011110000000

In UNItopia, such continents are up to 1000*1000 fields large (which would make
it somewhat inefficient to save it in another format than bits...)

As you may already have noticed, I'm not an Informatician at all. I don't know
how fast something like this would be if it was implemented in the driver (and
some new bitmatrixlike-datatype for LPC), or if something like that can be
implemented in the driver at all. It's just one of my crazy ideas...

With such a matrix, there could be functions which cut out submatrixes of a
large matrix, a line function that tells if on a line from (x1|y1) to (x2|y2)
are just 0's or just 1's or some 0's and 1's, and of course a short(est) path
from point A to B, or from point A to a border of the matrix, or something
similar... in this function one should be able to specify which of the 8
directions are possible, if 0's or 1's can be walked on and so on...

So, thats my idea. Something that may be possible and may be useful for many
muds.

You know the driver - of course - much better than I do. And certainly you know
muds better than I do. And you are a much better programmer than I am.

What do you think - is there a possibility to implement something like this?

Greetings,

Menaures@UNItopia (I'm not an admin, just a little wizard who doesn't know
much 'bout all this stuff;)

---------------------------------------------------------------------------
Date: Tue, 13 Mar 2001 00:54:29 -0700
From: Acius <helpsfamily@home.com>

Yeah I like this idea. Path finding on a 2d grid is good, My only
suggestion would be to use 1 byte per cell (0 = no passage, any other
number = cost) so that you can have variable-cost maps (allows NPC's to
favor roads over dark and dangerous forests, for example). For more info
on that, look up A-star (A*), which is probably the best algorithm for
this kind of problem.

A-star info, and pathfinding in general can be found at:
http://theory.stanford.edu/~amitp/GameProgramming/

As for arbitrary n-dimensional maps, it's a different problem --
basically a more general version of the 2d plane problem, and with no
cheap way to find out if you are closer or further from your
destination. Since rooms on most MUDs are usually implemented as
connected graphs with an arbitrary number of exits which can connect to
anywhere, solving the problem by modelling the rooms as a connected
graph is useful.

The main problem is that the driver has to be "exit-aware". So far,
exits are implemented at the MUDlib level, and the driver doesn't know
about them. Because the driver needs to know exits for lots of rooms all
at once, and because pathfinding may be used often, it is not efficient
to query exits from the rooms each time you try to find a path. It is
better, I believe, if the rooms proactively tell the driver what their
exits are in advance with a call to an efun (set_exit_connections,
perhaps) which passes an array of objects and/or filenames to the
driver, so it can trace from room to room. This would be stored with a
pointer in the object structure probably.

Here is some quick pseudocode on how a pathfinder might work:

Queue q;
           // A queue of nodes we have visited and which
           // we need to recurse outward from.
Object curr; // The current node we're focusing on.
Mapping visited;
           // Tracks nodes you've visited; also provides
           // a backward trace so you can figure out the
           // path when you're done.

QueuePush( q, starting_room );
visited = EMPTY_MAPPING;
MappingAdd( visited, starting_room, NULL );
while( !q.empty() ) {
    curr = QueuePop( q );
    if( curr = destination ) break;
    for (Loop "i" through each exit attached to curr)
    if( !MappingMember(visited, curr.exit[i]) ) {
       QueuePush( q, curr.exit[i] );
       MappingAdd(visited, curr.exit[i], curr);
    }
}

if( curr == destination ) {
    // Figure out the path by tracing it backward through
    // the mapping we made.
}

This algorithm is a breadth-first search. So it examines all rooms that
are one exit away, then all rooms that are two exits away, then three
exits, etc. It keeps doing this until it finds the final room. Each room
remembers the room before it in the recursion, so you can trace a path
backward. I think of this like an "expanding balloon" of rooms starting
at the beginning place, and stopping when the balloon reaches the
destination.

Another good technique is to make TWO expanding balloons, one from the
starting point and one from the destination point. You accomplish this
by putting both the starting and ending points on the queue. As soon as
one of them runs into a node from the other balloon, you trace paths
backwards through both and connect them together for the final path.
This is much harder to code, but would probably be more efficient (maybe
2-4x as fast?). The trick is testing for intersection between the
"balloons", probably with a special mapping again.

That's all I have. It's late, so I apologize for any incoherency or
oversights. Best of luck to Lars with this feature, I'm hoping to use it
already :).

-- Acius (Adam Helps)

---------------------------------------------------------------------------
Date: Tue, 13 Mar 2001 08:58:00 +0100 (MET)
From: Fini <ujastrow@hasyl04.desy.de>
To: amylaar-users@nightfall.org
Subject: Re: [amylaar-users]: Fwd: Idea: Short(est) Path Algorithms


> A map of a town could then look like the following:
> 00000000000000000000000
> 00001001001000000000000
Somewhere you need to assign pathnames to the 0s and 1s. Thats the
same problem you have in LPC. We have some differend path machines
running in our mud - speed is ok (but we aren't as large as unitopia)
but what really bothers is the memory usage for all those pathnames.
The speed to find the shortest path (with one of the well known algos)
is no problem here (for distances of maybe 100 rooms).

If you just implement 2d or 3d bitmaps and some path algorithm I cannot
see any improvement on lpc solutions.

And to be frank - I think there are more important things to do that
this ;o)



  Fiona @ Wunderland


---------------------------------------------------------------------------
Date: Tue, 13 Mar 2001 09:35:58 +0100 (MET)
From: Fini <ujastrow@hasyl04.desy.de>
To: acius@bigfoot.com
Cc: amylaar-users@nightfall.org
Subject: Re: [amylaar-users]: Re: Short(est) Path Algorithms

> This algorithm is a breadth-first search. So it examines all rooms that
> are one exit away, then all rooms that are two exits away, then three
> exits, etc.
> [...] an "expanding balloon"

In my experiance rooms in muds are not that much connected, you have some
paths with no extra exits at all for 5 rooms and so on. So this very
basic approach is really slow compared to more intelligent algos which
take the room graph into account - means having nodes and interconnecting
bows.

While the baloon-method needs different and more and more time heres a
snippet of http://ciips.ee.uwa.edu.au/~morris/Year2/PLDS210/dijkstra.html
(just the first I found an yahoo with 'djikstra' as search keyword).

> Djikstra's algorithm (named after its discover, E.W. Dijkstra) solves
> the problem of finding the shortest path from a point in a graph
> (the source) to a destination. It turns out that one can find the
> shortest paths from a given source to all points in a graph in the
> same time, hence this problem is sometimes called the single-source
> shortest paths problem.
>
> The somewhat unexpected result that all the paths can be found as
> easily as one further demonstrates the value of reading the literature
> on algorithms!

The last sentence is the most important :*)


   Fiona @ Wunderland


---------------------------------------------------------------------------
Date: Tue, 13 Mar 2001 19:31:25 +0100 (MET)
From: Fini <ujastrow@hasyl04.desy.de>
To: acius@bigfoot.com
Subject: Re: [amylaar-users]: Re: Short(est) Path Algorithms

Hi!

> The "balloon" algorithm I described does not mean a balloon-shaped object
I know your algo well enough ;o) its normally the first approch to that
kind of problem.

> compute per node, however it does handle edge cost (the method I gave
> assumes all edges are the same cost).
No problem to introduce edge cost in your algo, is it ;o)

> in O(n) time [...]
Btw complexity of the balloon in light graphs should be O((E+V)log V) ;o)

> Yes, very true, but be careful that you understand my algorithm before
> picking it apart. It is the same order of time.
There are some different algorithms for different types of typical or
expected data. Choosing the right algorithm for the given situation is
the problem - not the implementation of some well known algorithm.

I dont pick your balloon apart, I just state that there is another algo
which performes better with the given data (at least in our mud and our
typical interconnections of rooms). No offence intended.

Fini

---------------------------------------------------------------------------
Date: Tue, 13 Mar 2001 10:37:54 +0100 (MET)
From: Jacob 'Ugh' Wieland <ughosage@cs.tu-berlin.de>
To: acius@bigfoot.com
Cc: amylaar-users@nightfall.org
Subject: Re: [amylaar-users]: Re: Short(est) Path Algorithms

Maybe the problem should be approached from
the same angle as in reality (where the same problem exists).

There, the 'world' is organized hierarchically into 'regions'
(graphically speaking kinds of 'strongly connected components')
for which there exist
 - local maps (connecting actual locations),
 - country-maps (connecting the cities),
 - continent-maps (connecting the countries) and
 - world-maps (connecting the continents).

Each node needs some connection-points for the next-higher level
(city exits, borders-stations/mountain-passes, ports).

Thus, the complexity of the path-finding-problem to be solved
depends on the 'locality' of the source and destination (and possible
means of travel, of course :-)) meaning which hierarchical
boundaries have to be traversed.

Normally, the amount of actual nodes in each graph isn't that
high and the path-density decreases with each level. Thus, it
should neither be a problem to either compute the local
connections at runtime or once and for all for a database which
shouldn't be so large, either.

Thus, you (pre-)compute only the connections between nodes of the
same hierarchy and compute the global path from these by finding
the paths to the different connection points from the lower
and the higher hierarchy.

If you want to find the routes from a tavern in one city to a tavern in a
city on another continent
- look for paths to exits of that city
- look for paths from exits of that city to exits of the country of the city
- look for paths from exits of the country to exits of the continent of the country
- look for paths from exits of the continent to entries of the continent of
  the country of the other city
- look for paths from entries of the target-continent to entries of
  the target-country
- look for paths from entries of the target-country to entries of the
  target-city
- look for paths from entries of the target-city to the target tavern
--> compute the different routes (shortest paths or whatever) on this
    probably very small subgraph (you can rule out unacceptable paths
    - too long, too expensive, wrong means of travel, etc. - on each level
    to cut down the complexity of the overall problem)

For shortest/all paths (and related) problems, the Floyd-Warshall-Algorithm
has a good complexity (though not the best).

for all bridge(s) in nodes
  for all start(s) in nodes
    if there are paths from start to bridge
      for all goal(s) in nodes
        if there are paths from bridge to goal
          connect the paths from start to bridge with the paths from
          brige to goal and add them to the paths from start to goal

Ugh, the Lib Orang-Utan of TubMud

---------------------------------------------------------------------------
Date: Tue, 13 Mar 2001 19:59:18 -0700
From: Acius <helpsfamily@home.com>

Oops, sorry to send this to Jacob twice. I meant to post it to the
mailing list the first time.

Jacob 'Ugh' Wieland wrote:
 > Maybe the problem should be approached from
 > the same angle as in reality (where the same problem exists).
 >
 > There, the 'world' is organized hierarchically into 'regions'
 > (graphically speaking kinds of 'strongly connected components')
 > for which there exist
 > - local maps (connecting actual locations),
 > - country-maps (connecting the cities),
 > - continent-maps (connecting the countries) and
 > - world-maps (connecting the continents).
 >
 > Each node needs some connection-points for the next-higher level
 > (city exits, borders-stations/mountain-passes, ports).

<snip>

Yes, this is a good idea. The method I gave (where each room reports its
exits) can work for this problem, if you make an object for each area,
an object for each country, an object for each continent, etc. You would
implement it like this:

Rooms only report connections to other rooms in their area.

The area stores which rooms are connected to other areas, and reports
connections to other areas (as if they were rooms).

The country stores which areas have connections to other countries,
and reports its connections to other countries.

... same goes for countries connected on continents, and continents
connected on the world. There might be some interesting messing around
when you hit oceans, but the same principle can be used.

Then, at the MUDlib level when you want to find a path, you would
start by querying the path between the two continents, then between
the areas and the edges of the continent where they are connected,
then between the rooms connecting each area object (these can be
cached), and also the rooms in the endpoint area objects. You can do
this all in the MUDlib without extra driver support.

Also, Fiona points out that Dijkstra gives a better solution to path
finding if you have edge costs. Since edge costs are very useful (they
help persuade NPC's to stick to roads, etc.) it is probably better to do
it this way. Perhaps you can do it this way:

set_connections( borders, costs );

Where borders is an array of objects, and costs is an array of integers.
The two arrays would be in parallel. If an array of costs is not
included, you can assume ({ 1, 1, 1, ... }) to match the number of borders.

-- Acius

---------------------------------------------------------------------------
Date: Thu, 22 Mar 2001 11:49:58 +0800
From: Trevor Phillips <phillips@central.murdoch.edu.au>

Eeek! Have I ignored/missed interesting discussion on this list? Or has it been
on some other list I'm not on??

I dabbled with path finding years ago (assuming we're talking the auto-routing
from one room to another room, useful for Monster navigation, etc...), and had
a working model, but it was computationally intensive such that on the server
at the time it'd give "too long eval" too often to be practical.

Rooms is probably the most developed std object on our Mud, with rooms having
dimensions (rough NS/EW/Height), as well as properties like indoors/outdoors,
etc... The dimensions allowed an auto-mapper to fairly accurately map an area,
keeping in perspective (given that some rooms are tiny, and others are huge),
so it all matched up and actually looked reasonable on an auto-generated ASCII
map. The World Co-ordinates were set at particular rooms, and then coords for
each room were calculated based on the adjacent rooms, and room dimensions.

But, I digress. As I said, path-finding held great interest to me, but was too
slow. I planned to experiment with ERQ and an external process for calculating
the routes in a non-realtime manner. eg; Each room's properties are logged to a
MySQL table, and an external program uses the data to calculate a possible
shortest route from one room to another. I never got the time to get it up and
going, though...

Anyway, I'm interested in this topic, so'd be most appreciative if you can
forward any info on plans, etc...

Thanks. ^_^

--
. Trevor Phillips - http://jurai.murdoch.edu.au/ .
: CWIS Systems Administrator - T.Phillips@murdoch.edu.au :
| IT Services - Murdoch University |
 >------------------- Member of the #SAS# & #CFC# --------------------<
| On nights such as this, evil deeds are done. And good deeds, of /
| course. But mostly evil, on the whole. /
 \ -- (Terry Pratchett, Wyrd Sisters) /
---------------------------------------------------------------------------

Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000252)
menaures   
2004-12-12 16:01   
I don't need it anymore. Ships can no longer hop over islands and paths can be calculated from virtually anywhere to anywhere in realtime (as long as a ship can go there, of course). It's the most sophisticated thing I've ever done (and probably will ever do) in LPC.
(0000253)
malc   
2004-12-13 05:00   
If you've written something to compute shortest path algorithms, and it does it well...perhaps you could share that with the rest of the community? I'm sure most people either don't spend time on it, or don't have enough skills to make it happen. But either way, calculating paths is very interesting, at least for making more intelligent NPCs (to me).
(0000254)
menaures   
2004-12-13 06:44   
I doubt it would be of any use to the community. It's neither generic nor portable, but rather a very complex piece of code that was specially crafted to fit the requirements of UNItopia's ships. It operates on an infinite 2D grid (the sea) with arbitrary shaped obstacles (islands, but no isolated areas) on it. And our ships can move freely on this grid. If you have something in your MUD that resembles this very closely, I'll be happy to share my ideas and, if applicable, code as well. Send a message to the bearnip mailing list or contact me directly.
(0000255)
peng   
2004-12-13 09:49   
We have in our lib some support for moving npcs around. They get a target (which itself can be a moving object or a room or an object in an inventory) and do one step after another via call_out. The steps are relatively cheap (just looking in a table for the next command to do), but registering new rooms in the system can be expensive. But thats tolerable since its only done once. We have all the main areas included and the npcs can travel from one end of the galaxy, including using spaceships, teleporters and lifts to the other. It works quite well.
Internally it uses a dijkstra-algorithm.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
251 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-27 00:01 2004-12-07 07:12
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Reverse foreach()
Description: Short: Allow reversed foreach()
From: Pen (Stefan Riemer)
Date: 2001-06-04
Type: Feature
State: New

Allow the traverse an array from the top in foreach() instead of from the
bottom.

Maybe make the syntax similar to catch (;nolog):

  foreach (i : array ; reverse)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000237)
_xtian_   
2004-12-07 07:12   
this shouldn't be necessary anymore with the (new) efun reverse()

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
200 [LDMud] Efuns feature N/A 2004-11-26 22:40 2004-11-27 01:33
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Efuns from Tubmud
Description: Subject: Efuns from Tubmud
From: Lars Duning <lduning@peopledoc.com>
Date: Tue, 09 Mar 1999 18:30:40 +0000
Type: Feature
State: Acknowledged

In Tubmud, look at /basic/strings, /lib/strings, /kernel/simul/mapping.c
and look for the array efuns.

Alfe would like to see lib/strings/difference hardcoded, too :-)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: tubmud.stuff (4,877 bytes) 2004-11-27 01:33
http://ldmud.eu/file_download.php?file_id=37&type=bug
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
310 [LDMud] Other feature N/A 2004-11-27 01:18 2004-11-27 01:18
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Finalfrontier changes
Description: The changes done to FinalFrontier's driver prior to 1999
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: p-990204-0.gz (13,907 bytes) 2004-11-27 01:18
http://ldmud.eu/file_download.php?file_id=31&type=bug
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
308 [LDMud] Networking feature N/A 2004-11-27 01:11 2004-11-27 01:11
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: xerq: inet6 aton()
Description: Short: xerq: new request ERQ_INET6_ATON
From: mai94cch@studserv.uni-leipzig.de
Date: Wed, 5 Jan 2000 19:24:12 +0100 (MEZ)
To: Lars Duening <lars@bearnip.com>


Hallo,

ich hab mal in der erq/xerq eine neue Funktion eingebaut:

ERQ_INET6_ATON : liefert die addresse eines rechners in der
                 network-byte order.

Ich weis nicht, ob das teil ueberhaupt gebraucht wird, wenn ja wuerde
ich noch

ERQ_INET6_NTOA : liefert die ip eines rechners als string machen.

Wenns nicht gebraucht wird schmeiss den patch auf den muell :-)
                
MfG
Uwe
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: p-000401-0.gz (1,762 bytes) 2004-11-27 01:11
http://ldmud.eu/file_download.php?file_id=28&type=bug
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
307 [LDMud] Other feature N/A 2004-11-27 01:08 2004-11-27 01:08
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: EotL additions
Description: Date: Tue, 29 Feb 2000 04:25:09 -0600
From: Casey Zacek <cz@800hosting.com>
Short: EotL Additions
Type: Feature
State: New

Original changes (pre-177):

I think I'll go ahead and include the EotL hacks to the driver here,
so that you can ponder them, and possibly even include them so that we
don't have to hack them in with each update anymore!

(+ means it's a desired feature)
(- means I don't want it, but have to deal with it for legacy reasons
   but don't want it in the driver)

+ input_to has priority over editor

    This is a pretty easy hack. I agree with Xurbax that it's nice to
    be able to more a file while you're in the editor. If you decided
    to add this one to the stock driver, I don't foresee it causing any
    major problems for other muds.

+ took hostname off debug.log

    I've always thought it should be a compile- or run-time directive
    as to what you name your debug log, and I think I remember reading
    comments from you along those lines as well... We basically have
    all our "system" logs named with capital letters in our /
    directory so that they're easily seen at the beginning of a
    directory listing, and we don't really want the hostname on there.

+? added remote_command()

    I think Xurbax added this one because he didn't like leaving
    add_action()'ed functions non-static and not being able to force
    people to do stuff. I haven't hacked it into 3.2.7 because I don't
    think it's really that necessary, but it can be a nice thing from
    a coding standpoint. What it did was return 1 anywhere in the
    stack from the time command() with two arguments was invoked until
    that command execution finished. I'd rather have it return an
    object (the one that issued the command() call, probably) than
    just 1, but as it is, we don't have it at all.
    
    What'd *really* be cool, now that I'm discussing it with the EotL
    Arches, is if command_stack() had an extra element in the list that
    said whether there was a command() call to invoke the command or
    not.

+? one second call_out granularity

    I haven't really had a chance to look at this. I haven't patched
    it into 3.2.7, and it's not yet a priority. It's nice to have.
    Heartbeats still have 2-second-ish intervals.
    
    What we'd *really* like is a way to do a call_out(func, 0, args...)
    so that func(args) would be called immediately after the current
    execution stack was finished.

- added privilege_violation check for shutdown() efun

    This is like a 2-line hack, but I really don't see much point
    in adding it. We can use nomask simul_efuns instead. What we
    really want is a way to define what functions cause privilege
    violations through a driver hook or something.

+? added __BFILE__ preprocessor define

    Base file... The .c file being compiled, even if you're within a
    .h file, basically. Kinda handy, but not necessary... I didn't
    hack it into 3.2.7.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: p-000306-1.gz (15,308 bytes) 2004-11-27 01:08
http://ldmud.eu/file_download.php?file_id=26&type=bug
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
306 [LDMud] Other feature N/A 2004-11-27 01:07 2004-11-27 01:07
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Batmut diffs (2001)
Description: See attached archive.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: bat-011215-diff.tar.gz (28,310 bytes) 2004-11-27 01:07
http://ldmud.eu/file_download.php?file_id=25&type=bug
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
305 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-27 01:06 2004-11-27 01:06
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Class variables a la sima
Description: Short: class variables
From: Amylaar
Date: 2003-05-15
Type: Feature
State: New

In sima I have a 'shared' type modifier that causes the svalue itself to be
stored in the program.
Of course that goes with stackmachine lvalue codes to push references
to these values...
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
304 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-27 01:05 2004-11-27 01:05
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Automatic member initialisation for structs
Description: Short: Automatic member initialisation for structs
From: Dafire
Date: 2002-09-21
Type: Feature
State: New

Vielleicht wäre es schön wenn man schon member initialisieren könnte...
z.b. :

struct Test {
  int a;
  string b;
  mixed *c=({});
};

-------
This would be possible with another 'internal' function, holding the
code to setup the struct members. The function would have to be inherited in
parallel with the struct, which would happen automatically anyway. The struct
definition would have a flag saying if the function exists. If yes, any call
to S_AGGREGATE would also have a reference to the function.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
301 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-27 01:03 2004-11-27 01:03
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Index by value
Description: Short: Index by value
From: Gawain
Date: 2002-09-04
Type: Feature
State: New

Sag mal, waere es m??glich in den Driver ein Feature einzubauen, das so
aussieht:
den [] operator fuer strings zu erweitern, dass man schreiben kann
['x'...<'y'], wobei x,y chars sind... und dann bekommt man einen string
wieder, der vom ersten auftreten von x bis zum letzten auftreten von y
geht...
dann muss man nicht immer mit strstr und so rummachen...

bsp: string abc = "das ist; ein test: fuer bla";
     string def = abc[';'..<':'];
       def ist jetzt " ein test"

> Interessante Idee, auch wenn der [..] Operator dafuer nicht verwendbar ist
> ([';'..<':'] ist ununterscheidbar von [59..<58]); man koennte aber [[..]]

wenn man die zeigen in die '' einschliesst sollte man das doch erkennen
koennen... aber du weisst das sicher besser :)

> verwenden. Die Frage ist: was machst du, wenn eines oder beide Elemente
> nicht gefunden werden?

so wie beim []. wenn erstes nicht gefunden, dann vom start an, wenn letztes
nicht da, dann bis zum ende, wenn beide nicht da, dann den original-string.
man k??nnte auch noch so machen, dass man angeben kann, welches vorkommen...
also z.b. 2. '*' von vorn bis 4. ';' von hinten/vorn... also die selbe syntax
wie bei [] nur dass nicht die positionen gemeint sind, sondern das auftreten
von zeichen...
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
300 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-27 01:02 2004-11-27 01:02
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Quote special chars in compiler error messages
Description: Short: Quote special chars in the source text error messages
From: Markus Peter
Date: 2002-08-25
Type: Feature
State: New

Mir ist neuerdings (seit wir Windowsusers als Wizards haben) aufgefallen,
dass der Driver an die log_error Funktion Sonderzeichen unveraendert
weitergibt, ich hab also im Log jetzt so Meldungen wie:

home/mrks/npc/pet.c line 108 before '^M': Bad assignment: illegal lhs
(target)

wobei ^M ein echtes CR ist. Ich hab auch schon faelle gesehen, in denen
Escape Codes die irgendwie in die Files gelangten (Editorfehlfunktion
meist) so mit ausgegeben wurden.

Ich kann solche Sachen natuerlich auch im Master selber abfangen, aber so
wie ich die Master Objekte der verschiedenen Mudlibs kenne, hat da so gut
wie keiner darauf geachtet, also waere es vielleicht sinnvoll, dass der
Driver die Sonderzeichen im Source bereits gequoted an den master uebergibt.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
287 [LDMud] Runtime feature N/A 2004-11-27 00:52 2004-11-27 00:52
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Introduce 'regexp' datatype
Description: Short: Introduce 'regexp' LPC datatype
From: Lars
Date: 2002-03-28
Type: Feature
State: New

Add an svalue 'regexp' so that wizards can deliberately precompile
regexps. regexp() would then have the signature

  regexp(mixed *, string|regexp, int default: F_CONST0)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
282 [LDMud] Efuns feature N/A 2004-11-27 00:48 2004-11-27 00:48
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.10  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Default 'option' parameter for regexp functions.
Description: Short: Default 'option' parameter for regexp functions
From: "Wolf Dieter Dallinger" <wolf.dieter@dallinger.de>
Date: Thu, 7 Mar 2002 12:36:17 +0100
Type: Feature
State: new


regreplace() k=F6nnte auch ohne vierten Parameter funktionieren, als =
Default-Wert w=FCrde ich 1 vorschlagen, dies duerfte doch die haeufigste =
Anwendung sein.

Gruss

Pulami@UNItopia

Wolf Dieter Dallinger
Eckartshaldenweg 11 - D-70191 Stuttgart
Tel. (07 11) 25 67 55-0 - Fax (07 11) 25 67 55-5
Email wolf.dieter@dallinger.de
WWW http://www.dallinger.de/wolf.dieter/
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
280 [LDMud] Runtime feature N/A 2004-11-27 00:44 2004-11-27 00:44
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Heartbeat processing
Description: Short: Heartbeat functionality
Date: 2002-02-20
From: Lars
Type: Feature
State: New

MudOS has hooks to hook into the heartbeat processing? If yes, see if it is
useful.

For each object store the number of the last heartbeat and make it retrievable
with object_info().
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
272 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-27 00:24 2004-11-27 00:24
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Don't use magic characters in lexer
Description: Short: Lexer should not use magic EOF characters
From: Lars
Date: 2001-12-13
Type: Feature
State: New

Instead of using a magic EOF character, the lexer should find the end of
the file in the buffer by length checks.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
268 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-27 00:20 2004-11-27 00:20
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Make negative range assignments possible
Description: Short: Make negative range assignments switchable
Date: 2001-10-16
From: Coogan, Lars
Type: Feature
State: New

Assignments to negative ranges ([5..3]) can cause errors, but can also be
used usefully. Ideally a special syntactic construct, and/or a #pragma (the
latter for backwarts compatibility), could be used to let the programmer
clearly state their intentions.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
265 [LDMud] Efuns feature N/A 2004-11-27 00:17 2004-11-27 00:17
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Formatting in terminal_colour()
Description: Short: Left, Center, and Flush formatting for terminal_colour()
From: Slava Ignatjev
Date: 2001-10-15
Type: Feature
State: New
See also: f-011016-0

Okay, I suggest to change format of the fun a bit, to the following:

varargs string terminal_colour( string str
                              , null|mapping|closure map
                              , int wrap | string wrap
                              ^^^^^^^^^^^^^^^^^^^^^^^^^
                              , int indent )

where "int wrap" remains almost the same, except for it begins
to serve right justification.

"string wrap" will serve following:

"n-" <- left justification
"n|" <- centering
"n$" <- flushing
where 'n' is a number of columns

I think, this is not too hard to implement. And is not against current
ideology of the linewrapping in the function.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
259 [LDMud] Efuns feature N/A 2004-11-27 00:10 2004-11-27 00:10
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Object list efuns
Description: Short: New object list efuns
From: Tomba@Batmud
Date: 2001-08-25
Type: Feature
State: New

all_objects() globally tries to find objects matching to the argument
(objects name).

count_objects() is basically the same as all_objects, but it returns the
number of the objects found.

These two can be merged into the debug_info() efun.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
256 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-27 00:08 2004-11-27 00:08
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Location of redefined identifiers
Description: Short: Add location to defined identifiers
From: Freaky
Date: 2001-7-26
Type: Feature
State: New

When warning about redefined identifiers and the like, it would be nice to
know where the original definition was.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
252 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-27 00:02 2004-11-27 00:02
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Loop labels
Description: Short: Label (loop-) statements
Date: 2001-06-04
From: Lars
Type: Feature
State: New

Allow to label loop and other conditional statements, so that berak and
continue can terminate them directly.

loop : foreach() {
         ...
         break loop;
       }
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
246 [LDMud] Efuns feature N/A 2004-11-26 23:56 2004-11-26 23:56
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Filepath resolution support
Description: Short: Efun to resolve paths
From: Lars Duening <lars@bearnip.com>
Date: Tue, 22 May 2001 23:46:39 -0600
Type: Feature
State: New

Following up to all the resolve_path mails - I'll write something on the
catch_output and reload_object tomorrow (and apologies to Dale who now gets
to read this all again):

Dale Perkins wrote on Saturday, May 19 2001, 14:08:04:

>> - The relative path requires an anchor to be relative to. By default this
>> could be the current object, but the wizard should be able to specify
>> otherwise. A possible efun signature would therefore be
>>
>> string resolve_path ( string pathname
>> , string|object anchor = this_object())
>
>How about calling query_path() in the object passed to the efun, if that
>fails then you use the objects base directory.

Hmm, I don't really like adding hard coded lfun names to the driver - but
there might be a different way of getting the same result:

   string resolve_path ( string pathname
                       , string|object|closure anchor)

If the anchor is a string, it is the anchor path.
If the anchor is an object, it's object_name is the anchor path.
If the anchor is a closure, it is called and the resulting string is the
anchor path.

Your idea could then be implemented with the call

    resolve_path(path, (: this_object()->query_path() :) )

or easier

    resolve_path(path, this_object()->query_path() );

> string dir_of(object ob){
> return "/" + implode(explode(file_name(ob), "/")[0..<2], "/");
> }

This would be a equivalent to the dirname and basename unix commands. Are
they needed often?

>> - The ~ notation for home directories needs to be understood, and in
>> extension any shortcut notation (Nightfall for example uses + for
>> domains and & for projects). The solution I see here is to introduce
>> a new master apply which is called for any path which begins with
>> a special character other than '/' and '.'.

I thought about this, and I think that a resolve_path() efun does not need to
expand the shortcuts - it just needs to recognize them. The actual expansion
can be done in valid_read()/valid_write(), where it happens nowadays anyway.

Acius wrote:

>I have written a fair amount of MS-DOS, Windows, and Linux code, and
>they all have very similar systems for handling relative paths. Namely,
>each object/process has its own "current directory" and paths in all
>file commands are evaluated relative to it. If embedding this in the
>lib, I would actually change the handling of relative paths in all
>file-access commands. That would let me do things like:
>
>read_bytes("mydata", 100);
>
>... or ...
>
>save_object("myself");

I think the problem here is that there is no widely accepted notion of what
the 'current directory' for an object is, so we'd end up with a boondoggle of
hooks. In other words: this kind of functionality belongs into simul_efuns
and/or valid_read() and valid_write().

> Admittedly, the system I've described above doesn't need a new efun at
> all, just a few extra calls to master.c. And in fact, this entire system
> could be implemented with existing MUDlib code using valid_read and
> valid_write mechanisms... (although I think the point was making it
> consistent, not just making it possible)

The original point was to make one of the central pieces of path resolution
more efficient :-)

--
Lars Duening; lars@bearnip.com
PGP Key: http://www.bearnip.com/lars/pgp-lars.asc
------------------------------------------------------------------------------
Freaky writes:

Generell wuerde ich mir so eine Funktion im Driver auch wuenschen, da
ich dann nicht immer so auf einen korrekten Filenamen achten muesste
(z.B. kein .. oder /./ oder // im Pfad usw.)

Wir haben fuer diesen Zweck folgende simul-efuns:
abs_path und file_path

Und Funktionen 'add_path' und 'query_current_path' im Pla
Wildcard-Aufloesung.
------------------------------------------------------------------------------
Date: Thu, 24 May 2001 13:21:17 -0400
From: Matthew Julius <julius.2@wright.edu>

Lars Duening wrote:

[snip]

> string resolve_path ( string pathname
> , string|object|closure anchor)
>
> If the anchor is a string, it is the anchor path.
> If the anchor is an object, it's object_name is the anchor path.
> If the anchor is a closure, it is called and the resulting string is the
> anchor path.

[snip]


I'm not a big fan of this resolve_path() business. Relative paths vary
widely from game to game and the only consistent relative symbols used
across the board are "." and "..". I don't see an efun making them
that much more efficient. The LPC overhead in converting a relative path
to absolute is miniscule compared to the amount of work that you're
probably doing anyway (file manipulation, ls, etc.) so I don't see this
efun being used for efficiency concerns. I think it would only be useful
for convenience, but it's not particularly convenient for anyone who
already has a simul efun that does this (and probably does a whole lot
more, at that).

Additionally, there's going to be confusion with leading slashes and
other relative symbols. For example, what are the results of these calls
in compat mode (or native mode for that matter):

  resolve_path("dir/", "/secure")
    "dir/"
    "/dir/"
    "secure/dir/"
    "/secure/dir/"
  resolve_path("~wizard", "/secure")
    "/secure/~wizard"
    "secure/~wizard"
    "~wizard"
    "/~wizard"

So, at the very least, wouldn't we need a driver hook to define the
relative symbols ? What if somebody's mudlib allows a wizard to define
his or her own symbols ?

Also, most mudlibs will be doing processing after a call to resolve_path()
anyway, so this efun would be even less of a savings. It probably
wouldn't result in any savings at all, since all it will be doing is
converting "." and "..". The mudlib I use also allows "...", which causes
even more confusion. Is the "..." resolved at all, or do I end up
resolving it in a simul efun (in which case, I'd rather just do "." and
".." along with it).

I just don't see how this functionality is all that useful as an efun.

> >> - The ~ notation for home directories needs to be understood, and in
> >> extension any shortcut notation (Nightfall for example uses + for
> >> domains and & for projects). The solution I see here is to introduce
> >> a new master apply which is called for any path which begins with
> >> a special character other than '/' and '.'.
>
> I thought about this, and I think that a resolve_path() efun does not need to
> expand the shortcuts - it just needs to recognize them. The actual expansion
> can be done in valid_read()/valid_write(), where it happens nowadays anyway.

It definitely has to recognize the relative symbols. However, if it's
not expanding them also, what exactly is this efun going to be doing? And
whatever that is, why is it an efun and not 2 or 3 lines of LPC in a simul
efun?


> The original point was to make one of the central pieces of path resolution
> more efficient :-)

Hmm ...



--
Matthew Julius o_o
                                 ( _ )
julius.2@wright.edu ( | | )
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
241 [LDMud] Other feature N/A 2004-11-26 23:53 2004-11-26 23:53
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Pass the ERQ_DIR to the erq as argument
Description: Short: Runtime ERQ Executable directory specification
Date: Wed, 14 Mar 2001 14:49:05 +0100
Type: Feature
State: New

Weiterhin waere es dann auch noch schoen, wenn man das ERQ_DIR als
Kommandozeilen-Parameter uebergeben koennte. (dazu muesste der Driver
dem ERQ das als Parameter uebergeben, was aber zu Inkompatibilitaeten
fuehren wuerde, deswegen wohl eher als future-feature ;)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
237 [LDMud] Implementation feature N/A 2004-11-26 23:48 2004-11-26 23:48
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Possible implementation of T_ERROR
Description: Short: Possible implementation of T_ERROR
From: Lars
Date: 2001-02-16

Use T_NUMBER and set x.code to something != 0.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
236 [LDMud] Networking feature N/A 2004-11-26 23:41 2004-11-26 23:41
Reporter: lars Platform:  
Assigned To: OS:  
Priority: low OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Possible telnet machine implementation detail
Description: Short: Possible implementation detail of the telnet machine
From: Lars
Date: 2000-12-20
Type: Feature
State: New

May the interactive structure should also hold more flags: 'tried to switch to
charmode using method 0000001', 'succeeded with method 0000001', 'tried method 0000002', etc.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
230 [LDMud] Compilation, Installation feature N/A 2004-11-26 23:34 2004-11-26 23:34
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: configure-with_portno should take a string
Description: Short: configure-with_portno should take a string
From: Lars
Date: 000814
Type: Feature
State: New

The configure/config.h option 'PORTNO' should take a string of the form
"<port>{,<port>}" to allow the builtin configuration of multiple ports.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
220 [LDMud] Efuns feature N/A 2004-11-26 23:25 2004-11-26 23:33
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: chmod() and other filemask issues
Description: Short: Allow the use of masks with mkdir()
Date: 0003026
From: Krise
Type: Feature
State: New
See also: f-000616

As it says: allow the creation of dirs (or even files?) with an mask
other than the default 775.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
Notes
(0000216)
lars   
2004-11-26 23:33   
Short: Allow to set a certain umask
From: Kees Leune
Date: 000616
Type: Feature
State: New
See also: f-000326

Also, a related question. In object.c, line 1655, the function that
saves objects has a hard code umask in it (currently 0640). Would it be
possible to make this option configurable? Since we want our player save
files to be accessible by the web server, we needed to either put the
server in group mud, or allow mud to be read the rest. Since we are
running dedicated, I decided to take the easy way :) It would even be
more beautiful is we could have a umask efun, since i really only would
like to have the player.o files 644, but the rest 640 :)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
227 [LDMud] Runtime feature N/A 2004-11-26 23:30 2004-11-26 23:30
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Use id numbers instead of error messages
Description: Short: Use ID numbers for error messages
Date: 000413
From: MudOS and Lars
Type: Feature
State: New

Instead of generating message texts, pass a numeric ID plus any
extra data to the mudlib.

E.g. instead of error("Expected type %s instead of %s", a, g)
use error(E_TYPE, a, b);
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
219 [LDMud] Efuns feature N/A 2004-11-26 23:24 2004-11-26 23:24
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Efun copy_file() shouldn't raise errors
Description: Short: copy_file() should return error values
Date: Sun, 5 Mar 2000 15:25:22 -0600
From: Casey Zacek <cz@800hosting.com>
Type: Feature
State: New


copy_file() shouldn't raise a runtime error in any case. it should
only return error-specifying values.

--
-- Casey Zacek
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
218 [LDMud] Efuns feature N/A 2004-11-26 23:16 2004-11-26 23:16
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Modify efun command_stack()
Description: Short: Extension to command_stack()
Date: Tue, 29 Feb 2000 10:39:23 -0700
From: Lars Duening <lars@bearnip.com>
Type: Feature
State: New


On 29 Feb 00, at 11:21, Casey Zacek wrote:

>
> Regarding the command_stack() additions I suggested, one of my Arches
> came up with this:
>
>
> oh and I realized that if command_stack() returned the object
> calling command(), that'd almost certainly solve our problems
> cuz we can test that against the command_giver element of the
> corresponding stack item and if they match up, then the object
> is forcing itself and its okay to let it through the only
> problem is that i envisioned the offending object element to
> return 0 if command() wasn't used that might not work because
> what if the offending object got dested then it'd still be
> "insecure" or whatever, but 0 would be in there you'd need to
> come up with some other value for a "secure" command

How about the object name instead of the object itself?
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
212 [LDMud] Efuns feature N/A 2004-11-26 22:58 2004-11-26 22:58
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: restore_xxx() should accept looser syntax
Description: Short: restore_value() should accept looser syntax
From: Freaky
Date: 991123
Type: Feature
State: Unclassified

ein restore_value("({1,2,3})") geht nicht, da das ',' vor dem }) fehlt.
Ausserdem zeigt er im Fehlerfall nicht an, wo genau der Syntax-Fehler ist.

Problem is the dense programming of the value parser which expects exactly
the syntax of the value-writer - reprogramming it is not that easy.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
209 [LDMud] Networking feature N/A 2004-11-26 22:55 2004-11-26 22:55
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Use poll() or kevents instead of select()
Description: Short: Use poll() instead of select()
Date: 980816
From: Lynx
Type: Feature
State: Acknowledged

poll() scales better for a large number of users, but is not implemented
everywhere.

See CUJ 2002/12 which presents a wrapper around poll(), /dev/poll and the (imo
superior) FreeBSD kqueues.

Implementation maybe by simulation poll() through select() where not
supported.


POLL(2) POLL(2)


NAME
       poll - I/O multiplexing

SYNOPSIS
       #include <poll.h>

       int poll(fds, nfds, timeout)
       struct pollfd *fds;
       unsigned long nfds;
       int timeout;

DESCRIPTION
       poll() provides users with a mechanism for multiplexing
       input/output over a set of file descriptors (see
       intro(2)). poll() identifies those file descriptors on
       which a user can send or receive messages, or on which
       certain events have occurred. A user can receive messages
       using read(2V) or getmsg(2) and can send messages using
       write(2V) and putmsg(2). Certain ioctl(2) calls, such as
       I_RECVFD and I_SENDFD (see streamio(4)), can also be used
       to receive and send messages on streams.

       fds specifies the file descriptors to be examined and the
       events of interest for each file descriptor. It is a
       pointer to an array with one element for each open file
       descriptor of interest. The array's elements are pollfd
       structures which contain the following members:

              int fd; /* file descriptor */
              short events; /* requested events */
              short revents; /* returned events */

       where fd specifies an open file descriptor and events and
       revents are bitmasks constructed by ORing any combination
       of the following event flags:

       POLLIN If the file descriptor refers to a stream,
                      a non-priority or file descriptor passing
                      message (see I_RECVFD) is present on the
                      stream head read queue. This flag is set
                      even if the message is of zero length. If
                      the file descriptor is not a stream, the
                      file descriptor is readable. In revents,
                      this flag is mutually exclusive with POLL?
                      PRI.

       POLLPRI If the file descriptor is a stream, a pri?
                      ority message is present on the stream head
                      read queue. This flag is set even if the
                      message is of zero length. If the file
                      descriptor is not a stream, some excep?
                      tional condition has occurred. In revents,
                      this flag is mutually exclusive with
                      POLLIN.



                         21 January 1990 1





POLL(2) POLL(2)


       POLLOUT If the file descriptor is a stream, the
                      first downstream write queue in the stream
                      is not full. Priority control messages can
                      be sent (see putmsg(2)) at any time. If
                      the file descriptor is not a stream, it is
                      writable.

       POLLERR If the file descriptor is a stream, an
                      error message has arrived at the stream
                      head. This flag is only valid in the
                      revents bitmask; it is not used in the
                      events field.

       POLLHUP If the file descriptor is a stream, a
                      hangup has occurred on the stream. This
                      event and POLLOUT are mutually exclusive; a
                      stream can never be writable if a hangup
                      has occurred. However, this event and
                      POLLIN or POLLPRI are not mutually exclu?
                      sive. This flag is only valid in the
                      revents bitmask; it is not used in the
                      events field.

       POLLNVAL The specified fd value does not specify an
                      open file descriptor. This flag is only
                      valid in the revents field; it is not used
                      in the events field.

       For each element of the array pointed to by fds, poll()
       examines the given file descriptor for the event(s) speci?
       fied in events. The number of file descriptors to be
       examined is specified by nfds. If nfds exceeds the system
       limit of open files (see getdtablesize(2)), poll() will
       fail.

       If the value fd is less than zero, events is ignored and
       revents is set to 0 in that entry on return from poll().

       The results of the poll() query are stored in the revents
       field in the pollfd structure. Bits are set in the
       revents bitmask to indicate which of the requested events
       are true. If none are true, none of the specified bits is
       set in revents when the poll() call returns. The event
       flags POLLHUP, POLLERR, and POLLNVAL are always set in
       revents if the conditions they indicate are true; this
       occurs even though these flags were not present in events.

       If none of the defined events have occurred on any
       selected file descriptor, poll() waits at least timeout
       milliseconds for an event to occur on any of the selected
       file descriptors. On a computer where millisecond timing
       accuracy is not available, timeout is rounded up to the
       nearest legal value available on that system. If the
       value timeout is 0, poll() returns immediately. If the



                         21 January 1990 2





POLL(2) POLL(2)


       value of timeout is -1, poll() blocks until a requested
       event occurs or until the call is interrupted. poll() is
       not affected by the O_NDELAY flag.

RETURN VALUES
       poll() returns a non-negative value on success. A posi?
       tive value indicates the total number of file descriptors
       that has been selected (for instance, file descriptors for
       which the revents field is non-zero). 0 indicates the
       call timed out and no file descriptors have been selected.
       On failure, poll() returns -1 and sets errno to indicate
       the error.

ERRORS
       EAGAIN Allocation of internal data structures
                      failed, but the request should be attempted
                      again.

       EFAULT Some argument points outside the allocated
                      address space.

       EINTR A signal was caught during the poll() sys?
                      tem call.

       EINVAL The argument nfds is less than zero.

                      nfds is greater than the system limit of
                      open files.

SEE ALSO
       getdtablesize(2), getmsg(2), intro(2), ioctl(2),
       putmsg(2), read(2V), select(2), write(2V), streamio(4)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
208 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-26 22:54 2004-11-26 22:54
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Operator <=> for relational comparison
Description: Short: Operator '<=>' for relational comparison.
From: Lars
Type: Feature
Date: 990813

a <=> b === -1 if a < b, 0 if a == b, 1 if a > b

(Used in Perl)
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
207 [LDMud] LPC Compiler/Preprocessor feature N/A 2004-11-26 22:53 2004-11-26 22:53
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Operator :=: for swaps
Description: Short: Operator ':=:' for swaps.
From: Lars
Type: Feature
Date: 990813

Use ':=:' to swap left with righthand side (or a Cish modification, as this
operator stems from Algol-ish languages).
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
205 [LDMud] Runtime feature N/A 2004-11-26 22:51 2004-11-26 22:51
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Associate call_outs with IDs
Description: Short: call_out returns ID number
From: Daniel Sloan <sloand@alphalink.com.au>
Date: Fri, 23 Apr 1999 17:09:55 +0000
Type: Feature
State: Unclassified

I'd like to be able to do a call out and have it return an ID value. This is
an idea shamelessly ripped off from the CD driver ;-) Essentially, you remove
the need to do find_call_out(<string-value-to-search-for>), and change it to
query_call_out(<numerical-id>) or something, which is more efficient to
use...of course, the efficiency increase depends on how you implement the
search system and the call outs to work with it. The old string-search system
could be emulated very easily. Just a thought - it might not even be
beneficial.

This might even be used in parallel to the old search-by-name system.
+
------------------------------------------------------------------
From: Pulami
Date: 2002-05-19

Hi, Lars!

Ich w?rde gerne unter all den laufenden Call-Outs einer Funktion/Closure die
eine l?schen, die mit einem bestimmten Argument aufgerufen wird. Da ich
mittels call_out_info() ein Feld mit allen Call-Outs einer Funktion/Closure
bekommen kann, w?re die sinnvollste L?sung, dass ich den soundsovielten
Call-Out einer Funktion/Closure l?schen kann, also:

    int remove_call_out(string|closure fun [, int nummer])

Hierbei w?re remove_call_out(fun) das selbe wie remove_call_out(fun, 0), 0
st?nde also f?r den als n?chstes aufzurufenden Call-Out, 1 f?r den folgenden
etc. pp.

Eventuell w?re aus Geschwindigkeits-Gr?nden auch eine neue Efun

    mixed *find_all_call_outs(string|closure fun)

statt einer Sefun sinnvoll, die zur Funktion/Closure fun von this_object()
ein entsprechendes Feld analog zu call_out_info() (ohne 1.) und 2.)) zur
Verf?gung stellt. Ich nehme mal an, dass call_out_info() entsprechend der
Aufruf-Reihenfolge sortiert ist, mit dem n?chsten aufzurufenden Call-Out als
erstem Element.

Folgendes als Sefun ist wohl ausreichend schnell:

mixed *find_all_call_outs(mixed fun)
{
    return map(
        filter(
            call_out_info(),
            (: $1[0]==$2 && $1[1]==$3 :),
            // $1[0] ist das Objekt, $1[1] ist die Funktion/Closure.
            previous_object(),
            fun
            ),
        (: $1[2..] :)
        );
}
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
196 [LDMud] Efuns feature N/A 2004-11-26 22:35 2004-11-26 22:35
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: New efun strcount()
Description: Short: new efun strcount()
From: Holger@Wunderland
Date: 990217
Type: Feature
State: Unclassified

strcount(text, pattern) counts how often pattern appears in text.
Think sizeof(explode(text, pattern)).
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
192 [LDMud] Other feature N/A 2004-11-26 22:31 2004-11-26 22:31
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Socket specification (e.g. on the command line)
Description: Short: Idea for socket specification
From: Lars Duning <lduning@peopledoc.com>
Date: Mon, 25 Jan 1999 13:00:04 +0000
Type: Feature
State: Unclassified

All types of servers need a socket address. This socket address can have different formats.

    a.UNIX-sockets
      The format for a UNIX-socket is 'unix:<socket path>' or 'local:<socket path>'. The path can be an absolute path beginning with a '/'
      or a relative path to 'tnt_dir'.
      Example:

      unix:/tcp/sockets/convers

    b.INET-sockets
      The format for a INET-socket is 'ip-address:port'. ip-address can be a hostname, an ip-address or a '*' for any ip-address. Port can
      be any valid port number or a name for a service.
      Example:

      *:3600
      199.199.10.10:ftp
      foo.bar.com:2000
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
185 [LDMud] Efuns feature N/A 2004-11-26 22:25 2004-11-26 22:25
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: New efun: strmatch()
Description: Short: New efun strmatch()
From: Matthew Julius <julius.2@wright.edu>
Date: Fri, 08 Jan 1999 16:29:08 -0500
Type: Feature
State: Unclassified

string|string* strmatch(string|string*, string*|string)
  Return string matching pattern, strings matching pattern, or patterns
  matching string. The patterns are not regexp's, but patterns consisting
  of '*' and '?', such as user input. This isn't easy to do with regexp()
  since the patterns need to have sensitive characters escaped, which is
  costly in LPC. For examples,
    strmatch("london", "lon*") returns "london"
    strmatch(({ "london", "little", "like" }), "li*e")
     returns ({ "little", "like" })
    strmatch("file.o", ({ "*.o", "*.c", "*.h", "*.?", "*" }))
     returns ({ "*.o", "*.?", "*" })
  The Timewarp mudlib names this match_wildcard(), but as a sefun.

alfebtcd wrote:

> // this is useful to quote any string to be interpreted literally by the
> // regexp functions
> #define QUOTE_FOR_REGEXP(str) \
> regreplace(str,"([()[\\].*^$|\\\\])","\\\\\\1",1)
> // this does the same for single characters appearing between [ and ]
> #define QUOTE_CHARS_FOR_REGEXP(str) \
> regreplace(regreplace(str,"\\]","\\]",1),"([^-])-(..*)","\\1\\2-",1)

Again, see above. I suppose it's time to recompile our GD.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
184 [LDMud] Efuns feature N/A 2004-11-26 22:24 2004-11-26 22:24
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: New efun: member_values(): return indices for given mapping values.
Description: Short: New efun member_values()
From: Matthew Julius <julius.2@wright.edu>
Date: Fri, 08 Jan 1999 16:29:08 -0500
Type: Feature
State: Unclassified
See also: f-990714-1

mixed *member_values(mapping, closure|mixed, int, mixed...)
  Return the indices of a mapping that have a specific value.
  Second argument is the value to find or the closure to call.
  Third argument is the nth set of values to search in.
  Fourth argument and beyond are the extra arguments to send to the closure.
  Examples,
    mapping map;
    map = ([
      1: "a"; ({ 1, 2 }); 4,
      2: "b"; ({ 2 }); 5,
      3: "c"; ({ }); 12,
      ]);
    member_values(map, "a") returns ({ 1 })
    member_values(map, 8, 2) returns ({ })
    member_values(map,
     lambda(({ 'arr }), ({ #'!=, ({ #'member_array, 2, 'arr }), -1 })), 1)
       returns ({ 1, 2 })
    member_values(map, #'|, 2, 4) returns ({ 1, 2, 3 })
    member_values(map, 0) returns ({ })
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
179 [LDMud] Efuns feature N/A 2004-11-26 22:21 2004-11-26 22:21
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Give ed a programmatic interface
Description: Short: ed ideas
From: Matthew Julius <julius.2@wright.edu>
Date: Fri, 08 Jan 1999 16:29:08 -0500
Type: Feature
State: Unclassified

Something else from the MudOS CHANGELOG,
        * added a new interface for ed(), which is used if OLD_ED is not
          defined in options.h
          . Three new efuns replace ed():
            string ed_start(string | void, int | void) - start a new ed
                   session on file file. ed_start(foo, 1) means use
                   restricted mode. Only one ed session may be started
                   per object.
            string ed_cmd(string) - send the command line to ed
            int query_ed_mode() - returns:
                 0 - the current object is at a normal ed prompt (':')
                -1 - the current object isn't in ed
                -2 - the current object is at the more prompt in the
                     middle of help
                >0 - the object is at a prompt for a line. The number
                     is the line number.
          . The string result of ed_cmd() and ed_start() is the output
            that would have been sent to the user
          . The mudlib is responsible for setting the user's prompt
            (see query_ed_mode())
This is the right idea, but I really dislike the MudOS interface efuns. If
compatibility is desired, however, I can't really object much. Particularly,
my problem is with query_ed_mode(), which I think should return 0 if the
object is not in the editor. Also, problems exist if it's desired to have
the ed prompt print the current line number. This looks to be impossible
using query_ed_mode(). The -2 value, being in the middle of ed help, should
be put into ed_cmd(). If ed_cmd() returned the help as a string the mudlib
could determine how to display it--which is nice for users that have more
than 20 lines on their screen. Like I said, these additions to ed() are
the right idea, but the wrong implementation.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
175 [LDMud] Other feature N/A 2004-11-26 22:16 2004-11-26 22:16
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Ed improvements
Description: Short: Ed changes
From: MudOS via Matthew Julius <julius.2@wright.edu>
Date: Fri, 08 Jan 1999 16:29:08 -0500
Type: Feature
State: Unclassified

Straight from the MudOS CHANGELOG,
        . ed ranges can now extend past the end of the file; any line #
          larger than the last one refers to the last line
          . hitting return to get the next line at the end of a file
            now prints 'End of file.' and not 'Bad line range.'
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
173 [LDMud] LPC Compiler/Preprocessor text N/A 2004-11-26 22:14 2004-11-26 22:14
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: MudOS references vs. LDMud references
Description: Short: References MudOS vs. Amylaar
Date: Mon, 21 Dec 1998 20:08:04 +0200 (EET)
Type: Feature
State: Unclassified

The MudOS way of specifying reference arguments in the function signatures
make more sense than the Amylaar way of modifying the actual arguments.
Beek gives a good reason:

> Amylaar pass-by-reference is a real kludge, which is why it works
> differently in MudOS: consider the fact that you can expose internal
> modifications of function arguments by passing a reference to a
> function that didn't expect one! That's certainly wierd, and possibly
> even a security problem in poorly code functions ...

It can be argued if requiring the 'ref' in the function call is a good
thing or not, but it is a reminder to the programmer.

It can even be used to pass constant variables/literals for such arguments:

  void foo(ref int x);

  foo(5) -> GD creates a temporary int, assigns 5 and passes it as argument
  foo(ref 5) -> compile-time error
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
171 [LDMud] Efuns feature N/A 2004-11-26 22:11 2004-11-26 22:11
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: regexplode() modification
Description: Short: modified regexplode()
From: Dave Setty <garpoz@locallink.net>
Date: Thu, 10 Dec 1998 02:03:04 -0500
Type: Feature
State: Unclassified

2) A patch for regexplode which gives it an option not to include the
   matched parts of the input string in the return array. Useful for
   parsing some types of input. (regexplode(str, " *, *", 1))


Matthew Julius explains:

varargs string *regexplode(string, string, int)
  Allow an optional third argument to filter out matching or non matching
  pieces of the expression.
  For examples,
    regexplode("abc", "a.") returns ({ "", "ab", "c" })
    regexplode("abc", "a.", 1) returns ({ "", "c" })
    regexplode("abc", "a.", 2) returns ({ "ab" })
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
169 [LDMud] Efuns feature N/A 2004-11-26 22:07 2004-11-26 22:07
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: regexp() modification
Description: Short: modified regexp()
From: Dave Setty <garpoz@locallink.net>
Date: Thu, 10 Dec 1998 02:03:04 -0500
Type: Feature
State: Unclassified

5) A change to regexp() to let it take a single string as argument,
   returning either status, or the string if matched or 0 if not.
   This will make it more useful with map_ and filter_ array, etc.
   Since there's now a cache for compiled regexp patterns, this should
   work fairly efficiently now.

Matthew Julius explains:

varargs string *regexp(string *, string, int)
  Allow an optional third argument to return non matching strings, or return
  an array of 1's and 0's, with 1's representing matching strings in the
  array.
  For examples,
    string *arr;
    arr = ({ "abc", "def", "abbot", "lab" });
    regexp(arr, "ab.") returns ({ "abc", "abbot" })
    regexp(arr, "ab.", 1) returns ({ "def", "lab" })
    regexp(arr, "ab.", 2) returns ({ 1, 0, 1, 0 })
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
163 [LDMud] Networking feature N/A 2004-11-26 20:54 2004-11-26 21:05
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: TCP Support
Description: Short: TCP Support
Type: Feature
State: Unclassified
From: Marcus Meissner <marcus@jet.franken.de>
From: Lars
Date: Tue, 22 Dec 1998 11:57:41 +0100 (MET)
See also: f-991104-0, p-020912, p-021021

See also: MudOS, Anarres version, regarding the telnet machine.

Ich meine damit, erstmal genau ueberlegen, wie die API aussehen soll
und nicht einfach die UNIX socket* functions nachbilden, sonder etwas
LPC bezogenes basteln.

Ich hab mal drueber nachgedacht, einige Punkte, die wir beachten muessen:

- Wir muessen immer nonblocking arbeiten.
  -> Writes muessen wir wohl im Driver buffern, weil das zu kompliziert fuer
     LPC Benutzer ist.
  -> Reads sollten als Callbacks durchgegeben werden.
  -> accept/connect Behandlung braucht extra callbacks.

- Kein neuer LPC Variablentyp, das wuerde nur den Driver komplizieren.

Soweit ich mit Gedanken gekommen bin:
- Sockets werden in LPC spezifiziert durch die lokale Portnummer (die ist
  fuer TCP unique auf dem Rechner, nur wird der Portnummer Adressraum von UDP
  ueberlappt...Sprich, man muesste UDP anders behandeln. Und UNIX Domain
  sockets, und IPX ... )
- Wer darf write ausfuehren? Nur der Master, der dann evt. dieses Privileg
  per closure/functionptr weitergibt? Oder sollten wir nen Socket an ein Objekt
  binden?
-> Generell Privileg Vergabe abklaeren.

Insgesamt hatte ich ungefaehre folgende API im Kopf entwickelt erstmal,
die noch einige unklare Stellen hat:

# Macht socket/bind/listen/ socket-> select auf readability
tcp_accept(int localport,closure _accept_fun); // eventuell hostmask ?

# Wenn der accept socket readable wird ... accept und dann diese Funktion
# aufrufen.
_accept_fun(int localportnr,string remotehost,int remoteport) {
        /* Problem: Wir muessen dem GD jetzt irgendwie sagen, wem dieser
         * socket gehoert und wo er readcallbacks aufrufen soll
         */
}

# write(2) ... Mit buffering im driver. Schreibt immer soviel wie angegeben aus
# LPC sicht, wirft NICHTS weg.
void tcp_write(localport,int*|string);

# close(2) ... sollte den rest des obigen writebuffers leeren und dann erst
# den socket schliessen. Bzw. das durch evt. zusaetzliches Flag machen.
void tcp_close(localport);

# socket(2)/(connect(2) nonblocking). Ruft _connect_fun auf, wenn select(2)
# Schreibbarkeit oder Lesbarkeit signalisiert.
void tcp_connect(string remotehost,int remoteport,closure _connect_fun);

# bei readable/writeable connect aufgerufen. (remotehost/remoteport evt.
# unnoetig)
_connect_fun(int localportnr,string remotehost,int remoteport) {
        /* sollte irgendwie jetzt auch dem GD sagen, wem der Socket gehoert
         * und wo er readcallbacks aufrufen soll
         */
}

Dass Problem ist jetzt das spezifizieren von readcallbacks. Evt. kann man
die closure als returnwert von _connect_fun oder _accept_fun zurueckgeben,
oder noch eine API function verwenden, wie zB

tcp_bind(int localportnr,closure _socket_callback);

_socket_callback(int localport,int type,mixed stuff) {
        /*type: SOCKET_READ
         * stuff enthaelt entweder int* oder string (je nach intelligenter
         * binary detection.
         *type: SOCKET_ERROR
         * hmm
         *type: SOCKET_CLOSE
         * hmm
         */
}

Ueber besonders das letztere bin ich mir noch nicht ganz klar.

Vielleiocht sollte ich mir auch erstmal die MudOS implementation ansehen, bevor
ich mir NIH vorwerfen lasse :)

And lars wrote:

> Sprich, es spricht kaum was gegen ans Objekte binden.
> Ausser, wie genau man das nun machen sollte.

Driverintern relativ einfach, da mit der interactive-sentence die
notwendige Basisarchitektur vorhanden ist.

> Problem gibts wohl nur bei den leidigen Referencecounter.

?

> > > # write(2) ... Mit buffering im driver. Schreibt immer soviel wie
> > > # angegeben aus LPC sicht, wirft NICHTS weg.
> > > void tcp_write(localport,int*|string);
> >
> > Das wuerde ich socket_write() nennen, und zumindest einen Fehlercode
> > zurueckgeben lassen. Prinzipiell koennte der Socket ja auch ein UDP-
> > oder sonstwas Socket sein, 'tcp_' waere dann irrefuehrend.
>
> Hmm. Dann sollte man aber mit mehr als localport arbeiten, weil sich
> die portnummerraeume von TCP und UDP ueberschneiden.
> Oder man nimmt als Unique ID einen string mit "tcp:nr" oder "udp:nr".

Es sit moeglich ueber einen Socket/Port gleichzeitig TCP und UDP zu machen
(habs noch nie probiert und die TCP/IP-Buecher sind in der Bibliothek) - oder
iaW: TCP und UDP sind keine Namensraeume an sich.

Eine Unique-ID eruebrigt sich, da der Socket durch das Objekt definiert
ist. Funktionen wie socket_write() wuerden dann entweder ein
Socketobjekt als erstes Argument erwarten, oder nur funktionieren wenn
this_object() ein Socketobject ist.

query_mud_port(socket_object) wuerde die Portnummer liefern,
query_socket_type(socket_object) das Protokoll ("tcp", "udp", oder
"player" fuer normale Playerobjekte), query(_once)_interactive() koennte
sowas wie 'tcp:4242' zurueckgeben. Fuer die Remoteadressen hats bereits
query_ip_name(), man koennte da noch query_ip_port() hinzufuegen.

Ich schreib jetzt mal Funktionsideen auf wie sie mir gerade einfallen
(oder in deiner vorigen Mail stehen). Wenn nicht anders gesagt, setzen
die Funktionen voraus, dass this_object() das betroffene socketobjekt
ist.

void net_bind(int portno, string protocol)
  erzeugt einen Socket fuer Port <portno> (0 fuer 'any') und <protocol>
  ("udp", "tcp",...) und bindet ihn an this_object().

void net_accept(object obj, mixed extra...)
void net_accept(int portno, object obj, mixed extra...)
  Akzeptiert eine TCP-Verbindung, bindet sie an <obj> und ruft
  <obj>::_accepted(mixed extra...) auf. In der zweiten Form fuehrt
  accept() erstmal ein bind(portno, "tcp") wenn this_object kein
  socketobject ist, bzw. wirft einen Fehler wenn die Portnummer des
  gebundenen Sockets nicht mit <portno> uebereinstimmt.

void net_connect(string remotehost,int remoteport, mixed extra...);
void net_connect(int portno, string remotehost,int remoteport, mixed
extra...);
  Versucht eine Verbindung mit der gegebenen Adresse herzustellen.
  Klappt das, wird this_object::_connected(mixed extra...) aufgerufen.
  Ist this_object noch kein Socketobjekt, wird vorher noch ein
  bind(any, "tcp") ausgefuehrt etc.

void net_write(string|int* data)
  Schreibt <data> auf den Socket.

void net_read(int amount, mixed extra...)
  Liest den naechsten Block Daten, max. amount bytes, vom Socket und
  ruft this_object::_read(int* data, mixed extra...) auf.

void net_close(bool noflush)
  Schliesst den Socket, optional ohne die noch anhaengigen Daten
  wegzuschreiben.

Es braeuchte dann noch einen Fehlercallback, der asynchrone Fehler
meldet:

void _error(int(string?) type, int errcode, mixed additional...)
  wobei <type> zwischen connect, accept, read und unexpected close
  (z.B. durch destruct des Socketobjektes) unterscheidet.

Synchrone Fehler in der Ausfuehrung der efuns selber erzeugen ganz
normale runtime errors.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files: p-020912 (49,928 bytes) 2004-11-26 21:03
http://ldmud.eu/file_download.php?file_id=19&type=bug
p-021021 (9,634 bytes) 2004-11-26 21:05
http://ldmud.eu/file_download.php?file_id=20&type=bug
Notes
(0000212)
lars   
2004-11-26 20:57   
p-02912: TCP Sockets as implemented by Batmud:

Short: TCP sockets for LDMud
From: Tomi Valkeinen
Date: 2002-09-12
Type: Patch
State: New
Driver: 3.2.9-dev.248
See also: f-981226-1, f-991104-0, p-021021

UDP is not handled, hardly documented, modelled after MudOS, but stable.

Steps:
1. Apply the diff
2. Replace the socket.c with the one provided below
(0000213)
lars   
2004-11-26 21:04   
p-021021: Socket support by Ctx:

Ich habe ein bisschen mit deinem MUD-Driver herumgespielt, er ist
wirklich super ;)
Ich wollte ihn auch zu Verbindungen mit externen Services wie SMTP,
IMAP, POP3, NNTP, IRC usw. usf. einsetzen und hab festgestellt, dass das
mit dem ERQ-Daemon eigentlich nur sehr unsauber und hakelig geht. Also
dachte ich mir, waere es doch sinnvoll, wenn man den remote service als
"Player" sieht, der einem interaktiven objekt Kommandos schickt.
Bei einer Verbindung zu einem SMTP-Server z.B. wuerde das Kommando
'220' bedeuten, schick mir jetzt deine Befehle.
Bei einem IRC-Server mit festem Prefix (:irc-server.de 376) koennte man
mit modify_command() die Eingabe in ein entsprechendes Format bringen
(Zahlencode zuerst, dann Sender) und hier auch mit add_action arbeiten.
Gerade bei nicht-binaeren (Plaintext) Protokollen wie die oben genannten
finde ich diese Sichtweise elegant.

Ich habe fuer mich den Driver ein wenig geaendert, um eine efun
"connect_external" erweitert.
connect_external("127.0.0.1", 25, smtp_object); wuerde eine Verbindung
zum lokalen SMTP-server herstellen und die Verbindung an das smtp_object
binden. Nach gelungenem Verbindungsaufbau wird dort, wie bei
player-objekten, logon() aufgerufen. Bei Fehlschlag, bzw.
Verbindungsabbruch, wuerde "connerr" mit der entsprechenden errno als
Argument aufgerufen. Ansonsten verhaelt sich das objekt wie jedes andere
interaktive.

Fuer mich ist das ziemlich nuetzlich, vielleicht ja auch fuer dich oder
andere. Vermutlich sind noch Bugs darin (Eine Stelle, bei der ich mir
ziemlich sicher bin, habe ich mit FIXME markiert), ich hatte leider
nicht die Zeit mich in jedes Detail des Drivers einzuarbeiten.

Falls der Patch sinnlos/schlecht/falsch ist, schmeiss die Mail einfach
weg ;) Ueber kurzes Feedback wuerde ich mich trotzdem freuen.

Gruss

Florian Heinz (AKA Ctx)

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
162 [LDMud] Other feature N/A 2004-11-26 20:47 2004-11-26 20:47
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: OBJ_DUMP formatting needs improvement
Description: Short: OBJ_DUMP needs reformatting
Date: 981209
Type: Feature
State: Unclassified
From: Chameloid

Especially with long pathnames, the columns are very
unaligened. E.g. it'd be nice if all memory sizes
would be lined up.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
159 [LDMud] Other feature N/A 2004-11-26 20:42 2004-11-26 20:42
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Write driver-include files.
Description: Short: Write driver-include files.
Date: 981114
State: Feature
Long:

The driver should write include files like lpctypes.h on its own; e.g. with
a commandline option '--write-includes <dir>', <dir> interpreted relative
to the mudlibs top directory.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
155 [LDMud] LPC Compiler/Preprocessor tweak N/A 2004-11-26 20:38 2004-11-26 20:38
Reporter: lars Platform:  
Assigned To: OS:  
Priority: low OS Version:  
Status: new Product Version: 3.2.8 and before  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Spaces after \ - error message.
Description: Spaces after \ on a multi-line define should give a better error
message than just 'syntax error'.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
139 [LDMud] Compilation, Installation feature N/A 2004-10-31 01:52 2004-10-31 02:13
Reporter: lars Platform:  
Assigned To: OS:  
Priority: low OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
External Data (URL):
Summary: Dynamic Search paths
Description: Default the search paths for ERQ and MUDLIB to paths relative to the path of the executable at runtime.

ERQ would be at ./erq, the mudlib at ~user/mudlib or ../mudlib (searched in this order).
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.

View Issue Details
ID: Category: Severity: Reproducibility: Date Submitted: Last Update:
106 [LDMud 3.3] Implementation feature N/A 2004-08-01 23:26 2004-08-01 23:26
Reporter: lars Platform:  
Assigned To: OS:  
Priority: normal OS Version:  
Status: new Product Version:  
Product Build: Resolution: open  
Projection: none      
ETA: none Fixed in Version:  
    Target Version:  
Summary: More agressive 'force_more' handling in smalloc:large_malloc()
Description: On the 'force_more' retry, the search through the AVL tree should retain a pointer to the largest block which size is between 'size' and 'minsplit', and use that block if it can't find a fitting one.. This could lead to lots of wasted memory, but remove the number of sbrk()s.
Tags:
Steps To Reproduce:
Additional Information:
Attached Files:
There are no notes attached to this issue.