"Fossies" - the Fresh Open Source Software Archive 
Member "dbg-2.15.5/dbg_cmd.c" (28 Apr 2007, 35310 Bytes) of package /linux/www/old/dbg-2.15.5.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "dbg_cmd.c" see the
Fossies "Dox" file reference documentation.
1 /***************************************************************************
2 dbg_cmd.c - description
3 -------------------
4 begin : Sun Sep 24 2000
5 copyright : (C) 2001 by Dmitri Dmitrienko
6 : (C) 2002, 2007 NuSphere Corp.
7 www : http://dd.cron.ru
8 : http://www.nusphere.com/
9 author : written by Dmitri Dmitrienko
10 license : This source file is subject to version 3.0 of
11 the License, that is bundled with this package
12 in the file LICENSE, and is available at through
13 the world-wide-web at http://www.nusphere.com/dbg
14 ***************************************************************************/
15
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include "php.h"
22 #include "php_network.h"
23
24 #if HAVE_NETDB_H
25 #include <netdb.h>
26 #endif
27
28 #include "php_dbg.h"
29 #include "dbg_net.h"
30 #include "dbg_cmd.h"
31 #include "dbg_prof.h"
32 #include "dbg_ser.h"
33 #include "dbg_bp.h"
34 #include "SAPI.h"
35
36
37
38 typedef int (*framehandler)(dbg_packet *pack, dbg_packet *inpack, dbg_frame *frame TSRMLS_DC2(DBG, E));
39
40 typedef struct tag_cmddef {
41 framename name;
42 framehandler handler;
43 } cmddef;
44
45 int cmpll(void *element1, void *element2) {
46 return (element1 == element2);
47 }
48
49 int dbg_lookup_hostname(const char *addr, struct in_addr *in) {
50 struct hostent *host_info;
51
52 DBG_TRACE(("dbg_lookup_hostname\n"));
53 #ifdef PHP_WIN32
54 (*in).s_addr = inet_addr(addr);
55 if ((*in).s_addr == INADDR_NONE) {
56 #else
57 if (!inet_aton(addr, in)) {
58 #endif
59 host_info = gethostbyname(addr);
60 if (!host_info) {
61 return FAILURE;
62 }
63 *in = *((struct in_addr *) host_info->h_addr);
64 }
65 return SUCCESS;
66 }
67
68 char* get_redirected_address(TSRMLS_D2(DBG, E)) {
69 int rv;
70 zval **httpvars, **remoteaddr, **forwardedfor;
71 char *p, *ret_val = NULL;
72
73 DBG_TRACE(("get_redirected_address\n"));
74 rv = zend_hash_find(&EG(symbol_table), "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS"), (void **) &httpvars);
75 if (rv != FAILURE && ((*httpvars)->type==IS_ARRAY)) {
76 rv = zend_hash_find((*httpvars)->value.ht, "HTTP_X_FORWARDED_FOR", sizeof("HTTP_X_FORWARDED_FOR"), (void **) &forwardedfor);
77 if (rv != FAILURE && ((*forwardedfor)->type==IS_STRING) && (*forwardedfor)->value.str.len > 0) {
78 p = strchr(Z_STRVAL_P(*forwardedfor), ',');
79 if (p == NULL) {
80 ret_val = estrndup(Z_STRVAL_P(*forwardedfor),Z_STRLEN_P(*forwardedfor));
81 } else {
82 ret_val = estrndup(Z_STRVAL_P(*forwardedfor),p-Z_STRVAL_P(*forwardedfor));
83 }
84 } else {
85 rv = zend_hash_find((*httpvars)->value.ht, "REMOTE_ADDR", sizeof("REMOTE_ADDR"), (void **) &remoteaddr);
86 if (rv != FAILURE && ((*remoteaddr)->type==IS_STRING)) {
87 ret_val = estrndup(Z_STRVAL_P(*remoteaddr),Z_STRLEN_P(*remoteaddr));
88 }
89 }
90 }
91 return ret_val;
92 }
93
94 /*
95 * Connects to a specified host and port, and returns a socket for the connection.
96 */
97
98 int create_debugger_socket(SESSTYPE sesstype TSRMLS_DC2(DBG, E)) {
99 struct sockaddr_in address;
100 int err=-1;
101 int sockfd;
102 int ret_val;
103
104 DBG_TRACE(("create_debugger_socket(%d)\n", sesstype));
105 memset(&address, 0, sizeof(address));
106 address.sin_family = AF_INET;
107
108 if (DBG(client_address)) {
109 efree(DBG(client_address));
110 DBG(client_address) = NULL;
111 }
112
113 DBG(client_address) = (DBGF(DBGF_REQUESTFOUND)) ? (DBG(req_client_ip_address)) : (DBG(cfgprm_JIT_host));
114 if (!DBG(client_address)) DBG(client_address) = CLIENT_HOST;
115 DBG(client_address) = estrdup(DBG(client_address));
116
117 if (DBG(client_address) && stricmp(DBG(client_address), CLIENT_HOST) == 0) {
118 efree(DBG(client_address));
119 DBG(client_address) = get_redirected_address(TSRMLS_C2(DBG, E));
120 if (!DBG(client_address)) {
121 DBG(client_address) = estrdup("localhost");
122 }
123 }
124
125 DBG_TRACE(("address(%s)\n", SON(DBG(client_address))));
126
127 if (!DBG(client_address) || dbg_lookup_hostname(DBG(client_address), &address.sin_addr) == FAILURE) {
128 if (!DBG(cfgprm_fail_silently)) {
129 SysError("dbg_lookup() failed (address=\"%s\")\n", DBG(client_address));
130 }
131 return ESESS_LOOKUP;
132 }
133
134 DBG(client_port) = (DBGF(DBGF_REQUESTFOUND)) ? (DBG(req_client_port)) : (DBG(cfgprm_JIT_port));
135 if (DBG(client_port) == 0) DBG(client_port) = DEFAULT_PORT;
136 address.sin_port = htons((unsigned short)DBG(client_port));
137
138
139 DBG_TRACE(("conn. allowed to %s:%ld\n", SON(DBG(client_address)), DBG(client_port)));
140
141
142 sockfd = socket(AF_INET, SOCK_STREAM, 0);
143 ret_val = sockfd;
144 if (sockfd == SOCK_ERR) {
145 if (!DBG(cfgprm_fail_silently)) {
146 SysError("socket() failed\n");
147 }
148 ret_val = ESESS_SOCK;
149 } else {
150 while ((err = connect(sockfd, (struct sockaddr *) &address,
151 sizeof(address))) == SOCK_ERR && errno == EAGAIN);
152 if (err < 0) {
153 if (!DBG(cfgprm_fail_silently)) {
154 SysError("connect() failed\n");
155 }
156 SCLOSE(sockfd);
157 ret_val = ESESS_CONN;
158 } else {
159 DBG_TRACE(("socket (%d) opened\n", sockfd));
160 }
161 }
162 return ret_val;
163 }
164
165
166 /* ************************************************* */
167
168 inline int dbg_mod_item_by_name(const char *mod_name, int addifnotfound TSRMLS_DC1(DBG)) {
169 mod_item* p_mod = dbg_findmodule(mod_name, addifnotfound TSRMLS_CC1(DBG));
170 return (p_mod) ? (p_mod->mod_no) : (0);
171 }
172
173 inline mod_item* dbg_mod_item_by_no(int mod_no TSRMLS_DC1(DBG)) {
174 if (mod_no != 0 && DBG(curr_mod) && DBG(curr_mod)->mod_no==mod_no)
175 return DBG(curr_mod);
176 LLIST_FOREACH(DBG(mod_list), mod_item,
177 if (data->mod_no == mod_no) {
178 return data;
179 }
180 );
181 return NULL;
182 }
183
184 inline char *dbg_mod_name_by_no(int mod_no TSRMLS_DC1(DBG)) {
185 mod_item *src_item;
186 src_item = dbg_mod_item_by_no(mod_no TSRMLS_CC1(DBG));
187 return (src_item) ? (src_item->mod_name) : NULL;
188 }
189
190 inline int MATCHFILE(const char *name1, const char *name2 TSRMLS_DC1(DBG)) {
191 if (DBGO(SOF_MATCHFILESINLOWCASE))
192 return (stricmp(name1,name2)==0);
193 else
194 return (strcmp(name1,name2)==0);
195 }
196
197 inline mod_item* dbg_findmodule(const char *mod_name, int addifnotfound TSRMLS_DC1(DBG)) {
198 int idx;
199 mod_item newitem, *p_mod;
200
201 if (mod_name == DBG(curr_mod_name)) {
202 return DBG(curr_mod);
203 }
204 if (!mod_name)
205 return NULL;
206
207 idx = 1;
208 LLIST_FOREACH(DBG(mod_list), mod_item, {
209 if (MATCHFILE(mod_name, data->mod_name TSRMLS_CC1(DBG))) {
210 return data;
211 }
212 idx++;
213 });
214
215 if (!addifnotfound) return NULL;
216
217 memset(&newitem, 0, sizeof(newitem));
218 newitem.mod_no = idx;
219 newitem.mod_name = estrdup(mod_name);
220 newitem.rsrv1 = 0;
221 zend_llist_add_element(&DBG(mod_list), &newitem);
222 p_mod = dbg_mod_item_by_no(newitem.mod_no TSRMLS_CC1(DBG));
223 return p_mod;
224 }
225
226 /******** R E P L Y **********/
227
228 int handler_add_source_reply(dbg_packet *pack, dbg_packet *inpack, dbg_frame *frame TSRMLS_DC2(DBG, E)) {
229 char *fn;
230 FILE *f = NULL;
231 dbg_source_body body;
232 #if ZEND_EXTENSION_API_NO < 20020903
233 int issock = 0, socketd = 0;
234 #endif
235 int ret_val, mod_no, rest_size;
236 int error = 0, from_pos = -1, full_size = -1, bufsize = 128*1024;
237 void *buf = NULL;
238 char ok=0, *mod_name;
239
240 dbg_source_request *req = FRAME_DATA_PTR(dbg_source_request,frame);
241
242 mod_no = req->mod_no;
243 from_pos = req->from_filepos;
244
245 if (from_pos >= 0) {
246 error = -2; /* file open error */
247 fn = dbg_mod_name_by_no(mod_no TSRMLS_CC1(DBG));
248 if (fn && *fn!='-') {
249 f = fopen(fn, "rb");
250 if (!f) {
251 #if ZEND_EXTENSION_API_NO < 20020903
252 f = php_fopen_wrapper(fn, "rb", USE_PATH|IGNORE_URL_WIN, &issock, &socketd, NULL TSRMLS_CC0);
253 #else
254 f = php_stream_open_wrapper_as_file(fn, "rb", USE_PATH|IGNORE_URL_WIN, NULL);
255 #endif
256 }
257 }
258 ok = (f!=NULL);
259 if (ok) {
260 ret_val = fseek(f, 0, SEEK_END);
261 ok = (ret_val == 0);
262 if (!ok){
263 error = ferror(f); /* seek error */
264 }
265 }
266 if (ok) {
267 full_size = ftell(f);
268 ret_val = fseek(f, from_pos, SEEK_SET);
269 ok = (ret_val == 0);
270 if (!ok){
271 error = ferror(f); /* seek error */
272 }
273 }
274 if (ok) {
275 rest_size = full_size - from_pos;
276 bufsize = (rest_size > bufsize) ? bufsize:rest_size;
277 buf = emalloc(bufsize);
278 ok = (buf != NULL);
279 if (!ok){
280 error = -3; /*No memory for buffer*/
281 }
282 }
283 if (ok) {
284 ret_val = fread(buf, 1, bufsize, f);
285 ok = (ret_val == bufsize) || feof(f);
286 if (!ok){
287 error = ferror(f); /* read error */
288 }
289 bufsize = ret_val;
290 }
291 }
292
293 if (!ok){
294 bufsize = 0;
295 }
296
297
298 mod_name = (from_pos <= 0) ? dbg_mod_name_by_no(mod_no TSRMLS_CC1(DBG)) : NULL;
299 body.imod_name = (mod_name) ? dbg_packet_add_string(pack, mod_name) : 0;
300 body.itext = (from_pos >= 0 && buf) ? dbg_packet_add_rawdata(pack, buf, bufsize) : 0;
301 body.error = error;
302 body.mod_no = mod_no;
303 body.from_filepos = from_pos;
304 body.full_size = full_size;
305
306 dbg_packet_add_frame(pack, FRAME_SOURCE, &body, sizeof(body));
307
308 if (buf) {
309 efree(buf);
310 }
311 if (f) {
312 fclose(f);
313 }
314 return bufsize;
315 }
316
317 int handler_add_stack_reply(dbg_packet *pack, dbg_packet *inpack, dbg_frame *frame TSRMLS_DC2(DBG, E)) {
318 dbg_stack_body stk;
319 char *mod_name, *func_name;
320 int depth;
321 int line_no, mod_no;
322 int sz = 0;
323 char descr[256];
324
325 if (DBG(deactivate_inprocess)) return 1;
326
327 /*current location*/
328 if (zend_is_executing(TSRMLS_C0)) {
329 mod_name = zend_get_executed_filename(TSRMLS_C1(E));
330 line_no = zend_get_executed_lineno(TSRMLS_C1(E));
331 func_name = get_active_function_name(TSRMLS_C0);
332 } else if (zend_is_compiling(TSRMLS_C0)) {
333 TSRMLS_FETCH1_NOP(C);
334 mod_name = zend_get_compiled_filename(TSRMLS_C1(C));
335 line_no = zend_get_compiled_lineno(TSRMLS_C1(C));
336 func_name = NULL;
337 }
338 else {
339 mod_name = DBG(curr_mod_name);
340 line_no = DBG(curr_line_no);
341 func_name = NULL;
342 }
343
344 mod_no = DBG_FINDMODULE_ADD(mod_name);
345 depth = CURLOC_SCOPE_ID;
346 stk.mod_no = mod_no;
347 stk.line_no = line_no;
348 stk.scope_id = CURLOC_SCOPE_ID;
349
350 if (func_name!=NULL && stricmp(func_name,"main") != 0) {
351 snprintf(descr, sizeof(descr)-1, "%s()", func_name);
352 } else if (mod_name!=NULL) {
353 snprintf(descr, sizeof(descr)-1, "%s::main()", mod_name);
354 } else {
355 descr[0]='\0';
356 }
357 stk.idescr = dbg_packet_add_string(pack, descr);
358
359 dbg_packet_add_frame(pack, FRAME_STACK, &stk, sizeof(stk));
360 sz = sizeof(stk);
361
362 depth = DBG(back_trace_count);
363
364 /*stacked location(s)*/
365 LLIST_RFOREACH(DBG(back_trace), back_trace_item,
366 depth--;
367 stk.line_no = data->line_no;
368 stk.mod_no = data->mod_no;
369 stk.idescr = dbg_packet_add_string(pack, data->descr);
370 stk.scope_id = INC_SCOPEID(depth);
371 dbg_packet_add_frame(pack, FRAME_STACK, &stk, sizeof(stk));
372 sz+=sizeof(stk);
373 );
374
375 return sz;
376 }
377
378 int handler_add_mod_list_reply(dbg_packet *pack, dbg_packet *inpack, dbg_frame *frame TSRMLS_DC2(DBG, E)) {
379 dbg_src_tree_body body;
380 int idx = 1;
381
382 LLIST_FOREACH(DBG(mod_list), mod_item,
383 body.mod_no = idx;
384 body.rsrv1 = 0;
385 body.rsrv2 = 0;
386 body.imod_name = dbg_packet_add_string(pack, data->mod_name);
387 dbg_packet_add_frame(pack, FRAME_SRC_TREE, &body, sizeof(body));
388 idx++;
389 );
390 return ((idx-1) * sizeof(body));
391 }
392
393 int handler_add_bpl_reply(dbg_packet *pack, dbg_packet *inpack, dbg_frame *frame TSRMLS_DC2(DBG, E)) {
394 int cnt = 0;
395 dbg_bpl_request *req = FRAME_DATA_PTR(dbg_bpl_request, frame);
396
397 LLIST_FOREACH(DBG(breakpoint_list), bp_item, {
398 if (req->bp_no == 0 || data->bp_no == req->bp_no) {
399 cnt+=listout_bp_item(pack, data, data->bp_no);
400 }
401 });
402 return (cnt);
403 }
404
405 int handler_set_breakpoint(dbg_packet *pack, dbg_packet *inpack, dbg_frame *frame TSRMLS_DC2(DBG, E)) {
406 dbg_bps_request* req = FRAME_DATA_PTR(dbg_bps_request, frame);
407 return dbg_set_breakpoint(req, pack, inpack TSRMLS_CC2(DBG, E));
408 }
409
410 int handler_add_srclinesinfo_reply(dbg_packet *pack, dbg_packet *inpack, dbg_frame *frame TSRMLS_DC2(DBG, E)) {
411 dbg_srclinesinfo_request *req = FRAME_DATA_PTR(dbg_srclinesinfo_request, frame);
412 int mod_no = req->mod_no;
413 dbg_srclinesinfo_body body;
414 int cnt=0;
415
416 LLIST_FOREACH(DBG(ctxlines_list), ctxlines_item,
417 if (mod_no==0 || mod_no == data->mod_no) {
418 body.ctx_id = data->ctx_id;
419 body.mod_no = data->mod_no;
420 body.lines_count = data->lines_cnt;
421 body.start_line_no = data->start_line_no;
422 dbg_packet_add_frame(pack, FRAME_SRCLINESINFO, &body, sizeof(body));
423 cnt++;
424 }
425 );
426 return (cnt * sizeof(body));
427 }
428
429 int handler_add_srcctxinfo_reply(dbg_packet *pack, dbg_packet *inpack, dbg_frame *frame TSRMLS_DC2(DBG, E)) {
430 dbg_srcctxinfo_body body;
431 int cnt=0, imod_no;
432 dbg_srcctxinfo_request *req = FRAME_DATA_PTR(dbg_srcctxinfo_request, frame);
433 int mod_no = req->mod_no;
434
435 body.mod_no = mod_no;
436 LLIST_FOREACH(DBG(ctx_list), ctx_item,
437 imod_no = DBG_FINDMODULE(data->mod_name);
438 if (mod_no==0 || mod_no == imod_no) {
439 body.ctx_id = data->ctx_id;
440 body.mod_no = imod_no;
441 body.ifunction_name = dbg_packet_add_string(pack, data->function_name);
442 dbg_packet_add_frame(pack, FRAME_SRCCTXINFO, &body, sizeof(body));
443 cnt++;
444 }
445 );
446 return (cnt * sizeof(body));
447 }
448
449 int handler_add_profdata_reply(dbg_packet *pack, dbg_packet *inpack, dbg_frame *frame TSRMLS_DC2(DBG, E)) {
450 dbg_prof_body body;
451 profdata_item *it;
452 int i, cnt=0;
453 dbg_prof_request *req = FRAME_DATA_PTR(dbg_prof_request, frame);
454 int mod_no = req->mod_no;
455
456 LLIST_FOREACH(DBG(mod_list), mod_item,
457 if (data->mod_no == mod_no || mod_no==0) {
458 body.mod_no = data->mod_no;
459 for (i=0; i< data->profdata_items-1; i++) {
460 it=&(data->profdata_arr[i]);
461 if (it->hitcount > 0) {
462 body.hit_count = it->hitcount;
463 body.line_no = i;
464 body.tm_max_hi = (long)(it->tm_max >> 32);
465 body.tm_max_lo = (long)(it->tm_max & 0xFFFFFFFF);
466 body.tm_min_hi = (long)(it->tm_min >> 32);
467 body.tm_min_lo = (long)(it->tm_min & 0xFFFFFFFF);
468 body.tm_sum_hi = (long)(it->tm_sum >> 32);
469 body.tm_sum_lo = (long)(it->tm_sum & 0xFFFFFFFF);
470 dbg_packet_add_frame(pack, FRAME_PROF, &body, sizeof(body));
471 cnt++;
472 }
473 }
474 }
475 );
476 return 1;
477 }
478
479 int handler_add_proffreq_reply(dbg_packet *pack, dbg_packet *inpack, dbg_frame *frame TSRMLS_DC2(DBG, E)) {
480 dbg_prof_c_body body;
481 dbgint64 f;
482 dbgint64 v, sum1=0, sum2=0, mv, cnt1=0, cnt2=0, minv, maxv;
483 int i, loopc;
484 dbg_prof_c_request *req = FRAME_DATA_PTR(dbg_prof_c_request, frame);
485
486 PROF_PERF_FREQ(f);
487 body.tm_freq_lo = (unsigned dbgint)(f & 0xFFFFFFFF);
488 body.tm_freq_hi = (unsigned dbgint)(f >> 32);
489
490 loopc = req->test_loops;
491 if (loopc<2) loopc = 2;
492 minv = 0;
493 maxv = 0;
494 for (i=0; i<loopc/2; i++) {
495 PROF_DOUBLE_SNAP(v);
496 if (i==0) {
497 minv=v;
498 maxv=v;
499 } else {
500 if (v<minv) minv=v;
501 if (v>maxv) maxv=v;
502 }
503 sum1 +=v;
504 cnt1++;
505 }
506 mv=sum1/cnt1;
507 for (i = 0; i < loopc/2; i++) {
508 PROF_DOUBLE_SNAP(v);
509 if (v<minv) minv=v;
510 if (v>maxv) maxv=v;
511 if (v <= 3*mv) {
512 sum2 +=v;
513 cnt2++;
514 }
515 }
516 mv=sum2/cnt2;
517 if (maxv > MAXINT32T) maxv = MAXINT32T;
518 if (minv > MAXINT32T) minv = MAXINT32T;
519 if (mv > MAXINT32T) mv = MAXINT32T;
520 body.tm_diff_max = (long)maxv;
521 body.tm_diff_min = (long)minv;
522 body.tm_diff_m = (long)mv;
523 dbg_packet_add_frame(pack, FRAME_PROF_C, &body, sizeof(body));
524 return 1;
525 }
526
527 int dbg_add_version_reply(dbg_packet *pack TSRMLS_DC1(DBG)) {
528 dbg_version_body body;
529
530 body.idescription = dbg_packet_add_string(pack, DBG_API_DESCRIPTION);
531 body.major_version = DBG_API_MAJOR_VERSION;
532 body.minor_version = DBG_API_MINOR_VERSION;
533 dbg_packet_add_frame(pack, FRAME_VER, &body, sizeof(body));
534 return sizeof(body);
535 }
536
537 int handler_add_sid_reply(dbg_packet *pack, dbg_packet *inpack, dbg_frame *frame TSRMLS_DC2(DBG, E)) {
538 dbg_sid_body body;
539
540 body.isid = dbg_packet_add_string(pack, DBG(session_id));
541 body.sesstype = DBG(sesstype);
542 dbg_packet_add_frame(pack, FRAME_SID, &body, sizeof(body));
543 return sizeof(body);
544 }
545
546 int handler_add_ver_reply(dbg_packet *pack, dbg_packet *inpack, dbg_frame *frame TSRMLS_DC2(DBG, E)) {
547 dbg_version_body *client_ver = FRAME_DATA_PTR(dbg_version_body, frame);
548
549 DBG(clientversion) = ((client_ver->major_version & 0xFF) << 8) | (client_ver->minor_version & 0xFF);
550 dbg_add_version_reply(pack TSRMLS_CC1(DBG));
551 return (sizeof(dbg_version_body));
552 }
553
554
555 /* E V A L E F F O R T */
556
557
558 static void dbg_get_context_sym_table(long scope_id, HashTable **ht, zval **zthis TSRMLS_DC2(DBG, E)) {
559 back_trace_item *bt_item;
560 int depth;
561 int scope_count;
562
563 if (scope_id == CURLOC_SCOPE_ID) {
564 *ht = EG(active_symbol_table);
565 *zthis = EG_THIS;
566 return;
567 }
568 else {
569 scope_count = DBG(back_trace_count);
570 if (scope_id == GLOBAL_SCOPE_ID) {
571 depth = 0;
572 if (scope_count == 0) {
573 *ht = EG(active_symbol_table);
574 *zthis = EG_THIS;
575 return;
576 }
577 }
578 else {
579 depth = DEC_SCOPEID(scope_id);
580 }
581
582 if (depth >= 0 && depth < scope_count) {
583 LLIST_ITEM_AT(DBG(back_trace), depth, bt_item, back_trace_item*);
584 *ht = bt_item->active_sym_table;
585 *zthis = bt_item->active_this;
586 return;
587 }
588 }
589 *ht = NULL;
590 *zthis = NULL;
591 return;
592 }
593
594 void dbg_full_eval(char *str, HashTable *active_sym_table, zval *buf) {
595 HashTable *ast;
596 zval data;
597 TSRMLS_FETCH3(DBG, E, C);
598
599 ast = EG(active_symbol_table);
600 EG(active_symbol_table) = active_sym_table;
601
602 memset(&data, 0, sizeof(data));
603 Z_TYPE_P(&data) = IS_STRING;
604 data.refcount++;
605
606 if (DBG(eval_error)) {
607 efree(DBG(eval_error));
608 DBG(eval_error) = NULL;
609 }
610
611 if (zend_eval_string(str, &data, "dbg_eval()" TSRMLS_CC2(C, E)) == SUCCESS && !DBG(eval_error)) {
612 dbg_serialize_zval(&data, buf, 0 TSRMLS_CC2(DBG, E));
613 }
614 if (data.value.str.val) zval_dtor(&data);
615 EG(active_symbol_table) = ast;
616 }
617
618 int handler_add_eval_reply(dbg_packet *pack, dbg_packet *inpack, dbg_frame *frame TSRMLS_DC2(DBG, E)) {
619 char *str = NULL;
620 int sz = 0, ret_val = 0;
621 HashTable *active_sym_table = NULL;
622 zval **data;
623 zval buf;
624 zval *active_this;
625 dbg_eval_body body;
626 dbg_eval_request *req = FRAME_DATA_PTR(dbg_eval_request, frame);
627
628 memset(&buf, 0, sizeof(buf));
629 Z_TYPE_P(&buf) = IS_STRING;
630 buf.refcount++;
631
632 if (req->istr!=0 && (!dbg_packet_findstring(inpack, req->istr, &str, &sz) || sz<=0)) return 0;
633 if (str && strlen(str)==0) str = NULL;
634
635
636 DBG(in_eval)++;
637 {
638 DBG_CTX_SAVE
639 DBG_CTX_TRY {
640 if (DBG(eval_error)) {
641 efree(DBG(eval_error));
642 DBG(eval_error) = NULL;
643 }
644 dbg_get_context_sym_table(req->scope_id, &active_sym_table, &active_this TSRMLS_CC2(DBG, E));
645 if (active_sym_table) {
646 if (!str) {
647 dbg_serialize_hash(active_sym_table, active_this, &buf, DSER_ADD_DSIGN TSRMLS_CC2(DBG, E));
648 }
649 else if (str &&
650 sz > 1 &&
651 str[0]=='$' &&
652 zend_hash_find(active_sym_table, &str[1], sz-1, (void **) &data) == SUCCESS) {
653 dbg_serialize_zval(*data, &buf, 0 TSRMLS_CC2(DBG, E));
654 }
655 else if (str && strcmp(str,"$GLOBALS")==0) {
656 dbg_get_context_sym_table(GLOBAL_SCOPE_ID, &active_sym_table, &active_this TSRMLS_CC2(DBG, E));
657 dbg_serialize_hash(active_sym_table, active_this, &buf, DSER_ADD_DSIGN TSRMLS_CC2(DBG, E));
658 }
659 else {
660 dbg_full_eval(str, active_sym_table, &buf);
661 }
662 }
663
664 } DBG_CTX_CATCH {
665 DBG_TRACE(("eval: zend_catch\n"));
666 DBG_TRACE(("dbg_full_eval(!)<<\n"));
667 if (buf.value.str.val)
668 zval_dtor(&buf);
669 memset(&buf, 0, sizeof(buf));
670 DBG_CTX_RESTORE
671 } DBG_CTX_ENDTRY
672 }
673
674 DBG(in_eval)--;
675
676 ret_val = buf.value.str.len;
677 body.iresult = dbg_packet_add_rawdata(pack, Z_STRVAL(buf), Z_STRLEN(buf)+1);
678 body.istr = str ? dbg_packet_add_string(pack, str) : 0;
679 body.ierror = DBG(eval_error) ? dbg_packet_add_string(pack, DBG(eval_error)) : 0;
680 dbg_packet_add_frame(pack, FRAME_EVAL, &body, sizeof(body));
681 if (DBG(eval_error)) {
682 efree(DBG(eval_error));
683 DBG(eval_error) = NULL;
684 }
685 if (buf.value.str.val) zval_dtor(&buf);
686 return ret_val;
687 }
688
689 int handler_set_options(dbg_packet *pack, dbg_packet *inpack, dbg_frame *frame TSRMLS_DC2(DBG, E)) {
690 dbg_set_options_request *req = FRAME_DATA_PTR(dbg_set_options_request, frame);
691 DBG(opt_flags) = req->opt_flags;
692 switch ((req->opt_flags & SOF_ERR_LEVEL_MASK) >> SOF_ERR_LEVEL_SHIFT) {
693 case 0:
694 DBG(error_filter) = ERR_LEVEL0_MASK;
695 break;
696 case 1:
697 DBG(error_filter) = ERR_LEVEL1_MASK;
698 break;
699 case 2:
700 DBG(error_filter) = ERR_LEVEL2_MASK;
701 break;
702 case 4:
703 DBG(error_filter) = ERR_LEVEL4_MASK;
704 break;
705 default:
706 DBG(error_filter) = ERR_LEVEL3_MASK;
707 break;
708 }
709 return 1;
710 }
711
712 /* H A N D L E R E Q U E S T ( S ) */
713
714 cmddef cmdlist[] = {
715 {FRAME_STACK, handler_add_stack_reply},
716 {FRAME_SRC_TREE, handler_add_mod_list_reply},
717 {FRAME_EVAL, handler_add_eval_reply},
718 {FRAME_BPL, handler_add_bpl_reply},
719 {FRAME_BPS, handler_set_breakpoint},
720 {FRAME_SRCLINESINFO, handler_add_srclinesinfo_reply},
721 {FRAME_SRCCTXINFO, handler_add_srcctxinfo_reply},
722 {FRAME_PROF, handler_add_profdata_reply},
723 {FRAME_PROF_C, handler_add_proffreq_reply},
724 {FRAME_SID, handler_add_sid_reply},
725 {FRAME_VER, handler_add_ver_reply},
726 {FRAME_SET_OPT, handler_set_options},
727 {FRAME_SOURCE, handler_add_source_reply},
728 {0, NULL}
729 };
730
731
732 void dbg_handle_request(dbg_header_struct *hdr, dbg_packet *inpack TSRMLS_DC2(DBG, E)) {
733 dbg_frame *p;
734 dbg_packet outpack;
735 cmddef *pcmd;
736
737 if (!hdr->flags & DBGF_WAITACK) return;
738
739 dbg_packet_new(&outpack);
740
741 p = dbg_packet_firstframe(inpack);
742 while (p){
743 DBG_TRACE(("request %ld\n",p->name));
744 pcmd = cmdlist;
745 while (pcmd->name != 0) {
746 if (pcmd->name == p->name) {
747 pcmd->handler(&outpack, inpack, p TSRMLS_CC2(DBG, E));
748 break;
749 }
750 pcmd++;
751 }
752 p = dbg_packet_nextframe(inpack,p);
753 }
754
755 dbg_packet_send(DBGC_REPLY, &outpack, DBG(debug_socket), DBG(debugger_flags));
756 dbg_packet_free(&outpack);
757 }
758
759
760 /* debugger host may ask to provide some information (DBGA_REQUEST)
761 or urge to continue run (DBGA_xxxx) */
762 /* main way from the Listener to the DBG module */
763
764 void dbg_process_ack(dbg_header_struct *hdr, dbg_packet *pack TSRMLS_DC2(DBG, E)) {
765
766 DBG_TRACE(("ack %d\n",hdr->cmd));
767 switch (hdr->cmd) {
768 case DBGC_PAUSE: /* ignore */
769 break;
770 case DBGA_CONTINUE:
771 DBG(debugger_flags)&=~DBGF_WAITACK;
772 break;
773 case DBGA_STOP:
774 DBG(debugger_flags)&=~DBGF_WAITACK;
775 DBG(debugger_flags) |= DBGF_ABORT;
776 zend_bailout();
777 break;
778 case DBGA_STEPINTO:
779 DBG(debugger_flags) |= DBGF_STEPINTO;
780 DBG(debugger_flags) &= ~DBGF_WAITACK;
781 DBG(debugger_step_depth) = DBG(back_trace_count);
782 break;
783 case DBGA_STEPOVER:
784 DBG(debugger_flags) |= DBGF_STEPOVER;
785 DBG(debugger_flags) &= ~DBGF_WAITACK;
786 DBG(debugger_step_depth) = DBG(back_trace_count);
787 break;
788 case DBGA_STEPOUT:
789 DBG(debugger_flags) |= DBGF_STEPOUT;
790 DBG(debugger_flags) &= ~DBGF_WAITACK;
791 DBG(debugger_step_depth) = DBG(back_trace_count);
792 break;
793 case DBGA_REQUEST:
794 dbg_handle_request(hdr, pack TSRMLS_CC2(DBG, E));
795 break;
796 default:
797 DBG(debugger_flags)&=~DBGF_WAITACK;
798 if (hdr->flags & DBGF_WAITACK) {
799 dbg_packet_send(DBGC_REPLY, NULL, DBG(debug_socket), DBG(debugger_flags));
800 }
801 }
802 }
803
804 /* waiting and looking for debugger host responce */
805 inline void dbg_ack_loop(TSRMLS_D2(DBG, E)) {
806 int ret_val = 0, wcnt = 0;
807 dbg_header_struct hdr;
808 dbg_packet pack;
809
810 if (!dbg_packet_new(&pack)) {
811 DBG(debugger_flags)&=~DBGF_WAITACK;
812 return;
813 }
814
815 dbg_mark_del_temp_breakpoints(TSRMLS_C1(DBG));
816
817 zend_unset_timeout(TSRMLS_C0);
818 while (DBGF(DBGF_WAITACK)) {
819 dbg_packet_clear(&pack);
820 ret_val = dbg_packet_recv(&hdr, &pack, DBG(debug_socket), DBG(cfgprm_timeout_seconds) * 1000);
821 if (ret_val == 0) continue; /* socket is not closed, but we haven't data received, so continue wait */
822 if (ret_val < 0) break; /*socket just closed*/
823 dbg_process_ack(&hdr,&pack TSRMLS_CC2(DBG, E));
824 if (DBG(breakpoint_list_inv)) {
825 dbg_rebuild_bplist(TSRMLS_C1(DBG));
826 }
827 }
828
829 zend_set_timeout(EG(timeout_seconds));
830
831 dbg_packet_free(&pack);
832 if (ret_val < 0) {
833 DBG(debugger_flags)|=DBGF_UNSYNC;
834 DBG_TRACE(("session dropped. Closing socket(%d)\n", DBG(debug_socket)));
835 SCLOSE(DBG(debug_socket));
836 DBG(debug_socket) = ret_val;
837 }
838 DBG(debugger_flags)&=~DBGF_WAITACK;
839 dbg_flush_log(TSRMLS_C2(DBG, E));
840 }
841
842
843 /* inform the debugger host that it is debugging event has been fired */
844 inline int dbg_send_command(int cmd, dbg_packet *pack, char bWaitAck TSRMLS_DC2(DBG, E)) {
845 int ret_val;
846
847 if (DBG(debug_socket) <= 0 || DBG(is_failed_connection)) return 0;
848 if (DBGF(DBGF_WAITACK)) return 0; /*something wrong, go out*/
849
850 if (!DBGF(DBGF_UNSYNC) && bWaitAck) {
851 DBG(debugger_flags)|=DBGF_WAITACK;
852 }
853
854 zend_unset_timeout(TSRMLS_C0);
855 ret_val = dbg_packet_send(cmd, pack, DBG(debug_socket), DBG(debugger_flags));
856 zend_set_timeout(EG(timeout_seconds));
857
858 if (bWaitAck) {
859 DBG(debugger_flags) &= ~(DBGF_STEPINTO | DBGF_STEPOVER | DBGF_STEPOUT);
860 if (ret_val <= 0) {
861 DBG(debugger_flags)|=DBGF_UNSYNC;
862 DBG(debugger_flags)&=~DBGF_WAITACK;
863 return 0;
864 }
865 /* wait for debugger host responce. */
866 if (DBGF(DBGF_WAITACK)) {
867 dbg_ack_loop(TSRMLS_C2(DBG, E));
868 }
869 } else {
870 if (ret_val <= 0) {
871 DBG(debugger_flags)|=DBGF_UNSYNC;
872 return 0;
873 }
874 }
875 return ret_val;
876 }
877
878 /* send an event such as startup/breakpoint to the debugger host */
879 inline int dbg_send_std_action(int cmd, int hitcnt TSRMLS_DC2(DBG, E)) {
880 dbg_packet pack;
881 int ret_val;
882
883 if (cmd != DBGC_STARTUP) dbg_flush_log(TSRMLS_C2(DBG, E));
884
885 if (!dbg_packet_new(&pack)) return 0;
886
887 ret_val = handler_add_stack_reply(&pack, NULL, NULL TSRMLS_CC2(DBG, E));
888 if (cmd == DBGC_STARTUP && ret_val)
889 ret_val = dbg_add_version_reply(&pack TSRMLS_CC1(DBG));
890
891 if (ret_val) {
892 dbg_add_bp_reply(&pack TSRMLS_CC1(DBG));
893 ret_val = dbg_send_command(cmd, &pack, 1 TSRMLS_CC2(DBG, E));
894 }
895
896 dbg_packet_free(&pack);
897
898 dbg_reset_bp_isunderhit(TSRMLS_C1(DBG));
899 return ret_val;
900 }
901
902 inline int dbg_send_error(char *message, int type, const char *mod_name, int line_no TSRMLS_DC2(DBG, E)) {
903 dbg_packet pack;
904 dbg_error_body body;
905 int ret_val = 0;
906
907
908 dbg_flush_log(TSRMLS_C2(DBG, E));
909
910 if (!dbg_packet_new(&pack)) return 0;
911 body.imessage = dbg_packet_add_string(&pack, message);
912 body.type = type;
913 if (dbg_packet_add_frame(&pack, FRAME_ERROR, &body, sizeof(body)) &&
914 handler_add_stack_reply(&pack, NULL, NULL TSRMLS_CC2(DBG, E))) {
915 ret_val = dbg_send_command(DBGC_ERROR, &pack, 1 TSRMLS_CC2(DBG, E));
916 }
917 dbg_packet_free(&pack);
918 return ret_val;
919 }
920
921
922 void dbg_flush_log(TSRMLS_D2(DBG, E)) {
923
924 if (DBG(output_str_nd_len) > 0 && DBG(output_str_nd)) {
925 dbg_log_body body;
926 body.ext_info = 0;
927 body.ilog = dbg_packet_add_stringlen(&DBG(logpack), DBG(output_str_nd), DBG(output_str_nd_len));
928 body.imod_name = 0;
929 body.line_no = 0;
930 body.mod_no = 0;
931 body.type = LT_OUTPUT;
932 dbg_packet_add_frame(&DBG(logpack), FRAME_LOG, &body, sizeof(body));
933 DBG(output_str_nd_len) = 0;
934 }
935
936 if (DBG(logpack).size <= 0 || DBG(debug_socket)<=0) return;
937
938 if (dbg_send_command(DBGC_LOG, &DBG(logpack), 0 TSRMLS_CC2(DBG, E))!=0) {
939 DBG(logpack).size = 0;
940 DBG(logpack).lastrawid = 0;
941 }
942 }
943
944 inline int dbg_send_log(char *log, int len, int type, const char *mod_name, const int line_no, int ext_info TSRMLS_DC2(DBG, E)) {
945 dbg_log_body body;
946 int ret_val = 0;
947 char const *amod_name;
948 int aline_no;
949
950 if (DBG(deactivate_inprocess)) return 0; /* should not activate connection by dbg_send_log() */
951 {
952
953 body.type = type;
954 body.ext_info = ext_info;
955
956 if (type!=LT_OUTPUT || DBGO(SOF_SEND_OUTPUT_DETAILED)) {
957 amod_name = mod_name;
958 aline_no = line_no;
959 if (amod_name == NULL) {
960 if (zend_is_executing(TSRMLS_C0)) {
961 amod_name = zend_get_executed_filename(TSRMLS_C1(E));
962 aline_no = zend_get_executed_lineno(TSRMLS_C1(E));
963 } else if (zend_is_compiling(TSRMLS_C0)) {
964 TSRMLS_FETCH1_NOP(C);
965 amod_name = zend_get_compiled_filename(TSRMLS_C1(C));
966 aline_no = zend_get_compiled_lineno(TSRMLS_C1(C));
967 } else {
968 amod_name = NULL;
969 aline_no = 0;
970 }
971 }
972 body.line_no = aline_no;
973 body.mod_no = DBG_FINDMODULE_ADD(amod_name);
974 body.imod_name = dbg_packet_add_string(&DBG(logpack), amod_name);
975 body.ilog = dbg_packet_add_stringlen(&DBG(logpack), log, len);
976 dbg_packet_add_frame(&DBG(logpack), FRAME_LOG, &body, sizeof(body));
977 if (DBG(logpack).size >= 16300 || DBG(logpack).lastrawid > 512 || type == LT_FATALERROR)
978 dbg_flush_log(TSRMLS_C2(DBG, E));
979 } else { /* non-detailed output */
980 int newlen;
981 if (!DBG(output_str_nd)) {
982 newlen = len;
983 DBG(output_str_nd_len) = 0;
984 DBG(output_str_nd_limit) = (len > 8192) ? len : 8192;
985 DBG(output_str_nd) = emalloc(DBG(output_str_nd_limit));
986 } else {
987 newlen = DBG(output_str_nd_len) + len;
988 }
989 if (newlen > DBG(output_str_nd_limit)) {
990 DBG(output_str_nd_limit) = (newlen + 4096) & (~4095);
991 DBG(output_str_nd) = erealloc(DBG(output_str_nd), DBG(output_str_nd_limit));
992 }
993 if (DBG(output_str_nd)) {
994 memcpy((char*)DBG(output_str_nd)+DBG(output_str_nd_len), log, len);
995 } else {
996 newlen = 0;
997 DBG(output_str_nd_limit) = 0;
998 }
999 DBG(output_str_nd_len) = newlen;
1000 if (newlen > 4096 || type == LT_FATALERROR)
1001 dbg_flush_log(TSRMLS_C2(DBG, E));
1002 }
1003 ret_val = 1;
1004 }
1005 return ret_val;
1006 }
1007
1008 void add_session_cookie(TSRMLS_D2(DBG, S)) {
1009 char buf[256];
1010 if (SG(headers_sent) || SG(request_info).no_headers) return;
1011 if (DBG(cfgprm_session_cookie) &&
1012 !DBG(session_cookie_added) &&
1013 DBG(req_sess_var) != NULL &&
1014 strlen(DBG(req_sess_var)) != 0) {
1015 DBG(session_cookie_added) = 1;
1016 snprintf(buf, sizeof(buf) - 1, "Set-Cookie: %s;path=/;", DBG(req_sess_var));
1017 buf[sizeof(buf) - 1] = 0;
1018 DBG_TRACE(("adding '%s'\n", buf));
1019 ADD_HDR(buf);
1020 }
1021 }
1022
1023 int hex2digits_toi(char *s2) {
1024 int ret_val;
1025 int c;
1026
1027 c = s2[0];
1028 if (isupper(c))
1029 c = tolower(c);
1030 ret_val = ((c >= '0' && c <= '9') ? (c - '0') : (c - 'a' + 10)) * 16;
1031
1032 c = s2[1];
1033 if (isupper(c))
1034 c = tolower(c);
1035 ret_val += (c >= '0' && c <= '9') ? (c - '0') : (c - 'a' + 10);
1036
1037 return (ret_val);
1038 }
1039
1040 int urldecode(char *str, int len) {
1041 char *dest = str, *src = str;
1042
1043 while (len--) {
1044 if (*src == '+')
1045 *dest = ' ';
1046 else if (*src == '%' && len >= 2 && isxdigit((int) *(src + 1)) && isxdigit((int) *(src + 2))) {
1047 *dest = (char) hex2digits_toi(src + 1);
1048 src += 2;
1049 len -= 2;
1050 } else
1051 *dest = *src;
1052 src++;
1053 dest++;
1054 }
1055 *dest = '\0';
1056 return (dest - str);
1057 }
1058
1059 int parse_session_request(char *str, int len, char delimiter TSRMLS_DC1(DBG)) {
1060 char *psid, *phost, *pport = NULL, *p;
1061 int nsid, nhost, nport;
1062 char numbuf[10], reqbuf[512];
1063
1064
1065 DBG_TRACE(("parse_session_request '%s'\n", SON(str)));
1066 if (str == NULL || len < 1) return 0;
1067
1068 if (len > sizeof(reqbuf)-1) len = sizeof(reqbuf)-1;
1069 strncpy(reqbuf, str, len);
1070 reqbuf[len] = 0;
1071 p = strchr(reqbuf, delimiter);
1072 if (p) p[0] = 0;
1073 len = urldecode(reqbuf, strlen(reqbuf));
1074
1075 str = reqbuf;
1076
1077 DBG_TRACE(("req '%s'\n", SON(str)));
1078
1079 if (DBG(req_sess_var)) {
1080 efree(DBG(req_sess_var));
1081 DBG(req_sess_var) = NULL;
1082 }
1083 if (DBG(req_client_ip_address)) {
1084 efree(DBG(req_client_ip_address));
1085 DBG(req_client_ip_address) = NULL;
1086 }
1087 if (DBG(session_id)) {
1088 efree(DBG(session_id));
1089 DBG(session_id) = NULL;
1090 }
1091
1092
1093 phost = strchr(str, '@');
1094 if (phost!=NULL) {
1095 psid = str;
1096 nsid = phost - psid;
1097 phost++;
1098 pport = strchr(phost, ':');
1099 if (pport) {
1100 nhost = pport - phost;
1101 if ((p = strchr(phost, ',')) != NULL && p < pport) {
1102 nhost = p - phost;
1103 }
1104 pport++;
1105 nport = strlen(pport);
1106 } else {
1107 nhost = strlen(phost);
1108 nport = 0;
1109 }
1110 DBG(req_client_ip_address) = nhost > 0 ? estrndup(phost, nhost) : NULL;
1111 DBG(session_id) = estrndup(psid, nsid);
1112 if (pport != NULL && nport > 0) {
1113 if (nport >= sizeof(numbuf)) nport = sizeof(numbuf) - 1;
1114 strncpy(numbuf, pport, nport);
1115 numbuf[nport]='\0';
1116 DBG(req_client_port) = atol(numbuf);
1117 if (DBG(req_client_port) <= 0 || DBG(req_client_port) > 32767) DBG(req_client_port) = DEFAULT_PORT;
1118 }
1119 snprintf(reqbuf, sizeof(reqbuf), DBGSESSVAR "=%s@%s:%d", DBG(session_id), DBG(req_client_ip_address), DBG(req_client_port));
1120 DBG(req_sess_var) = estrdup(reqbuf);
1121 DBG_TRACE(("parsed req IP=%s, PORT=%ld (%s), SID=%s\n", SON(DBG(req_client_ip_address)), DBG(req_client_port), numbuf, SON(DBG(session_id))));
1122 } else {
1123 DBG(session_id) = estrndup(str, len);
1124 DBG(req_client_port) = 0;
1125 snprintf(reqbuf, sizeof(reqbuf), DBGSESSVAR "=%s", DBG(session_id));
1126 DBG(req_sess_var) = estrdup(reqbuf);
1127 DBG_TRACE(("parsed req SID=%s\n", SON(DBG(session_id))));
1128 return -1;
1129 }
1130 return 1;
1131 }
1132
1133 int chk_session_request(char *str, int len, char delimiter TSRMLS_DC1(DBG)) {
1134 char *p, *e;
1135 int ret_val;
1136
1137 if (str == NULL) {
1138 DBG_TRACE(("chk_session_request NULL\n"));
1139 return 0;
1140 }
1141 DBG_TRACE(("chk_session_request '%s'\n", SON(str)));
1142 if (len == -1) len = strlen(str);
1143 p = str;
1144 e = p + len;
1145 while (p < e) {
1146 while (p < e && (p[0] == ' ' || p[0] == '\t')) p++;
1147 if ((e-p) < sizeof(DBGSESSVAR)-1) break;
1148 if (strncmp(p, DBGSESSVAR, sizeof(DBGSESSVAR)-1) == 0) {
1149 p += sizeof(DBGSESSVAR)-1;
1150 if (p >= e-1) return 0;
1151 if (*p == '=') {
1152 p++;
1153 ret_val = parse_session_request(p, e-p, delimiter TSRMLS_CC1(DBG));
1154 DBG_TRACE(("parsed result=%d\n", ret_val));
1155 return (ret_val);
1156 }
1157 }
1158 while (p < e && p[0] != delimiter) p++;
1159 if (p[0] != delimiter) return 0;
1160 p++;
1161 }
1162 return 0;
1163 }
1164
1165 int dbg_send_sid(TSRMLS_D2(DBG, E)) {
1166 dbg_packet pack;
1167 int ret_val;
1168
1169 if (!dbg_packet_new(&pack)) return 0;
1170
1171 ret_val = handler_add_sid_reply(&pack, NULL, NULL TSRMLS_CC2(DBG, E));
1172 if (ret_val) ret_val = dbg_send_command(DBGC_SID, &pack, 0 TSRMLS_CC2(DBG, E));
1173
1174 dbg_packet_free(&pack);
1175 return ret_val;
1176 }
1177
1178
1179 int dbg_start_session(SESSTYPE sesstype TSRMLS_DC3(DBG, E, S)) {
1180 int ret_val;
1181
1182 DBG_TRACE(("dbg_start_session req %d\n", sesstype));
1183
1184
1185 if ((DBGF(DBGF_REJECTIONFOUND) && (sesstype != DBG_EMB)) ||
1186 DBG(debug_socket) != 0 ||
1187 DBG(is_failed_connection) ||
1188 !DBG(cfgprm_enabled) ||
1189 DBG(deactivate_inprocess)) return ESESS_NOREASON;
1190
1191 add_session_cookie(TSRMLS_C2(DBG, S));
1192 DBG(debug_socket) = create_debugger_socket(sesstype TSRMLS_CC2(DBG, E));
1193 DBG(is_failed_connection) = (DBG(debug_socket) > 0) ? 0:1;
1194 if (DBG(is_failed_connection)) return DBG(debug_socket);
1195
1196 DBG(debugger_flags) = DBGF_STARTED;
1197 DBG(sesstype) = sesstype;
1198
1199 ret_val = dbg_send_sid(TSRMLS_C2(DBG, E));
1200 if (ret_val > 0)
1201 ret_val = dbg_send_std_action(DBGC_STARTUP, 0 TSRMLS_CC2(DBG, E));
1202 if (ret_val > 0 && DBG(session_id) && strlen(DBG(session_id)) > 0) {
1203 if (DBG(cfgprm_session_nocache) &&
1204 !SG(headers_sent) &&
1205 !SG(request_info).no_headers) {
1206 ADD_HDR("Expires: Thu, 19 Nov 1981 08:52:00 GMT");
1207 ADD_HDR("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
1208 ADD_HDR("Pragma: no-cache");
1209 }
1210 }
1211
1212 DBG_TRACE(("dbg_start_session ret_val=%d\n", ret_val));
1213 return ret_val;
1214 }
1215
1216 int dbg_stop_session(TSRMLS_D2(DBG, E)) {
1217 int ret_val = 0;
1218
1219 if (!DBG(is_failed_connection) && DBG(debug_socket) > 0) {
1220 ret_val = dbg_send_std_action(DBGC_END, 0 TSRMLS_CC2(DBG, E));
1221 }
1222 DBG(debugger_flags) = DBGF_FINISHED;
1223 DBG(sesstype) = 0;
1224 return ret_val;
1225 }
1226
1227
1228 inline int dbg_checkpausereq(TSRMLS_D1(DBG)) {
1229 fd_set rset, eset;
1230 struct timeval timeout;
1231 int ret_val;
1232 dbg_header_struct hdr;
1233 dbg_packet pack;
1234 int socket = DBG(debug_socket);
1235
1236 if (socket <= 0) {
1237 return 0;
1238 }
1239 FD_ZERO(&rset);
1240 FD_SET((unsigned int)socket, &rset);
1241 FD_ZERO(&eset);
1242 FD_SET((unsigned int)socket, &eset);
1243 timeout.tv_sec = 0;
1244 timeout.tv_usec = 0;
1245 ret_val = select(socket + 1, &rset, NULL, &eset, &timeout);
1246 if (ret_val != 1 || !FD_ISSET((unsigned int)socket, &rset))
1247 return 0;
1248
1249 if (!dbg_packet_new(&pack)) return 0;
1250 ret_val = dbg_packet_recv(&hdr, &pack, socket, 0);
1251 if (ret_val > 0) {
1252 ret_val = (hdr.cmd == DBGC_PAUSE);
1253 }
1254 dbg_packet_free(&pack);
1255 return ret_val;
1256 }
1257