/[LeafOK_CVS]/pvpgn-1.7.4/README.DEV
ViewVC logotype

Annotation of /pvpgn-1.7.4/README.DEV

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Tue Jun 6 03:41:37 2006 UTC (19 years, 9 months ago) by sysadm
CVS Tags: pvpgn_1-7-4-0_MIL
Branch point for: GNU, MAIN
Initial revision

1 sysadm 1.1
2     PVPGN (wannabe) DEVELOPERS GUIDE
3    
4     Please read this file before asking any questions !
5    
6     0. About this document
7     =======================
8    
9     This document is intended to be read by all of you out there wanting to do
10     development or testing for/on PvPGN.
11    
12     ChangeLog:
13     29-07-2003: dizzy : Initial version
14     28-08-2004: dizzy : Run-time debugging : Appendix A
15     30-08-2004: dizzy : Updated (fdwatch, xalloc, goto, gdb)
16    
17     1. Why ?
18     =========
19    
20     You want to start coding for PvPGN ? Why ? What do you expect to get from it ?
21     Answer yourself this questions and then go to the next paragraph.
22    
23     2. History
24     ===========
25    
26     PvPGN has started as a game server emulation project, taking the excelent's
27     bnetd project source and working on it. While initially it has started as
28     a War3 emulation patch over bnetd it become a lot more than that (lots of
29     new features, lots of code changes organizing). Because of the code roots
30     you will notice a lot of things still carrying the "bnetd" word (most notable
31     examples are the main servers program file called "bnetd" or the main server
32     configuration file called bnetd.conf). We considered that as a sign of respect
33     from us to the bnetd coders we keep their names on the code they written (but
34     on the new code of course we may name them different).
35    
36     3. Objective
37     =============
38    
39     PvPGN's main objective is to support all Battle.Net clients (games) but are
40     considering in the near future to extend it to support other game protocols
41     as well.
42    
43     4. Layout of files
44     ===================
45    
46     Note: Starting here on you may find lots of terms and wors which may sound
47     "strange" to you and for this reason we have included a glossary of terms
48     in the end of this file.
49    
50     The PvPGN project consists of a main server (called "bnetd") and various
51     other programs and (little) servers (ex. bnchat, d2cs, d2dbs etc...).
52    
53     PvPGN follows the bnetd's layout of files:
54     ./bin -> used to store binaries (after compilation)
55     ./conf -> configuration files (many of them templates)
56     ./files -> various files needed for clients connecting
57     ./man -> outdated man pages :(
58     ./sbin -> same as ./bin
59     ./scripts -> various scripts for testing/managing pvpgn
60     ./src -> the source main directory
61     ./src/bnetd -> source files used only by the main server
62     ./src/common -> source files used in common by different programs
63     ./src/compat -> source files concerning portability of code
64     ...
65    
66     The build process takes place in the "src" dir.
67    
68     5. Coding Style
69     ================
70    
71     a. General
72    
73     PvPGN is mainly developed on and for UNIX/Linux. The reasons are because we
74     as coders work on this systems and because our users (at least the big ones)
75     use UNIX/Linux more than ex. Windows. But, even so we try to code in a portable
76     fashion and any release PvPGN had we made sure it compiles on win32 too (we
77     even release win32 binaries). We will never refuse a good win32 coder but we
78     prefer UNIX ones ;)
79    
80     One thing which is overlooked by newbie coders is the "esthetical" side of the
81     code. It may not be so important to many people (which code on the idea "if it
82     works then its good") but for us, coding on PvPGN is VERY important. When you
83     are coding for PvPGN PLEASE try to make your code look similar to already
84     written code (this includes identing, identificator names, etc...). Keeping
85     the code look "the same" makes its reading a lot more easier so, finding
86     bugs easier so coding better.
87    
88     One way to make sure your code sticks with the PvPGN coding style is to use
89     "indent" code indenting formating tool (http://www.gnu.org/software/indent/).
90     To use indent to get your code acording to PvPGN coding style use something
91     like this (it will format properly the file clan.c and save the new file to
92     clan.c.new):
93     $ indent -kr -bl -bli0 -l0 -br -ce -cli4 clan.c -o clan.c.new
94    
95     Other overlooked aspect for newbie coders is code replication. Please DONT
96     copy and paste code arround !!! If you need to copy common functionality from
97     some place, think about making some API of that functionalilty, put it in
98     some functions and use it from both places. I repeat, DONT replicate code.
99    
100     When allocating memory inside a function always free it in the same function
101     before its exit (exceptions: the function returns the allocated memory in
102     which case the calling function should take care of the allocated memory;
103     or the allocated memory is cached/stored somewhere to be used later, in which
104     case you must make sure it will be free()d when not needed anymore).
105    
106     In the startup code of any "external" function (function which may be called
107     from other modules then the one containing it) please check ALL the input
108     parameters (you will notice how PvPGN already does that in such functions).
109     Traditionally this has been done with contructs like:
110     if (var==NULL) { eventlog(error); return <error-code>; }
111     We have recently changed our policy because of increasing code size and lots
112     of redundant checks, we now usually prefer using assert() for this type of
113     checks (check the manual page for assert).
114    
115     A new addition is the xalloc memory allocation wrappers (for malloc,
116     calloc, realloc, strdup and free). We now do NOT allow memory allocation to
117     take place without this wrappers. They make the code smaller and easier to
118     read because they never fail so they eliminate the need for failure checks
119     and eventlogs in such cases.
120    
121     Another thing recently adopted in the team is the usage of "goto" keyword.
122     Many people have argued (and continue to) that goto are inherently _evil_ and
123     they produce "spaghetti code". But that is true for pointers and lots of other
124     powerfull C features. We consider the programmer to be the cause of bad
125     written codes and not some keywords. So we are moving into using "goto"
126     mainly in the "error exit paths" cases. Let's say you have a function which
127     needs to allocate some stuff (in 3 variables), checks for each allocation,
128     exits with error for each specific failure (also free()ing the already
129     allocated space). You can do it the PvPGN traditional way like:
130    
131     ------- CODE ----------
132     a = malloc(X);
133     if (!a) {
134     eventlog(bla);
135     return -1;
136     }
137    
138     b = malloc(Y);
139     if (!b) {
140     eventlog(bla);
141     free(a);
142     return -1;
143     }
144    
145     c = malloc(Z);
146     if (!c) {
147     eventlog(bla);
148     free(b);
149     free(a);
150     return -1;
151     }
152     <do stuff>
153    
154     return 0;
155     ------ CODE -----------
156    
157     Or you can do it the new, "goto" way:
158     --------- CODE --------------
159     a = malloc(X);
160     if (!a) {
161     eventlog(bla);
162     goto err_a;
163     }
164    
165     b = malloc(Y);
166     if (!b) {
167     eventlog(bla);
168     goto err_b;
169     }
170    
171     c = malloc(Z);
172     if (!c) {
173     eventlog(bla);
174     goto err_c;
175     }
176     <do stuff>
177     return 0;
178    
179     err_c:
180     free(c);
181     err_b:
182     free(b);
183     err_a:
184     return -1;
185     -------- CODE ------------
186    
187     The last version is a lot easier to read/debug. Because the reader is usually
188     interested by the main (non-error) code path not about the error code path.
189     Also the traditional way replicates codes (those replicated free()) which is
190     error prone (more badly, its prone to memory leaks, and believe me, I did
191     fixed a lot of this forgotten free() in error exit paths).
192     NOTE: however, with the xalloc wrappers that never fail the above examples
193     are obsolete, still there are many other similar situations where you need
194     a complex error exit path and goto comes in handy.
195    
196     When developing code you should compile always with "all warnings" enabled
197     and try to fix them (some warnings uncover real bugs), like for gcc use
198     "-Wall". When running/testing the codes you should use a memory debugger like
199     valgrind and/or bounds checking compiler patches like bounds-checking-gcc.
200     For more details about how to run pvpgn check Appendix B.
201    
202     b. Code Organizing
203    
204     PvPGN (inhireted from bnetd) trys to group functions based on their data on
205     which they work on. Thus it somewhat resembles the principle of data
206     encapsulation used in OOP. For example connection.h defines structs necesarry
207     to work with connections (the main one beeing t_connection) and functions
208     which work with this structs and which do actions related to this connections.
209     Also notice that all this functions are named like conn_<name>(). In general
210     if you have a set of functions working on a set of structs, you define the
211     structs and the functions in a <module>.h file (thus defining the API) then
212     write the function implementations in <module>.c file. And the function names
213     should be something like <module>_<name>(). Separating and grouping functions
214     in their own modules, working on their own data structures helps isolating
215     functionality in the server and thus hunting bugs a lot easier.
216    
217     c. Code Flow
218    
219     Note: this chapter is more or less correct. Is intended to give a general
220     ideea about the code flow, it may contain flows and things which are not
221     in sync with the actual code, for a better understanding I recommend reading
222     the actual code
223    
224     The server starts in main() found in bnetd/main.c file. There it parses
225     command line arguments then tries to initilize the modules by calling their
226     initilizing function (many of them called like <module>_init()). Some of this
227     modules depend on the initilizing of others so the order there may be important.
228     Also some of the modules if fail on initilizing may represent a general fail
229     thus PvPGN bails out. But should print out a explaining message (or write it
230     to the log configured file).
231    
232     From there the server calls the main server loop function found in server.c.
233     Here the loop may be simplified to something like:
234     1. fdwatch() on the set of opened sockets
235     2. call fdwatch_handle() which reads (if any) network data and "handle" them
236     (by calling the handle function coresponding to the class of the connection
237     receiving the data)
238     3. write (if any) to the network from the output queue
239     4. do any periodic or time based events
240     5. go to 1
241    
242     As seen on step 2. above we call the handling functions coresponding to the
243     class of the connection. The handle functions usualy are a big switch/case or
244     a for/if (which is equivalent) and they check for the packet type received, then
245     they act acordingly to the data received (many of them responing with packets
246     by adding them to the output packet queue of the connection).
247    
248     Appendix A. Glossary of terms
249     ===============================
250    
251     * autoupdate: the feature of Battle.Net servers to send a (MPQ, see MPQ) file
252     to the client which after downloading it, it is used to update the client
253    
254     * connection class: when a connection is established to a bnet listening
255     address the client sends an initial byte which tells the server of what class
256     of connection the following packets will be; classes of connections determine
257     what packets can go through that connection.
258    
259     * MPQ: a format archive which is used by Blizzard clients and Battle.Net
260     servers. This files are used for containing verious files (sound/graphics in
261     clients, AI scripts, update patches etc...)
262    
263     * versioncheck: also know as vcheck and sometimes just vc ; a client
264     verification system used by Battle.Net servers to identify client version and
265     "purity". Based on this the server may accept/refuse connection or ask for
266     upgrade (see autoupdate).
267    
268     Appendix B. How to run PvPGN for debugging
269     ===========================================
270    
271     It is very helpfull in finding out memory coruption bugs as soon as possible
272     so while developing codes or just when running a server it is good that you
273     use some memory coruption run-time debuggers. I dont know about Win32 users
274     but on Unix/Linux there are some good options.
275    
276     1. valgrind (http://valgrind.kde.org)
277    
278     Valgrind is not very portable (only x86, Linux and very recently FreeBSD),
279     also it slows down the debugged codes (it acts like a CPU emulator so it
280     has to do that) but I have yet to find out a better debugging tool for what
281     he does. Valgrind is so cool that recently many OSS projects use it for
282     finding out bugs in their codes. For more information you can check out their
283     web page. I will focus on valgrind with PvPGN.
284    
285     After you have compiled and installed valgrind (it's easy, ./configure, make,
286     make install) you will use it by running PvPGN like this:
287    
288     $ valgrind --tool=memcheck --num-callers=10 /path/to/bnetd -f 2> valg.out
289    
290     "num-callers" makes valgrind record backtraces with 10 entries and is usually
291     needed with PvPGN which has not very small backtrace path :)
292    
293     Another option you might want to use is "--leak-check=yes" and probably
294     "--leak-resolution=high". This options make valgrind even slower but they
295     will give memory leak information when PvPGN exits.
296    
297     I encourage EVERYONE to use it if available (that is if you run PvPGN on
298     a supported platform). Only very big servers won't be able to do it because
299     there is no hardware powerfull enough to run a big server with valgrind (but
300     big means over 500 users online). You should test it with your server and if
301     it does not make your bnetd go over 90% CPU then you should be fine. If you
302     cannot run valgrind for any reason or if you are hunting for some bugs
303     valgrind cannot find (yes, valgrind is superb but there is a class of bugs,
304     especially overflows which valgrind can't help you with) you should then try
305     the next debugging tool.
306    
307     2. bounds-checking GCC (http://sourceforge.net/projects/boundschecking/)
308    
309     This has the drawback of beeing just for GCC (as far as I know of) but has
310     the advantage over valgrind that is : more portable (virtually it should be
311     possible to use it anywhere you can use a recent GCC), a lot faster and can
312     detect bugs that valgrind cannot find. However it has the disadvantage that
313     it's error reports do not contain backtraces so they might be lesser usefull.
314    
315     To use it basically it cuts down to:
316     - download a recent compiler (ex GCC 3.4.1)
317     - download the coresponding patch from the project's sf.net page
318     - apply the patch while beeing in the gcc source dir you unpacked with a
319     command like bunzip2 -c /path/to/patch.bz2 | patch -p1
320     - compile gcc and install gcc
321     - to make pvpgn compile with your new gcc do something like:
322     $ CC=/path/to/new/gcc CFLAGS="-O0 -Wall -fbounds-checking -g" ./configure
323     - then the usual make, make install
324     - to run PvPGN you will probably need to redirect stderr like:
325     $ /path/to/bnetd -f 2> debug.out
326    
327     You will probably encounter some problems when configuring, building gcc, so
328     you should read the text in the beginning of the bounds-checking patch file.
329     Also the gcc install docs are usefull.
330    
331     When starting up your new bounds checking enabled binary you will see some
332     usefull messages. By default the patch makes the debugged program exit on the
333     first error it encounters. For a production server this is not very nice so
334     you will want to set GCC_BOUNDS_OPTS shell variable to "-never-fatal" like:
335     $ GCC_BOUNDS_OPTS="-never-fatal" /path/to/bnetd -f 2> debug.out
336    
337     Appendix C. How to generate and use "core" files
338     =================================================
339    
340     This appendix is for Unix users. I dont know if other platforms have similar
341     features, that when the program crashes unexpectedly the OS would dump the
342     contents of the memory of the crashing process into a disk file for later
343     inspection.
344    
345     First make sure that PvPGN has been compiled with debugging ("-g" parameter
346     to gcc) and with no optimizations ("-O0" parameter to gcc). PvPGN default
347     build process puts "-g -O2" so you need to edit Makefile file before compile
348     and change it to "-g -O0". Then something like "make clean; make".
349    
350     On Unix/Linux to be able to get core dumps you first need to make sure your
351     core file size limit is set acordingly. Use "ulimit -c" for querying and
352     setting this limit (I recommend setting it to "unlimited"). After that when
353     you start PvPGN make sure you are in a directory where you have write access
354     (so the OS when it wants to do the core dump it will be allowed to do so).
355     The last thing to do is when starting PvPGN make sure it starts in FOREGROUND,
356     example : /path/to/bnetd -f . If you did all this then when PvPGN will crash
357     you will get a core dump. On linux this is a file called "core", on *BSD it's
358     called <processname>.core (for bnetd that means it's called bnetd.core).
359    
360     Now that you got a core file it is time to use it to identify what happened
361     wrong in the crashing process. We use gdb (the GNU debugger, should be
362     available on all Unices) to do this. Run gdb like this:
363     $ gdb /path/to/bnetd /path/to/corefile
364    
365     Then gdb should startup, print out a lot of messages and stop after printing
366     a file and line number and quoting some C code where the crash has happened.
367     You can find out a lot more information than this. Run gdb's command "bt full"
368     and it will display a full backtrace of the moment of the crash. The backtrace
369     will contain how the functions were called along the way (their parameters),
370     and also any local variables. If you do not know what to do next from here
371     contact a PvPGN developer and give him exactly that backtrace dump, he should
372     know more.

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1