Recently we got ownership of a legacy piece of code with no knowledge transfer and we cannot figure out why a certain line of code with apr_dbd_pselect results in segmentation fault in the c code which is deployed on Apache 2.4 using mysql on Amazon Linux2. The same piece of c code works perfectly fine on Apache 2.2 and Centos with mysql same version. Code in question is as follows. And the line throwing the seg fault is the second call to apr_dbd_pselect (second last line in the code). This piece of code basically makes use of the apr_dbd routines to make a select call to get a value from a table given the argument and then we believe the second select statement somehow ends up closing the connection/statement/transaction on Centos with Apache 2.2. On Amazon linux 2 with Apache 2.4 it ends up throwing seg fault. We wanted to know why the second select statement results in seg fault on AL2 and if it can be rewritten in some other way to achieve the same result (as in closing successfully the connection/statement/transaction) and not result in seg fault. In both cases if we comment the line then the next invocation of this method in same request results in this error- https://dev.mysql.com/doc/mysql-errors/5.6/en/client-error-reference.html#error_cr_commands_out_of_sync
static char *method1( apr_pool_t *tmp_pool, ap_dbd_t *dbd, const char *table_name, const char *arg1) { char *value = ""; apr_dbd_results_t *res = NULL; apr_dbd_row_t *row = NULL; int ret; apr_dbd_prepared_t *jstmt; fprintf( stderr,"%s.%d Lookup token : %s\n",__FILE__, __LINE__, arg1 );fflush(stderr); if (dbd == NULL) { fprintf( stderr,"%s.%d Could not open DBD conenction",__FILE__, __LINE__);fflush(stderr); return ""; } if (table_name == NULL || strlen(table_name) < 1) { table_name = "table1"; } //char *stmt = "select fn from students where token = '12345'"; /* jdh -- table_name is not used can be used for prepared statement hash name */ jstmt = apr_hash_get(dbd->prepared,table_name,APR_HASH_KEY_STRING); if (NULL == jstmt) { fprintf(stderr,"%s.%d Could not find prepared statement: %s\n",__FILE__, __LINE__,table_name); fflush(stderr); return ""; } const char *arglist[2]; arglist[0] = arg1; ret = apr_dbd_pselect(dbd->driver,tmp_pool,dbd->handle,&res,jstmt,0,1,arglist); if (0 != ret){ fprintf(stderr,"%s.%d apr_dbd_pselect failed: %d\n",__FILE__, __LINE__,ret); fflush(stderr); return ""; } int rows = apr_dbd_num_tuples(dbd->driver, res); int cols = apr_dbd_num_cols(dbd->driver, res); fprintf( stderr,"%s.%d Rows, Cols : %i %i\n",__FILE__, __LINE__, rows, cols );fflush(stderr); if (rows < 1 || cols < 1) { fprintf( stderr,"%s.%d No results found for %s\n",__FILE__, __LINE__, token_id); fflush(stderr); return ""; } ret = apr_dbd_get_row(dbd->driver, tmp_pool, res, &row, -1); if (0 == ret) { value = apr_dbd_get_entry(dbd->driver, row, 0); fprintf( stderr,"%s.%d Data, : %s\n",__FILE__, __LINE__, value ); fflush(stderr); } else { fprintf( stderr,"%s.%d get_row fail ret=%d\n",__FILE__, __LINE__, ret); fflush(stderr); } apr_dbd_pselect(dbd->driver,tmp_pool,dbd->handle,NULL,NULL,-2,0,NULL); return value; }