Discussion:
List hd error
Adrian
2012-02-28 13:32:49 UTC
Permalink
Hello,
i have to setup a modified sks server. This server works well at 2010 but
now it raise an exeption. So the changes in the data of the server are the
reason for the error. But the software have to work with these datas. I
tried to get the error but ocaml isn’t simple. The raised error tells me
nearly nothing.

The last outputs:
skipped key 6D793EA9C97C0238: No_valid_selfsig (no valid selfsignature
(version 4))
no valid selfsignature (version 2)
skipped key 0F1451FD126A6139: No_valid_selfsig (no valid selfsignature
(version 2))
no valid selfsignature (version 3)
skipped key 28D5AFEF69AFF739: No_valid_selfsig (no valid selfsignature
(version 3))
Fatal error: exception Failure("hd")

I think the attached file contains the error but i did not get it :(


if you need the whole source code :

http://gs.myftp.biz/sks/sks-keyserver-mercurial.tar.gz

thats round about 3,7MB and that is the reason why i did not attached it.

Thank for your time.
Regards.

Adrian


[Non-text portions of this message have been removed]
Esther Baruk
2012-02-28 13:53:37 UTC
Permalink
Hi,

Try to run your code with OCAMLRUNPARAM=b, it will give you the stack trace
of the exception and you will see which line of code are involved.
For instance :
$ OCAMLRUNPARAM=b ./my_server

In general, try not to use List.hd (or List.tl) which can fail on an empty
list.
Use pattern matching instead and raise a significant exception in case of
an empty list.



Esther Baruk
Post by Adrian
**
Hello,
i have to setup a modified sks server. This server works well at 2010 but
now it raise an exeption. So the changes in the data of the server are the
reason for the error. But the software have to work with these datas. I
tried to get the error but ocaml isn’t simple. The raised error tells me
nearly nothing.
skipped key 6D793EA9C97C0238: No_valid_selfsig (no valid selfsignature
(version 4))
no valid selfsignature (version 2)
skipped key 0F1451FD126A6139: No_valid_selfsig (no valid selfsignature
(version 2))
no valid selfsignature (version 3)
skipped key 28D5AFEF69AFF739: No_valid_selfsig (no valid selfsignature
(version 3))
Fatal error: exception Failure("hd")
I think the attached file contains the error but i did not get it :(
http://gs.myftp.biz/sks/sks-keyserver-mercurial.tar.gz
thats round about 3,7MB and that is the reason why i did not attached it.
Thank for your time.
Regards.
Adrian
[Non-text portions of this message have been removed]
[Non-text portions of this message have been removed]



------------------------------------

Archives up to December 31, 2011 are also downloadable at http://www.connettivo.net/cntprojects/ocaml_beginners
The archives of the very official ocaml list (the seniors' one) can be found at http://caml.inria.fr
Attachments are banned and you're asked to be polite, avoid flames etc.Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ocaml_beginners/

<*> Your email settings:
Individual Email | Traditional

<*> To change settings online go to:
http://groups.yahoo.com/group/ocaml_beginners/join
(Yahoo! ID required)

<*> To change settings via email:
ocaml_beginners-***@yahoogroups.com
ocaml_beginners-***@yahoogroups.com

<*> To unsubscribe from this group, send an email to:
ocaml_beginners-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
oliver
2012-02-28 14:23:06 UTC
Permalink
Post by Esther Baruk
Hi,
Try to run your code with OCAMLRUNPARAM=b, it will give you the stack trace
of the exception and you will see which line of code are involved.
$ OCAMLRUNPARAM=b ./my_server
[...]


Hey, thats nice. :-)

For compilation/linkage, switch "-g" must be used.
Post by Esther Baruk
In general, try not to use List.hd (or List.tl) which can fail on an empty
list.
Use pattern matching instead and raise a significant exception in case of
an empty list.
[...]

The problem might be very similar then....
...just that you have a more elaborated name of the exception
might be helpful.

Ciao,
Oliver
oliver
2012-02-28 14:27:04 UTC
Permalink
On Tue, Feb 28, 2012 at 02:53:37PM +0100, Esther Baruk wrote:
[...]
Post by Esther Baruk
In general, try not to use List.hd (or List.tl) which can fail on an empty
list.
Use pattern matching instead and raise a significant exception in case of
an empty list.
[...]

Something like a changed List.hd that will get a second parameter (excpetion) and
will raise that exception if List.length is 0 also would work.

Something like

let hd lis exc = if List.length lis = 0 then raise exc else List.hd lis

Ciao,
Oliver
Esther Baruk
2012-02-28 14:32:48 UTC
Permalink
No, it would not work since exceptions cannot be manipulated like other
values, they cannot be passed as argument of a function.
But, you can pass a string message which will be given to failwith in case
of an empty list.

Esther Baruk
Post by oliver
**
[...]
Post by Esther Baruk
In general, try not to use List.hd (or List.tl) which can fail on an
empty
Post by Esther Baruk
list.
Use pattern matching instead and raise a significant exception in case of
an empty list.
[...]
Something like a changed List.hd that will get a second parameter (excpetion) and
will raise that exception if List.length is 0 also would work.
Something like
let hd lis exc = if List.length lis = 0 then raise exc else List.hd lis
Ciao,
Oliver
[Non-text portions of this message have been removed]



------------------------------------

Archives up to December 31, 2011 are also downloadable at http://www.connettivo.net/cntprojects/ocaml_beginners
The archives of the very official ocaml list (the seniors' one) can be found at http://caml.inria.fr
Attachments are banned and you're asked to be polite, avoid flames etc.Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ocaml_beginners/

<*> Your email settings:
Individual Email | Traditional

<*> To change settings online go to:
http://groups.yahoo.com/group/ocaml_beginners/join
(Yahoo! ID required)

<*> To change settings via email:
ocaml_beginners-***@yahoogroups.com
ocaml_beginners-***@yahoogroups.com

<*> To unsubscribe from this group, send an email to:
ocaml_beginners-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Esther Baruk
2012-02-28 14:34:04 UTC
Permalink
Returning "assert false" works also and has the advantage to give you the
line where the error occured.


Esther Baruk
Post by Esther Baruk
No, it would not work since exceptions cannot be manipulated like other
values, they cannot be passed as argument of a function.
But, you can pass a string message which will be given to failwith in case
of an empty list.
Esther Baruk
Post by oliver
**
[...]
Post by Esther Baruk
In general, try not to use List.hd (or List.tl) which can fail on an
empty
Post by Esther Baruk
list.
Use pattern matching instead and raise a significant exception in case
of
Post by Esther Baruk
an empty list.
[...]
Something like a changed List.hd that will get a second parameter (excpetion) and
will raise that exception if List.length is 0 also would work.
Something like
let hd lis exc = if List.length lis = 0 then raise exc else List.hd lis
Ciao,
Oliver
[Non-text portions of this message have been removed]



------------------------------------

Archives up to December 31, 2011 are also downloadable at http://www.connettivo.net/cntprojects/ocaml_beginners
The archives of the very official ocaml list (the seniors' one) can be found at http://caml.inria.fr
Attachments are banned and you're asked to be polite, avoid flames etc.Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ocaml_beginners/

<*> Your email settings:
Individual Email | Traditional

<*> To change settings online go to:
http://groups.yahoo.com/group/ocaml_beginners/join
(Yahoo! ID required)

<*> To change settings via email:
ocaml_beginners-***@yahoogroups.com
ocaml_beginners-***@yahoogroups.com

<*> To unsubscribe from this group, send an email to:
ocaml_beginners-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
r***@happyleptic.org
2012-02-28 14:39:39 UTC
Permalink
-[ Tue, Feb 28, 2012 at 03:32:48PM +0100, Esther Baruk ]----
Post by Esther Baruk
No, it would not work since exceptions cannot be manipulated like other
values, they cannot be passed as argument of a function.
They can. Exceptions are values of type exn:

# let raiseme e = raise e;;
val raiseme : exn -> 'a = <fun>
# exception Bla of int;;
exception Bla of int
# raiseme (Bla 10);;
Exception: Bla 10.
Esther Baruk
2012-02-28 14:59:27 UTC
Permalink
Yes you're right, my mistake!


Esther Baruk
Post by r***@happyleptic.org
**
-[ Tue, Feb 28, 2012 at 03:32:48PM +0100, Esther Baruk ]----
Post by Esther Baruk
No, it would not work since exceptions cannot be manipulated like other
values, they cannot be passed as argument of a function.
# let raiseme e = raise e;;
val raiseme : exn -> 'a = <fun>
# exception Bla of int;;
exception Bla of int
# raiseme (Bla 10);;
Exception: Bla 10.
[Non-text portions of this message have been removed]



------------------------------------

Archives up to December 31, 2011 are also downloadable at http://www.connettivo.net/cntprojects/ocaml_beginners
The archives of the very official ocaml list (the seniors' one) can be found at http://caml.inria.fr
Attachments are banned and you're asked to be polite, avoid flames etc.Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ocaml_beginners/

<*> Your email settings:
Individual Email | Traditional

<*> To change settings online go to:
http://groups.yahoo.com/group/ocaml_beginners/join
(Yahoo! ID required)

<*> To change settings via email:
ocaml_beginners-***@yahoogroups.com
ocaml_beginners-***@yahoogroups.com

<*> To unsubscribe from this group, send an email to:
ocaml_beginners-***@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
Gabriel Scherer
2012-02-28 18:37:20 UTC
Permalink
All of this is rather moot: with the backtrace information enabled, as
suggested by Esther, the precise place where the error happens will be
available -- so there is no more need, for example, to litter the code
with "assert false" to get location informations. I second the
recommendation not to use List.hd and List.tl, though, pattern
matching forces to handle the failure case and is almost always
better. If you know statically that the list is always non-empty, then
at least write a comment to justify invariant.
Post by Esther Baruk
Yes you're right, my mistake!
Esther Baruk
Post by r***@happyleptic.org
**
-[ Tue, Feb 28, 2012 at 03:32:48PM +0100, Esther Baruk ]----
Post by Esther Baruk
No, it would not work since exceptions cannot be manipulated like other
values, they cannot be passed as argument of a function.
# let raiseme e = raise e;;
val raiseme : exn -> 'a = <fun>
# exception Bla of int;;
exception Bla of int
# raiseme (Bla 10);;
Exception: Bla 10.
[Non-text portions of this message have been removed]
------------------------------------
Archives up to December 31, 2011 are also downloadable at http://www.connettivo.net/cntprojects/ocaml_beginners
The archives of the very official ocaml list (the seniors' one) can be found at http://caml.inria.fr
Attachments are banned and you're asked to be polite, avoid flames etc.Yahoo! Groups Links
Adrian
2012-03-02 13:44:57 UTC
Permalink
well i got the error. The error is in parsePGP.ml line 150.

let mpi = List.hd mpis in
{ pk_version = version;
pk_ctime = creation_time;
pk_expiration = (match expiration with Some 0 -> None | x -> x);
pk_alg = algorithm;
pk_keylen = mpi.mpi_bits;
}

the task of the program is to dump the database. How can i kill the error without killing the structure of data?

Adrian


From: Gabriel Scherer
Sent: Tuesday, February 28, 2012 7:37 PM
To: ***@yahoogroups.com
Cc: ***@happyleptic.org
Subject: Re: "ocaml_beginners"::[] List hd error


All of this is rather moot: with the backtrace information enabled, as
suggested by Esther, the precise place where the error happens will be
available -- so there is no more need, for example, to litter the code
with "assert false" to get location informations. I second the
recommendation not to use List.hd and List.tl, though, pattern
matching forces to handle the failure case and is almost always
better. If you know statically that the list is always non-empty, then
at least write a comment to justify invariant.
Post by Esther Baruk
Yes you're right, my mistake!
Esther Baruk
Post by r***@happyleptic.org
**
-[ Tue, Feb 28, 2012 at 03:32:48PM +0100, Esther Baruk ]----
Post by Esther Baruk
No, it would not work since exceptions cannot be manipulated like other
values, they cannot be passed as argument of a function.
# let raiseme e = raise e;;
val raiseme : exn -> 'a = <fun>
# exception Bla of int;;
exception Bla of int
# raiseme (Bla 10);;
Exception: Bla 10.
[Non-text portions of this message have been removed]
------------------------------------
Archives up to December 31, 2011 are also downloadable at http://www.connettivo.net/cntprojects/ocaml_beginners
The archives of the very official ocaml list (the seniors' one) can be found at http://caml.inria.fr
Attachments are banned and you're asked to be polite, avoid flames etc.Yahoo! Groups Links
[Non-text portions of this message have been removed]

oliver
2012-02-28 14:18:52 UTC
Permalink
Hello,
Post by Adrian
Hello,
i have to setup a modified sks server. This server works well at 2010 but
now it raise an exeption. So the changes in the data of the server are the
reason for the error. But the software have to work with these datas. I
tried to get the error but ocaml isn’t simple. The raised error tells me
nearly nothing.
[...]
Post by Adrian
http://gs.myftp.biz/sks/sks-keyserver-mercurial.tar.gz
[...]


This is the list of List.hd-calls in your code:
------------------------------------------------

==========================================================================================
***@siouxsie:~/tmp/sks/sks-keyserver$ grep -n "List.hd" *.ml
add_mail.ml:49: Filename.concat (List.hd !anonymous) "messages"
dbserver.ml:100: let ki = ParsePGP.parse_pubkey_info (List.hd key) in
dbserver.ml:243: let hash_str = List.hd request.search in
ekey_conv_all.ml:229: List.hd uids
ekey_conv_all.ml:264: let keyid = keyid_to_string (Fingerprint.keyid_from_packet (List.hd key)) in
ekey_conv_all.ml:269: let keyid = keyid_to_string (Fingerprint.keyid_from_packet (List.hd key)) in
ekey_conv_all.ml:273: let keyid = keyid_to_string (Fingerprint.keyid_from_packet (List.hd key)) in
ekey_conv_all.ml:277: let keyid = keyid_to_string (Fingerprint.keyid_from_packet (List.hd key)) in
ekey_conv_all.ml:281: let keyid = keyid_to_string (Fingerprint.keyid_from_packet (List.hd key)) in
ekey_conv.ml:191: List.hd uids
ekey_conv.ml:222: let keyid = Fingerprint.keyid_from_packet (List.hd key) in
ekey_conv.ml:227: let keyid = Fingerprint.keyid_from_packet (List.hd key) in
index.ml:538: (* let primary_uid_string = (fst (List.hd uids)).packet_body in *)
index.ml:611: let pki = ParsePGP.parse_pubkey_info (List.hd key) in
membership.ml:169: let saddr = (List.hd addrlist).Unix.ai_addr in
parsePGP.ml:150: let mpi = List.hd mpis in
query.ml:58: keyidstr (List.hd (Key.get_ids key))
tester.ml:99:let first log = List.hd log
wserver.ml:204: match List.hd pieces with
***@siouxsie:~/tmp/sks/sks-keyserver$
==========================================================================================



This is the list of files that use List.hd-calls:
--------------------------------------------------

==========================================================================================
***@siouxsie:~/tmp/sks/sks-keyserver$ grep -l "List.hd" *.ml
add_mail.ml
dbserver.ml
ekey_conv_all.ml
ekey_conv.ml
index.ml
membership.ml
parsePGP.ml
query.ml
tester.ml
wserver.ml
***@siouxsie:~/tmp/sks/sks-keyserver$
==========================================================================================

So you have 10 files where the error might occur.

For looking up the length of the called list and get a message
with the length printed (and an additional message, if the length is 0),
you could use this approach here:


Insert the follwoing code into the above mentioned files,
and adapt the line, where module List is (re)defined.


====================================================================================
module L = functor ( Name : sig val filename: string end ) ->
struct
include List

let hd l = let len = List.length l in
if len = 0 then prerr_string "!!!!! ";
Printf.fprintf stderr "%s: length = %d\n" Name.filename len;
List.hd l
end

module List = L(struct let filename = "stuff.ml" end) (* this must be adapted for each file *)
====================================================================================

Then you will get a length-message for each List.hd call
and a marker with leading "!"'s, if the length of the list is 0.
Use the filename of the file where you insert that code as
structure that is used in the functor-application.
Then you at least get a hint, in which module your problem occurs.

Hope that helps.

Ciao,
Oliver
Loading...