473,320 Members | 1,922 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Why the setjmp and longjmp I wrote can not work?

I wrote a simple one as follow:

typedef struct __myjmp_buf
{
int efp;
int epc;
}myjmp_buf;

int mysetjmp(myjmp_buf env)
{
int reval=0;
__asm__("movl %%ebp,%0":"=r"(env[0].efp));
__asm__("movl $1f,%0\n\t"
"1:"
:"=r"(env[0].epc));
return reval;
}

void mylongjmp(myjmp_buf env , int val)
{
__asm__("movl %1,-4(%0)\n\t"
"movl %0,%%ebp\n\t"
"jmp %2"
::"r"(env[0].efp),
"r"(val),
"r"(env[0].epc));
}

myjmp_buf buf;

int test()
{
int i=0;
i++;
mylongjmp(buf , 1);
return 0;
}

int main()
{
if(mysetjmp(buf))
{
printf("return success\n");
}
printf("pc:%x,fp:%x\n" , buf[0].epc , buf[0].efp);
printf("main address:%x\n" , main);
test();
exit(0);
}

When the computer execute jmp %2, and gives me a segment fault.
Why the address I save is a invalid address?
By the way, I want to find the codes of setjmp and longjmp in glibc,
but can not get it, and waht I find does not seem to be what I want.
How to find the codes of setjmp and longjmp which can run under Linux
and x86?
Thank you

Nov 15 '05 #1
8 2377
Zheng Da wrote:
I wrote a simple one as follow:
<snip>
Sorry, your code does not compile; you forgot to
#include <stdio.h>
and you use the non-standard __asm__() function.
When the computer execute jmp %2, and gives me a segment fault.
Why the address I save is a invalid address?
By the way, I want to find the codes of setjmp and longjmp in glibc,
but can not get it, and waht I find does not seem to be what I want.
How to find the codes of setjmp and longjmp which can run under Linux
and x86?


Please provide a minimal compiling example in standard
C or repost your request in a newsgroup where your
platform/operating system/compiler-combination is on-topic.

Information about setjmp/longjmp() can be found below.
Cheers
Michael

PS: The following is only a quote from the standard.

As for setjmp()/longjmp():

7.13 Nonlocal jumps <setjmp.h>

1 The header <setjmp.h> defines the macro setjmp, and declares one
function and one type, for bypassing the normal function call and
return discipline.207)
,---
| 207) These functions are useful for dealing with unusual conditions
| encountered in a low-level function of a program.
`---

2 The type declared is
jmp_buf
which is an array type suitable for holding the information needed to
restore a calling environment. The environment of a call to the setjmp
macro consists of information sufficient for a call to the longjmp
function to return execution to the correct block and invocation of that
block, were it called recursively. It does not include the state of the
floating-point status flags, of open files, or of any other component of
the abstract machine.

3 It is unspecified whether setjmp is a macro or an identifier declared
with external linkage. If a macro definition is suppressed in order to
access an actual function, or a program defines an external identifier
with the name setjmp, the behavior is undefined.

7.13.1 Save calling environment
7.13.1.1 The setjmp macro

Synopsis
1
#include <setjmp.h>
int setjmp(jmp_buf env);

Description
2 The setjmp macro saves its calling environment in its jmp_buf argument
for later use by the longjmp function.

Returns
3 If the return is from a direct invocation, the setjmp macro returns
the value zero. If the return is from a call to the longjmp function,
the setjmp macro returns a nonzero value.

Environmental limits
4 An invocation of the setjmp macro shall appear only in one of the
following contexts:
— the entire controlling expression of a selection or iteration
statement;
— one operand of a relational or equality operator with the other
operand an integer constant expression, with the resulting expression
being the entire controlling expression of a selection or iteration
statement;
— the operand of a unary ! operator with the resulting expression being
the entire controlling expression of a selection or iteration
statement; or
— the entire expression of an expression statement (possibly cast to
void).

5 If the invocation appears in any other context, the behavior is undefined.

7.13.2 Restore calling environment
7.13.2.1 The longjmp function

Synopsis
1
#include <setjmp.h>
void longjmp(jmp_buf env, int val);

Description
2 The longjmp function restores the environment saved by the most recent
invocation of the setjmp macro in the same invocation of the program
with the corresponding jmp_buf argument. If there has been no such
invocation, or if the function containing the invocation of the setjmp
macro has terminated execution208) in the interim, or if the invocation
of the setjmp macro was within the scope of an identifier with variably
modified type and execution has left that scope in the interim, the
behavior is undefined.
,---
| 208) For example, by executing a return statement or because another
| longjmp call has caused a transfer to a setjmp invocation in a
| function earlier in the set of nested calls.
`---

3 All accessible objects have values, and all other components of the
abstract machine209) have state, as of the time the longjmp function was
called, except that the values of objects of automatic storage duration
that are local to the function containing the invocation of the
corresponding setjmp macro that do not have volatile-qualified type
and have been changed between the setjmp invocation and longjmp call are
indeterminate.
,---
| 209) This includes, but is not limited to, the floating-point status
| flags and the state of open files.
`---

Returns
4 After longjmp is completed, program execution continues as if the
corresponding invocation of the setjmp macro had just returned the value
specified by val. The longjmp function cannot cause the setjmp macro to
return the value 0; if val is 0, the setjmp macro returns the value 1.

5 EXAMPLE
The longjmp function that returns control back to the point of the
setjmp invocation might cause memory associated with a variable length
array object to be squandered.

#include <setjmp.h>
jmp_buf buf;
void g(int n);
void h(int n);
int n = 6;

void f(void)
{
int x[n]; // valid: f is not terminated
setjmp(buf);
g(n);
}

void g(int n)
{
int a[n]; // a may remain allocated
h(n);
}

void h(int n)
{
int b[n]; // b may remain allocated
longjmp(buf, 2); // might cause memory loss
}

--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 15 '05 #2
Thank you for advice and information you provided.
I compile the program in Fedora core1 which runs in x86, and the
version of gcc is 3.3.2.
By the way, the program has been a minimal compiling example, and there
is no error to compile it in my system but a warning "indirect jmp
without '*' "
But I do not know what the warning mean.

Nov 15 '05 #3
"Zheng Da" <zh*********@gmail.com> writes:
Thank you for advice and information you provided.
I compile the program in Fedora core1 which runs in x86, and the
version of gcc is 3.3.2.
By the way, the program has been a minimal compiling example, and there
is no error to compile it in my system but a warning "indirect jmp
without '*' "
But I do not know what the warning mean.


Please don't assume your readers can see the article to which you're
replying. You need to provide some context so each article can be
read on its own. Google makes it unnecessarily difficult to do this
properly, but there is a workaround:

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

We don't know what the warning means either, because it doesn't refer
to anything in standard C. "__asm__" is not part of the C standard;
it's apparently a gcc extension.

You might try gnu.gcc.help.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #4

Keith Thompson wrote:
"Zheng Da" <zh*********@gmail.com> writes:
Thank you for advice and information you provided.
I compile the program in Fedora core1 which runs in x86, and the
version of gcc is 3.3.2.
By the way, the program has been a minimal compiling example, and there
is no error to compile it in my system but a warning "indirect jmp
without '*' "
But I do not know what the warning mean.


Please don't assume your readers can see the article to which you're
replying. You need to provide some context so each article can be
read on its own. Google makes it unnecessarily difficult to do this
properly, but there is a workaround:

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

We don't know what the warning means either, because it doesn't refer
to anything in standard C. "__asm__" is not part of the C standard;
it's apparently a gcc extension.

You might try gnu.gcc.help.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.


First, I am sorry. I did know it made so much trouble when I click
"Reply" link at the bottom of the article in google newsgroup.
I think I should redescribe the problem I met.
I wrote a program as follow:
#include <stdio.h>

typedef struct __myjmp_buf
{
int efp;
int epc;
}myjmp_buf;

int mysetjmp(myjmp_buf env)
{
int reval=0;
__asm__("movl %%ebp,%0":"=r"(env[0].efp));
__asm__("movl $1f,%0\n\t"
"1:"
:"=r"(env[0].epc));
return reval;
}

void mylongjmp(myjmp_buf env , int val)
{
__asm__("movl %1,-4(%0)\n\t"
"movl %0,%%ebp\n\t"
"jmp %2"
::"r"(env[0].efp),
"r"(val),
"r"(env[0].epc));
}

myjmp_buf buf;

int test()
{
int i=0;
i++;
mylongjmp(buf , 1);
return 0;
}

int main()
{
if(mysetjmp(buf))
{
printf("return success\n");
}
printf("pc:%x,fp:%x\n" , buf[0].epc , buf[0].efp);
printf("main address:%x\n" , main);
test();
exit(0);
}
When the computer execute jmp %2, and gives me a segment fault.
I do not know why the address I save is a invalid address, and wonder
to know what should I do if I want that mysetjmp and mylongjmp can work
like setjmp and longjmp.
My platform is x86, the system I use is Fedora core1, and I compile the
program with gcc.

Nov 15 '05 #5
Zheng Da wrote:

<snip>
First, I am sorry. I did know it made so much trouble when I click
"Reply" link at the bottom of the article in google newsgroup.
Please send a complaint to Google about the problems their interface
causes you and others.

Also, you don't need to quote everything, snip out the bits you are not
replying too.

<snip>
void mylongjmp(myjmp_buf env , int val)
{
__asm__("movl %1,-4(%0)\n\t"
"movl %0,%%ebp\n\t"
"jmp %2"
::"r"(env[0].efp),
"r"(val),
"r"(env[0].epc));
}
<snip>
When the computer execute jmp %2, and gives me a segment fault.


<snip>

I'm sure I've seen posts telling you that __asm__ is not on topic here
because it is a system specific extension and we don't deal with those.
Please ask about your problem in a GNU or Linux group, or possibly an
x86 group since this is x86 assembler.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 15 '05 #6
I'm sure I've seen posts telling you that __asm__ is not on topic here
because it is a system specific extension and we don't deal with those.
Please ask about your problem in a GNU or Linux group, or possibly an
x86 group since this is x86 assembler.


OK. Thank you all the same

Nov 15 '05 #7
Zheng Da wrote:
I wrote a simple one as follow:

typedef struct __myjmp_buf
{
int efp;
int epc;
}myjmp_buf;

int mysetjmp(myjmp_buf env)
{
int reval=0;
__asm__("movl %%ebp,%0":"=r"(env[0].efp));
__asm__("movl $1f,%0\n\t"
"1:"
:"=r"(env[0].epc));
return reval;
}

void mylongjmp(myjmp_buf env , int val)
{
__asm__("movl %1,-4(%0)\n\t"
"movl %0,%%ebp\n\t"
"jmp %2"
::"r"(env[0].efp),
"r"(val),
"r"(env[0].epc));
}

myjmp_buf buf;

int test()
{
int i=0;
i++;
mylongjmp(buf , 1);
return 0;
}

int main()
{
if(mysetjmp(buf))
{
printf("return success\n");
}
printf("pc:%x,fp:%x\n" , buf[0].epc , buf[0].efp);
printf("main address:%x\n" , main);
test();
exit(0);
}

When the computer execute jmp %2, and gives me a segment fault.
Why the address I save is a invalid address?
By the way, I want to find the codes of setjmp and longjmp in glibc,
but can not get it, and waht I find does not seem to be what I want.
How to find the codes of setjmp and longjmp which can run under Linux
and x86?
Thank you

1)
Your program will not compile
In the function "mysetjump" you declare "env" as a structure
"myjmp_buf" but you access it as an array.

2) You are passing the structure myjump_buf by value to the
function mysetjmp, so any changes or assignments done to that
structure are destroyed when the function returns. You are working
in a COPY of the structure

3) Do not use the embedded assembler of gcc. It is utterly
incomprehensible. Write setjmp like this:

mov 0x4(%esp,1),%edx ;save address of buffer in edx
mov (%esp,1),%ecx ;save return address in ecx
mov %ebx,0xc(%edx) ; save ebx
mov %esi,0x10(%edx) ; save esi
mov %edi,0x14(%edx) ; save edi
mov %ecx,0x8(%edx) ; save return address
mov %eax,0x1c(%edx) ; save eax
mov %ebp,0x4(%edx) ; save ebp
mov %esp,%eax ; save esp+4
add $0x4,%eax
mov %eax,(%edx) ; at the bottom of the buffer
xor %eax,%eax ; return zero
ret

I leave you the long jump routine as an exercise for the reader :-)

Nov 15 '05 #8
In article <11**********************@f14g2000cwb.googlegroups .com>,
"Zheng Da" <zh*********@gmail.com> wrote:
void mylongjmp(myjmp_buf env , int val)
{
__asm__("movl %1,-4(%0)\n\t"
"movl %0,%%ebp\n\t"
"jmp %2"
::"r"(env[0].efp),
"r"(val),
"r"(env[0].epc));
}


To be honest, implementing setjmp and longjmp is one of the things that
you shouldn't even try if you have to ask people how to do it.
Nov 15 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Thomas Baruchel | last post by:
Hi, wondering about: func1: setjmp() ; func2(); func2: {FILE *f; f = fopen(); func3(); fclose(f)} func3 : if() longjmp; else return; Note that FILE *fis a local variable in func2.
6
by: someone | last post by:
I have *thought* that setjmp/longjmp() should take a pointer to jmp_buf. And the calling function should hold the actual struct data. But ... I trid on both Win32 and Linux, it seems that...
12
by: Michael B Allen | last post by:
Should setjmp/longjmp really be used in a fast mundane ANSI C piece of code? Or is it frowned apon like goto? I have a need but I don't want to use something that is costly, isn't supported...
4
by: Jrferguson | last post by:
I have a C program that I am trying to port to a Motorola 68k based system. It makes use of setjmp and longjmp which are not supported by my C compiler. I understand the general principle behind...
5
by: candy | last post by:
hi all, Consider the following C code: void funct(){ }
20
by: JS | last post by:
When setjmp is called how can the if statement evaluate to true or false when setjmp only returns 0 or non-zero? struct pcb { void *(*start_routine) (void *); void *arg; jmp_buf state; int...
15
by: rover8898 | last post by:
Hello all, I used setjmp() in a recent of program of mine (it is not completed, so I have not the chance to test it out yet). I am not very profocient in C coding as are some of my co-workers....
4
by: nicho | last post by:
Could some knowledgable soul tell me if the following setjmp/longjmp structure will work from a logical standpoint ? The problem is that bar() needs to suspend processing and return control to...
5
by: Spiros Bousbouras | last post by:
In the following assume that a is int and env is of type jmp_buf a = setjmp(env) ; Is it legal ? It looks reasonable but it seems to violate what is mentioned under "Environmental limits" of...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.