Bonjour à tous,
J'ai réalisé un programme qui fait appel à des librairies chargé dynamiquement via dlopen, lors de l' execution du symbole "module_init" recupéré via dlsym mon module fait appel a une commande interne du programme principal qui me remplie une structure de type command_t et ajoute l'element dans un tableau, jusqu'ici tout semble bien aller sauf que lorsque je parcours le tableau pour vérifier que mon pointeur s'y trouve bien et bien il n'y est pas !? Je me dit encore une ânerie de ma part mais lorsqu'a la fin de mon programme je veux décharger mon module via dlsym (... "module_end") et donc au passage libérer mon tableau (je le parcours de nouveau) et bien la mon element de type command_t est bien la, je ne sais même pas comment vous exposer explicitement mon problème tellement celui me depasse.
Je suis sous windows 7 et j'utilise cygwin32 pour compiler le programme
Le Makefile compilant les sources:
Le Makefile compilant mes modules:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 CC = gcc CFLAGS = -Wall -O -Wpadded -I /home/blackbox/havoc-ircd/include LDFLAGS = -Wall -Wl,--export-all-symbols -ldl SRCS = $(wildcard *.c) OBJS = $(SRCS:.c=.o) all: $(OBJS) @$(CC) $(CFLAGS) $(LDFLAGS) -o ircd.exe $(OBJS) @mv -f ircd.exe .. %.o: %.c @echo -e "BUILD: $@ from $<" @$(CC) $(CFLAGS) -c $< clean: @echo -e "Clearing /home/blackbox/havoc-ircd/src objects ..." @rm -f *.o @cd .. && rm ircd.exe
Le fichier module.c ou les actions dlopen/dlsym et dlclose se trouvent
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 CC = gcc CFLAGS = -Wall -g -Wpadded -I /home/blackbox/havoc-ircd/include LDFLAGS = -shared SRCS = $(wildcard *.c) OBJS = $(wildcard /home/blackbox/havoc-ircd/src/*.o) SOBJS = $(SRCS:.c=.so) all: $(SOBJS) %.so: %.c @echo -e "BUILD: $@ from $<" @$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(OBJS) clean: @echo -e "Clearing /home/blackbox/havoc-ircd/src/commands shared objects ..." @rm -f *.so
Le fichier command.c ou je créer les elements de type command_t
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105 #include "module.h" static module_t *modlist[MODHASHSIZE] = {0}; static unsigned int modhash(const char *str) { unsigned int hash = 0; int c; while ((c = *str++)) hash += c; return (hash & (MODHASHSIZE - 1)); } int load_module(const char *filename) { void *handle; void (*func) (void); char *error = NULL; //char name[KEYLEN + 1]; module_t *new = NULL; unsigned int hash; if (find_module(filename)) /* module deja chargé, rien a faire */ return 1; if (!(handle = dlopen(filename, RTLD_NOW|RTLD_GLOBAL))) { printf("load_module 2 %s (%s) %p\n", filename, dlerror(), handle); return 0; } dlerror(); /* clear olders errors */ func = dlsym(handle, "module_init"); if ((error = dlerror()) != NULL) { printf("load_module 3 %s\n", filename); dlclose(handle); return 0; } if (!func) return 0; if (!(new = calloc(1, sizeof(*new)))) { printf("load_module: malloc failed\n"); return 0; } hash = modhash(filename); strncpy(new->name, filename, FILELEN); new->handle = handle; printf("[+MODULE]: name=%s address=%p table location=%i\n", new->name, new, hash); new->next = modlist[hash]; modlist[hash] = new; func(); return 1; } module_t *find_module(const char *name) { module_t *mod = modlist[modhash(name)]; for (; mod && strcasecmp(name, mod->name); mod = mod->next); return mod; } void unload_module(module_t *mod) { char *error = NULL; void (*func) (void); func = dlsym(mod->handle, "module_end"); if ((error = dlerror()) != NULL && !func) { // erreur } else (*func)(); printf("[-MODULE]: name=%s address=%p table location=%i next=%s\n", mod->name, mod, modhash(mod->name), (mod->next) ? mod->next->name : "NULL"); dlclose(mod->handle); modlist[modhash(mod->name)] = mod->next; free(mod); } void close_modules(void) { unsigned int i = 0; for (; i < MODHASHSIZE; i++) { if (modlist[i]) { unload_module(modlist[i]); } } }
un module parmi d'autre:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 #include "command.h" static command_t *cmdtable[CMDHASHSIZE] = {0}; static unsigned int cmdhash(const char *str) { unsigned int hash = 0; while (*str) { hash += (hash << 3) + tolower((unsigned char)*str++); } return (hash & (CMDHASHSIZE - 1)); } static void add_cmdhash(command_t *cmd) { unsigned int hashv = cmdhash(cmd->name); cmd->next = cmdtable[hashv]; cmdtable[hashv] = cmd; } command_t *add_command(const char *name, unsigned int level, int (*handle) (connect_t *connect, int parc, char **parv)) { command_t *new = NULL; if (!name || !*name) return NULL; if (find_command(name)) return NULL; if ((new = calloc(1, sizeof(*new))) == NULL) return NULL; strncpy(new->name, name, COMLEN); new->level = level; new->handle = handle; add_cmdhash(new); printf("[+COMMAND]: name=%s address=%p table location=%i\n", new->name, new, cmdhash(new->name)); return new; } command_t *find_command(const char *name) { unsigned int hashv = cmdhash(name); command_t *cmd = cmdtable[hashv]; printf("[DEBUG] find_command(%s): cmdtable[%i]=%p\n", name, hashv, cmdtable[hashv]); for (; cmd && strcasecmp(name, cmd->name); cmd = cmd->next); return cmd; } void del_command(command_t *cmd) { unsigned int hashv = cmdhash(cmd->name); command_t *tmp = cmdtable[hashv]; if (tmp == cmd) cmdtable[hashv] = cmd->next; else { for (; tmp && tmp->next != cmd; tmp = tmp->next); if (tmp) tmp->next = cmd->next; } printf("[-COMMAND]: name=%s address=%p table location=%i next=%s\n", tmp->name, tmp, hashv, (tmp->next) ? tmp->next->name : "NULL"); free(cmd); }
et voici le résultat en console
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 #include "ircd.h" int cmd_nick(connect_t *, int, char **); void module_init(void) { add_command("NICK", 0, cmd_nick); } void module_end(void) { command_t *cmd = find_command("NICK"); if (cmd) del_command(cmd); } static int validnick(const char *nick) { return 1; } int cmd_nick(connect_t *connect, int parc, char **parv) { /* nouveau client entreprend son identification */ if (IsConnect(connect)) { if ((parc < 1) || !validnick(parv[0])) del_connect(connect); connect->type = TP_CLIENT; strncpy(connect->nick, parv[0], NICKLEN); printf("NICK merge: %s\n", connect->nick); } /* changement de pseudonyme */ else if (IsClient(connect)) { if (parc < 1) return send_numeric(connect, ERR_NONICKNAMEGIVEN, connect->nick); if (!strcasecmp(connect->nick, parv[0])) return 0; if (!validnick(parv[0])) return send_numeric(connect, ERR_ERRONEOUSNICKNAME, me->name, connect->nick, parv[0], "Pseudonyme erroné"); } return 0; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 blackbox@blackbox-PC ~/havoc-ircd $ ./ircd.exe [+MODULE]: name=/home/blackbox/havoc-ircd/src/commands/cmd_nick.so address=0x80040250 table location=11 [DEBUG] find_command(NICK): cmdtable[93]=0x0 /* ici la commande n'est pas encore créer mais je verifie qu'elle ne le soit pas déja */ [+COMMAND]: name=NICK address=0x80050300 table location=93 /* elle ne l'ete pas donc création ... */ [+CONNECTION] 192.168.1.39:64948 fd=4 highest_fd: 4 /* un client se connecte */ Traffic from fd=4 bytes=52 data=NICK newbie /* il envoi une requete de commande NICK, crée précédement */ [DEBUG] find_command(NICK): cmdtable[93]=0x0 /* je verifie que cette commande existe et bien non sa position dans le tableau NULL */ Traffic from fd=4 bytes=52 data=USER kvirc 0 192.168.1.39 :Lil Chapdo [DEBUG] find_command(USER): cmdtable[15]=0x0 received SIGINT/SIGTERM - closing link /* j'interromps le programme manuellement et decharge les modules */ accept: 11 Resource temporarily unavailable [DEBUG] find_command(NICK): cmdtable[93]=0x80050300 /* et la c'est le bug de l'an 2000 ? WTF ???? */ [-COMMAND]: name=NICK address=0x80050300 table location=93 next=NULL [-MODULE]: name=/home/blackbox/havoc-ircd/src/commands/cmd_nick.so address=0x80040250 table location=11 next=NULL closing: 4 closing: 3
Aucune erreur à la compilation, le programme s'execute correctement, les autres actions à réaliser après un chargement de module fonctionne (creation socket, ecoute du traffic, etc ...)
En gros entre l'appel à module_init et module_end mon tableau cmdtable est NULL.
Désolé du pavé que je viens de balancer, si jamais quelqu'un a envie de se ronger le cerveau avec moi je suis preneur, je tiens à préciser que je ne t'attend qu'on me serve la réponse sur un plateau je suis cloué sur le problème depuis déja presqu'un mois j'ai mangé le man de gcc, ld , dlopen et co, essayé des trucs plus ou moins censé d'autres pas du tout et la je séche totalement ...
Partager