This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

STATUS_ACCESS_VIOLATION when using tvb_memcpy / Displaying Fixed Point Numbers

0

I have an issue where the information I'm trying to display a fixed point number from the message. However, the way the message is sent is that the value is basically a short int (signed 16 bit int) multiplied by 10^-2. Since there are no accessors to pull a 16 bit signed int from the buffer I used tvb_memcpy to place the bits into a gint16 variable. Then I cast that as a gfloat and multiply by 0.01. Whenever I do this, I see an error in the tree at this section that says

"[Dissector bug, protocol MY_PROTOCOL: STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address".

Am I missing something curcial, or is there a better way to do this? Any suggestions would be greatly appreciated. Here is the code for this part:

    // declared at the beginning of the dissect function
    gint16 *val_short = 0;
    gfloat val_float = 0;     
    .
    .
    .
    //within the switch that handles message type
    case 10:
       tvb_memcpy(tvb, (guint8*)&val_short, offset, 2);
       val_float = ((gfloat)(*val_short)) * (gfloat)0.01;
       proto_tree_add_float(my_protocol_tree, hf_my_protocol_x_value, tvb, offset, 2, val_float);

asked 16 May '13, 06:15

Gaax's gravatar image

Gaax
16115
accept rate: 0%

edited 16 May '13, 06:16


One Answer:

1

The invalid memory access is because you didn't allocate any memory for val_short. You have a pointer pointing to NULL and you're trying to copy into it.

But: why not use tvb_get_ntohs() or tvb_get_letohs() (depending on the endianism of the 16 bits)? Sure they returned an unsigned value but if you store the result in a signed variable, well, it'll be treated as signed.

answered 16 May '13, 08:42

JeffMorriss's gravatar image

JeffMorriss ♦
6.2k572
accept rate: 27%

Ok, I kind of feel stupid but hey, I'm learning lol.

I tried doing it using tvb_get_ntohs() and it worked perfectly! I just had to cast the return value as a gint16 (simply storing it into a gint16 wasn't enough apparantly).

Before this, I also tried allocating the memory space for that pointer and doing it the way I had originally planned but it just returned zero every time. For the sake of learning, if you (or anyone) could tell me how to do it properly using the pointer, I'd be truly grateful.

(16 May '13, 10:26) Gaax

No worries, we are all (hopefully) learning all the time. :-)

Something like this would probably be a good way to do it (no need for a pointer):

gint16 val_short;
[...]
tvb_memcpy(tvb, (guint8*)&val_short, offset, 2);

If you really want to use a pointer then:

gint16 *val_short;
val_short = g_malloc(sizeof(gint16));
[...]
tvb_memcpy(tvb, (guint8*)val_short, offset, 2); << note the lack of "&" since val_short is already a pointer
(16 May '13, 10:39) JeffMorriss ♦

Aha, ok I get it now. Thanks!

(16 May '13, 10:46) Gaax