[sane-devel] Xscanimage Exits with Segmentation Fault using HP 5370C

Dan McGhee beesnees at grm.net
Sun Sep 25 16:13:56 UTC 2005


Henning Meier-Geinitz wrote:

>[segfault of xscanimage with avision backend]
>
>On Sat, Sep 24, 2005 at 07:39:51AM -0500, Dan McGhee wrote:
>  
>
>>Starting program: /usr/bin/xscanimage
>>
>>*[This is the point at which I clicked "scan" in the preview window]*
>>
>>Program received signal SIGSEGV, Segmentation fault.
>>0x08057467 in gsg_sync (dialog=0x80ef4f0) at gtkglue.c:1424
>>1424 curve = GTK_GAMMA_CURVE (dialog->element[i].widget)->curve;
>>(gdb) bt
>>#0 0x08057467 in gsg_sync (dialog=0x80ef4f0) at gtkglue.c:1424
>>    
>>
>
>The code is:
>
>
>      if (opt->type != SANE_TYPE_INT && opt->type != SANE_TYPE_FIXED)
>        continue;
>
>      if (opt->size == sizeof (SANE_Word))
>        continue;
>
>      /* ok, we're dealing with an active vector */
>
>      optlen = opt->size / sizeof (SANE_Word);
>      optval = alloca (optlen * sizeof (optval[0]));
>      vector = alloca (optlen * sizeof (vector[0]));
>
>      curve = GTK_GAMMA_CURVE (dialog->element[i].widget)->curve;
>
>So I looked into the avision backend for a SANE_TYPE_INT or
>SANE_TYPE_FIXED option with a length != SANE_Word. There are the four
>gamma vectors but they look ok. The only thing that looks fishy is
>this (avision.c):
>
>  s->opt[OPT_NUM_OPTS].name = "";
>  s->opt[OPT_NUM_OPTS].title = SANE_TITLE_NUM_OPTIONS;
>  s->opt[OPT_NUM_OPTS].desc = "";
>  s->opt[OPT_NUM_OPTS].cap = SANE_CAP_SOFT_DETECT;
>  s->opt[OPT_NUM_OPTS].type = SANE_TYPE_INT;
>  s->opt[OPT_NUM_OPTS].size = sizeof(SANE_TYPE_INT);
>
>The last line is wrong (it must be sizeof(SANE_Word)). SANE_TYPE_INT
>is an enum. Is this automatically and "int" or can it be shorter? I'm
>not sure if this is actually the problem but you could try that:
>
>  s->opt[OPT_NUM_OPTS].size = sizeof (SANE_Word);
>
>in avision.c and recompile+install.
>  
>
Just to remind you, I'm not using the version of avision released in 
backends-1.0.16. I'm using Rev. 280 of avision from SVN. It is patched 
with the file Falk Rohsiepe sent me and then Rene posted a patch here 
last month.

I'm really a "noob" at reading code, so right now about the only thing I 
can do is gather and report data. In the version of avision.c that I 
currently have--the patched one--I ran:

'grep -in -A 5 -B 5 SANE_Word avision.c'

I have attached the resulting file. I know there's probably a lot of 
extraneous info there, but I don't know how to filter out the extra stuff.

I also ran:
` grep -in \-A 5 -B 5 sizof\(SANE_Word\) avision.c`
with no results.

`grep -in \-A 5 -B 5 OPT_NUM_OPTS avision.c` yielded

899- dev->speed_range.min = (SANE_Int)0;
5900- dev->speed_range.max = (SANE_Int)4;
5901- dev->speed_range.quant = (SANE_Int)1;
5902-
5903: init_option_int (s, OPT_NUM_OPTS, "", SANE_TITLE_NUM_OPTIONS, "",
5904- SANE_UNIT_NONE, SANE_CAP_SOFT_DETECT, 0, 0,
5905- NUM_OPTIONS);
5906-
5907- /* "Mode" group: */
5908- init_option_group (s, OPT_MODE_GROUP, SANE_TITLE_SCAN_MODE);
--
7605- case OPT_SPEED:
7606- case OPT_TL_X:
7607- case OPT_TL_Y:
7608- case OPT_BR_X:
7609- case OPT_BR_Y:
7610: case OPT_NUM_OPTS:
7611-
7612- case OPT_BRIGHTNESS:
7613- case OPT_CONTRAST:
7614- case OPT_QSCAN:
7615- case OPT_QCALIB:

>If that's not the problem, I guess Rene has to do some debugging
>because without a scanner supported by the avision backend I can't
>help more.
>
>  
>
If you give me specific directions, I can run the commands and post back.

@Rene and Falk I can do the same for both of you too.

>Does the segfault also occur with sane-backends 1.0.16?
>  
>
I'm going by memory, which fails as I age, and I think there may be a 
regression between avision released in backends-1.0.15 and Rev 280. I 
THINK I remember xscanimage working with the patch applied to avision in 
1.0.15, but I'm not sure. If I have the time I will rebuild it and report.

Thanks for the help, Henning.

Dan

-------------- next part --------------
1462-    SANE_FIX (0), /* minimum */
1463-    SANE_FIX (100), /* maximum */
1464-    SANE_FIX (1) /* quantization */
1465-  };
1466-
1467:static const SANE_Word bool_list[] =
1468-  {
1469-    2, /* 2 members */
1470-    SANE_FALSE,
1471-    SANE_TRUE
1472-  };
--
1524-      DBG (3, "constrain_value: while trying to set %.3f\n",
1525-	   SANE_UNFIX(*(SANE_Fixed*)value));
1526-    }
1527-    else {
1528-      DBG (3, "constrain_value: while trying to set %lu\n",
1529:	   (u_long)*(SANE_Word*)value);
1530-    }
1531-  }
1532-  return r;
1533-}
1534-
--
3221-  
3222-  return SANE_STATUS_GOOD;
3223-}
3224-
3225-static SANE_Status
3226:set_frame (Avision_Scanner* s, SANE_Word frame)
3227-{
3228-  struct {
3229-    struct command_send cmd;
3230-    u_int8_t data[8];
3231-  } scmd;
--
5681-  
5682-static void
5683-init_option_int (Avision_Scanner *s, int idx,
5684-		 const char* name, const char* title, const char* desc,
5685-		 SANE_Unit unit, SANE_Int cap,
5686:		 const SANE_Word* valid_list, const SANE_Range* valid_range,
5687-		 SANE_Int value)
5688-{
5689-  s->opt[idx].name = name;
5690-  s->opt[idx].title = title;
5691-  s->opt[idx].desc = desc;
5692-  s->opt[idx].type = SANE_TYPE_INT;
5693-  s->opt[idx].unit = unit;
5694:  s->opt[idx].size = sizeof (SANE_Word);
5695-  s->opt[idx].cap = cap;
5696-  if (valid_list) {
5697-    s->opt[idx].constraint_type = SANE_CONSTRAINT_WORD_LIST;
5698-    s->opt[idx].constraint.word_list = valid_list;
5699-  }
--
5709-  
5710-static void
5711-init_option_int_vec (Avision_Scanner *s, int idx,
5712-		     const char* name, const char* title, const char* desc,
5713-		     SANE_Unit unit, SANE_Int cap,
5714:		     const SANE_Word* valid_list, const SANE_Range* valid_range,
5715-		     SANE_Int* value, SANE_Int value_len)
5716-{
5717-  s->opt[idx].name = name;
5718-  s->opt[idx].title = title;
5719-  s->opt[idx].desc = desc;
5720-  s->opt[idx].type = SANE_TYPE_INT;
5721-  s->opt[idx].unit = unit;
5722:  s->opt[idx].size = value_len * sizeof (SANE_Word);
5723-  s->opt[idx].cap = cap;
5724-  if (valid_list) {
5725-    s->opt[idx].constraint_type = SANE_CONSTRAINT_WORD_LIST;
5726-    s->opt[idx].constraint.word_list = valid_list;
5727-  }
--
5737-  
5738-static void
5739-init_option_fix (Avision_Scanner *s, int idx,
5740-		 const char* name, const char* title, const char* desc,
5741-		 SANE_Unit unit, SANE_Int cap,
5742:		 const SANE_Word* valid_list, const SANE_Range* valid_range,
5743-		 SANE_Fixed value)
5744-{
5745-  s->opt[idx].name = name;
5746-  s->opt[idx].title = title;
5747-  s->opt[idx].desc = desc;
5748-  s->opt[idx].type = SANE_TYPE_FIXED;
5749-  s->opt[idx].unit = unit;
5750:  s->opt[idx].size = sizeof (SANE_Word);
5751-  s->opt[idx].cap = cap;
5752-  if (valid_list) {
5753-    s->opt[idx].constraint_type = SANE_CONSTRAINT_WORD_LIST;
5754-    s->opt[idx].constraint.word_list = valid_list;
5755-  }
--
5766-#ifdef NEEDED
5767-static void
5768-init_option_fix_vec (Avision_Scanner *s, int idx,
5769-		     const char* name, const char* title, const char* desc,
5770-		     SANE_Unit unit, SANE_Int cap,
5771:		     const SANE_Word* valid_list, const SANE_Range* valid_range,
5772-		     SANE_Fixed* value, SANE_Int value_len)
5773-{
5774-  s->opt[idx].name = name;
5775-  s->opt[idx].title = title;
5776-  s->opt[idx].desc = desc;
--
5846-  s->opt[idx].name = name;
5847-  s->opt[idx].title = title;
5848-  s->opt[idx].desc = desc;
5849-  s->opt[idx].type = SANE_TYPE_BOOL;
5850-  s->opt[idx].unit = SANE_UNIT_NONE;
5851:  s->opt[idx].size = sizeof (SANE_Word);
5852-  s->opt[idx].cap = cap;
5853-  s->opt[idx].constraint_type = SANE_CONSTRAINT_NONE;
5854-  s->val[idx].w = value;
5855-}
5856-
--
5873-  
5874-  memset (s->opt, 0, sizeof (s->opt));
5875-  memset (s->val, 0, sizeof (s->val));
5876-
5877-  for (i = 0; i < NUM_OPTIONS; ++ i) {
5878:    s->opt[i].size = sizeof (SANE_Word);
5879-    s->opt[i].cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT;
5880-  }
5881-  
5882-  /* Init the SANE option from the scanner inquiry data */
5883-  
--
7536-		     SANE_Action action, void* val, SANE_Int* info)
7537-{
7538-  Avision_Scanner* s = handle;
7539-  Avision_Device* dev = s->hw;
7540-  SANE_Status status;
7541:  SANE_Word cap;
7542-  
7543-  DBG (3, "sane_control_option: option=%d, action=%d\n",
7544-       (int)option, (int)action);
7545-
7546-  if (info)
--
7577-            DBG (3, "sane_control_option: queried for %d (%s): %.3f\n",
7578-	         option, s->opt[option].name,
7579-	         (double)SANE_UNFIX(s->val[option].w));
7580-	  break;
7581-	case SANE_TYPE_INT:
7582:	  if (s->opt[option].size > (int)sizeof (SANE_Word)) {
7583-	    int i;
7584-            DBG (3, "sane_control_option: queried for %d (%s):\n",
7585-	         option, s->opt[option].name);
7586:	    for (i = 0; i < (int)(s->opt[option].size/sizeof(SANE_Word)); ++i)
7587-              DBG (3, "sane_control_option:         %lu\n",
7588-	           (long)s->val[option].wa[i]);
7589-	  }
7590-	  else
7591-            DBG (3, "sane_control_option: queried for %d (%s): %lu\n",
--
7624-	case OPT_CCT_7:
7625-	case OPT_CCT_8:
7626-	case OPT_CCT_9:
7627-	case OPT_CCT_HW:
7628-	  
7629:	  *(SANE_Word*) val = s->val[option].w;
7630-	  return SANE_STATUS_GOOD;
7631-	  
7632-	  /* specially treated word options */
7633-	  /* FR: shouldn't this better be a string, word array or bitmask?
7634-	     having to query in order is counter-intuitive. */
--
7644-	case OPT_BUTTON_5:
7645-	case OPT_BUTTON_6:
7646-	case OPT_BUTTON_7:
7647-	  
7648-	  /* copy the button state */
7649:	  *(SANE_Word*) val = s->val[option].w;
7650-	  /* clear the button state */
7651-	  s->val[option].w = SANE_FALSE;
7652-
7653-	  return SANE_STATUS_GOOD;
7654-	  
--
7689-            DBG (3, "sane_control_option: ordered to set %d (%s) to %.3f\n",
7690-	         option, s->opt[option].name,
7691-	         (double)SANE_UNFIX(*(SANE_Fixed*)val));
7692-	  break;
7693-	case SANE_TYPE_INT:
7694:	  if (s->opt[option].size > (int)sizeof (SANE_Word)) {
7695-	    int i;
7696-            DBG (3, "sane_control_option: ordered to set %d (%s) to:\n",
7697-	         option, s->opt[option].name);
7698:	    for (i = 0; i < (int)(s->opt[option].size/sizeof(SANE_Word)); ++i)
7699-              DBG (3, "sane_control_option:         %lu\n",
7700:	           (long)((SANE_Word*)val)[i]);
7701-	  }
7702-	  else
7703-            DBG (3, "sane_control_option: ordered to set %d (%s) to %lu\n",
7704:	         option, s->opt[option].name, (long)*(SANE_Word*)val);
7705-	  break;
7706-	case SANE_TYPE_BUTTON:
7707-	  DBG (3, "sane_control_option: button %d (%s) activated\n",
7708-	       option, s->opt[option].name);
7709-	  break;
7710-	default:
7711-          DBG (3, "sane_control_option: ordered to set %d (%s) to %lu\n",
7712:	       option, s->opt[option].name, (long)*(SANE_Word*)val);
7713-	  break;
7714-      }
7715-      if (!SANE_OPTION_IS_SETTABLE (cap))
7716-	return SANE_STATUS_INVAL;
7717-      
--
7728-	case OPT_CONTRAST:
7729-	case OPT_QSCAN:
7730-	case OPT_QCALIB:
7731-	case OPT_CCT_HW:
7732-
7733:	  s->val[option].w = *(SANE_Word*) val;
7734-	  return SANE_STATUS_GOOD;
7735-
7736-	case OPT_CCT_1:
7737-	case OPT_CCT_2:
7738-	case OPT_CCT_3:
--
7740-	case OPT_CCT_5:
7741-	case OPT_CCT_6:
7742-	case OPT_CCT_7:
7743-	case OPT_CCT_8:
7744-	case OPT_CCT_9:
7745:	  s->val[option].w = *(SANE_Word*) val;
7746-	  set_3x3_matrix (s);
7747-	  return SANE_STATUS_GOOD;
7748-	  
7749-	  /* side-effect-free word-array options: */
7750-	case OPT_GAMMA_VECTOR:
--
7759-	case OPT_TL_X:
7760-	case OPT_TL_Y:
7761-	case OPT_BR_X:
7762-	case OPT_BR_Y:
7763-
7764:	  s->val[option].w = *(SANE_Word*) val;
7765-
7766-  	  if (dev->hw->feature_type & AV_WINDOW_BUG) {
7767-	    if ((s->scale_mode == AV_SCALE_HWONLY) && adjust_hwdpi (s)) {
7768-	      if (info)
7769-		*info |= SANE_INFO_INEXACT | SANE_INFO_RELOAD_OPTIONS;
--
7775-
7776-	  return SANE_STATUS_GOOD;
7777-
7778-	case OPT_GAMMA_RELATIVE:
7779-	  
7780:	  if (s->val[option].w != *(SANE_Word*) val) {
7781-	    int i, j;
7782-	    SANE_Int* tt;
7783:	    s->val[option].w = *(SANE_Word*) val;
7784-	    
7785-	    if (s->val[option].w)
7786-	      tt = default_gamma ();
7787-	    else
7788-	      tt = default_inverse_gamma ();
--
7857-	      *info |= SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS;
7858-	    return SANE_STATUS_GOOD;
7859-	  }
7860-	case OPT_FRAME:
7861-	  {
7862:	    SANE_Word frame = *((SANE_Word  *) val);
7863-	    
7864-	    status = set_frame (s, frame);
7865-	    if (status == SANE_STATUS_GOOD) {
7866-	      s->val[OPT_FRAME].w = frame;
7867-	      dev->current_frame = frame;


More information about the sane-devel mailing list