.NET application crashes when capturing console close event only in Release build











up vote
1
down vote

favorite












I have a .NET application (.NET Framework 4) which monitors certain machines. I am capturing the console close event (actually CTRL+C) and ask the user if he/she is sure about it. In case the answer is yes, the application proceeds to run a method that closes open resources.
When running it in the Debug build it works fine, the problem is running it in Release mode, when CTRL+C is pressed, the application crashes and this event is shown in Window's Event Viewer.



 <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name=".NET Runtime" />
<EventID Qualifiers="0">1026</EventID>
<Level>2</Level>
<Task>0</Task>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2018-11-08T13:39:31.140511100Z" />
<EventRecordID>25125</EventRecordID>
<Channel>Application</Channel>
<Computer>this.computer</Computer>
<Security />
</System>
<EventData>
<Data>Aplicación: FooBar.exe Versión de Framework: v4.0.30319 Descripción: el proceso terminó debido a una excepción no controlada. Información de la excepción: código de la excepción c0000005, dirección de la excepción 0000000000E80B18</Data>
</EventData>
</Event>


Below I add the code I use to invoke the method that cleans resources.





enum CtrlType
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT = 1,
CTRL_CLOSE_EVENT = 2,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT = 6
}

private delegate bool EventHandler(CtrlType sig);

[DllImport("Kernel32")]
private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);
private static bool Handler(CtrlType sig)
{
if (sig == CtrlType.CTRL_C_EVENT)
{
DialogResult dr = MessageBox.Show("Seguro que quieres cerrar la aplicación?", "Confirmación de cierre", MessageBoxButtons.YesNo);
switch (dr)
{
case DialogResult.Yes:
Environment.Exit(0); // se ejecutará la limpieza y luego se cerrará la aplicacion
return false;
case DialogResult.No:
return true;
default:
break;
}
} else
{
DialogResult exitDialog = MessageBox.Show("La aplicación procederá a cerrarse", "Cerrando Supervisor", MessageBoxButtons.OK);
}
return true;
}
[DllImport("user32.dll")]
public static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags);

[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

[DllImport("kernel32.dll", ExactSpelling = true)]
private static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
#endregion

#region Methods
public static void Main(string args)
{
SetConsoleCtrlHandler(Handler, true);
Console.Title = GlobalConfig.Title;
Console.Clear();
DeleteMenu(GetSystemMenu(GetConsoleWindow(), false), 0xF060, 0x00000000);
ShowWindow(GetConsoleWindow(), 5);

//AppDomain.CurrentDomain.ProcessExit += new System.EventHandler(CleanBeforeExit);

init();
}

static void CleanBeforeExit(object sender, EventArgs e) { ... }


If I use the ProcessExit way it won't crash, but it won't execute my CleanBeforeExit method either.



Does anybody know how to solve this? I don't think the client (a really important one) would accept an application in Build config (or isn't it really important?).










share|improve this question






















  • I have try some build config, and your example work fine. Juste I have removed the line init();. What is the method init?
    – Orwel
    Nov 8 at 14:43












  • @Orwel Have you tried only Debug build? As I said in the post, the issue is in the Release build only. In the former it works fine.
    – Sergi Mascaró
    Nov 8 at 18:52










  • I have try in debug, realease, x86, x64, with/without optimization... It's work fine. But I have replaced init(); by Thread.Sleep(10000); to simulate a work.
    – Orwel
    Nov 8 at 22:23










  • @Orwel oh sorry I understood that you had tried debug build (my bad). Anyways, init() configures log4net and then there is more code in Main method, which runs the application. Did you try using .NET 4.0 ?
    – Sergi Mascaró
    Nov 9 at 8:12










  • I have test only with .NET 4.0. Can you post a minimal example to reproduce the crash? Maybe the problem concern machine/OS (I use Windows 10 Pro). Have you try on other computer?
    – Orwel
    Nov 9 at 14:00

















up vote
1
down vote

favorite












I have a .NET application (.NET Framework 4) which monitors certain machines. I am capturing the console close event (actually CTRL+C) and ask the user if he/she is sure about it. In case the answer is yes, the application proceeds to run a method that closes open resources.
When running it in the Debug build it works fine, the problem is running it in Release mode, when CTRL+C is pressed, the application crashes and this event is shown in Window's Event Viewer.



 <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name=".NET Runtime" />
<EventID Qualifiers="0">1026</EventID>
<Level>2</Level>
<Task>0</Task>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2018-11-08T13:39:31.140511100Z" />
<EventRecordID>25125</EventRecordID>
<Channel>Application</Channel>
<Computer>this.computer</Computer>
<Security />
</System>
<EventData>
<Data>Aplicación: FooBar.exe Versión de Framework: v4.0.30319 Descripción: el proceso terminó debido a una excepción no controlada. Información de la excepción: código de la excepción c0000005, dirección de la excepción 0000000000E80B18</Data>
</EventData>
</Event>


Below I add the code I use to invoke the method that cleans resources.





enum CtrlType
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT = 1,
CTRL_CLOSE_EVENT = 2,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT = 6
}

private delegate bool EventHandler(CtrlType sig);

[DllImport("Kernel32")]
private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);
private static bool Handler(CtrlType sig)
{
if (sig == CtrlType.CTRL_C_EVENT)
{
DialogResult dr = MessageBox.Show("Seguro que quieres cerrar la aplicación?", "Confirmación de cierre", MessageBoxButtons.YesNo);
switch (dr)
{
case DialogResult.Yes:
Environment.Exit(0); // se ejecutará la limpieza y luego se cerrará la aplicacion
return false;
case DialogResult.No:
return true;
default:
break;
}
} else
{
DialogResult exitDialog = MessageBox.Show("La aplicación procederá a cerrarse", "Cerrando Supervisor", MessageBoxButtons.OK);
}
return true;
}
[DllImport("user32.dll")]
public static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags);

[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

[DllImport("kernel32.dll", ExactSpelling = true)]
private static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
#endregion

#region Methods
public static void Main(string args)
{
SetConsoleCtrlHandler(Handler, true);
Console.Title = GlobalConfig.Title;
Console.Clear();
DeleteMenu(GetSystemMenu(GetConsoleWindow(), false), 0xF060, 0x00000000);
ShowWindow(GetConsoleWindow(), 5);

//AppDomain.CurrentDomain.ProcessExit += new System.EventHandler(CleanBeforeExit);

init();
}

static void CleanBeforeExit(object sender, EventArgs e) { ... }


If I use the ProcessExit way it won't crash, but it won't execute my CleanBeforeExit method either.



Does anybody know how to solve this? I don't think the client (a really important one) would accept an application in Build config (or isn't it really important?).










share|improve this question






















  • I have try some build config, and your example work fine. Juste I have removed the line init();. What is the method init?
    – Orwel
    Nov 8 at 14:43












  • @Orwel Have you tried only Debug build? As I said in the post, the issue is in the Release build only. In the former it works fine.
    – Sergi Mascaró
    Nov 8 at 18:52










  • I have try in debug, realease, x86, x64, with/without optimization... It's work fine. But I have replaced init(); by Thread.Sleep(10000); to simulate a work.
    – Orwel
    Nov 8 at 22:23










  • @Orwel oh sorry I understood that you had tried debug build (my bad). Anyways, init() configures log4net and then there is more code in Main method, which runs the application. Did you try using .NET 4.0 ?
    – Sergi Mascaró
    Nov 9 at 8:12










  • I have test only with .NET 4.0. Can you post a minimal example to reproduce the crash? Maybe the problem concern machine/OS (I use Windows 10 Pro). Have you try on other computer?
    – Orwel
    Nov 9 at 14:00















up vote
1
down vote

favorite









up vote
1
down vote

favorite











I have a .NET application (.NET Framework 4) which monitors certain machines. I am capturing the console close event (actually CTRL+C) and ask the user if he/she is sure about it. In case the answer is yes, the application proceeds to run a method that closes open resources.
When running it in the Debug build it works fine, the problem is running it in Release mode, when CTRL+C is pressed, the application crashes and this event is shown in Window's Event Viewer.



 <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name=".NET Runtime" />
<EventID Qualifiers="0">1026</EventID>
<Level>2</Level>
<Task>0</Task>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2018-11-08T13:39:31.140511100Z" />
<EventRecordID>25125</EventRecordID>
<Channel>Application</Channel>
<Computer>this.computer</Computer>
<Security />
</System>
<EventData>
<Data>Aplicación: FooBar.exe Versión de Framework: v4.0.30319 Descripción: el proceso terminó debido a una excepción no controlada. Información de la excepción: código de la excepción c0000005, dirección de la excepción 0000000000E80B18</Data>
</EventData>
</Event>


Below I add the code I use to invoke the method that cleans resources.





enum CtrlType
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT = 1,
CTRL_CLOSE_EVENT = 2,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT = 6
}

private delegate bool EventHandler(CtrlType sig);

[DllImport("Kernel32")]
private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);
private static bool Handler(CtrlType sig)
{
if (sig == CtrlType.CTRL_C_EVENT)
{
DialogResult dr = MessageBox.Show("Seguro que quieres cerrar la aplicación?", "Confirmación de cierre", MessageBoxButtons.YesNo);
switch (dr)
{
case DialogResult.Yes:
Environment.Exit(0); // se ejecutará la limpieza y luego se cerrará la aplicacion
return false;
case DialogResult.No:
return true;
default:
break;
}
} else
{
DialogResult exitDialog = MessageBox.Show("La aplicación procederá a cerrarse", "Cerrando Supervisor", MessageBoxButtons.OK);
}
return true;
}
[DllImport("user32.dll")]
public static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags);

[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

[DllImport("kernel32.dll", ExactSpelling = true)]
private static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
#endregion

#region Methods
public static void Main(string args)
{
SetConsoleCtrlHandler(Handler, true);
Console.Title = GlobalConfig.Title;
Console.Clear();
DeleteMenu(GetSystemMenu(GetConsoleWindow(), false), 0xF060, 0x00000000);
ShowWindow(GetConsoleWindow(), 5);

//AppDomain.CurrentDomain.ProcessExit += new System.EventHandler(CleanBeforeExit);

init();
}

static void CleanBeforeExit(object sender, EventArgs e) { ... }


If I use the ProcessExit way it won't crash, but it won't execute my CleanBeforeExit method either.



Does anybody know how to solve this? I don't think the client (a really important one) would accept an application in Build config (or isn't it really important?).










share|improve this question













I have a .NET application (.NET Framework 4) which monitors certain machines. I am capturing the console close event (actually CTRL+C) and ask the user if he/she is sure about it. In case the answer is yes, the application proceeds to run a method that closes open resources.
When running it in the Debug build it works fine, the problem is running it in Release mode, when CTRL+C is pressed, the application crashes and this event is shown in Window's Event Viewer.



 <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name=".NET Runtime" />
<EventID Qualifiers="0">1026</EventID>
<Level>2</Level>
<Task>0</Task>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2018-11-08T13:39:31.140511100Z" />
<EventRecordID>25125</EventRecordID>
<Channel>Application</Channel>
<Computer>this.computer</Computer>
<Security />
</System>
<EventData>
<Data>Aplicación: FooBar.exe Versión de Framework: v4.0.30319 Descripción: el proceso terminó debido a una excepción no controlada. Información de la excepción: código de la excepción c0000005, dirección de la excepción 0000000000E80B18</Data>
</EventData>
</Event>


Below I add the code I use to invoke the method that cleans resources.





enum CtrlType
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT = 1,
CTRL_CLOSE_EVENT = 2,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT = 6
}

private delegate bool EventHandler(CtrlType sig);

[DllImport("Kernel32")]
private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);
private static bool Handler(CtrlType sig)
{
if (sig == CtrlType.CTRL_C_EVENT)
{
DialogResult dr = MessageBox.Show("Seguro que quieres cerrar la aplicación?", "Confirmación de cierre", MessageBoxButtons.YesNo);
switch (dr)
{
case DialogResult.Yes:
Environment.Exit(0); // se ejecutará la limpieza y luego se cerrará la aplicacion
return false;
case DialogResult.No:
return true;
default:
break;
}
} else
{
DialogResult exitDialog = MessageBox.Show("La aplicación procederá a cerrarse", "Cerrando Supervisor", MessageBoxButtons.OK);
}
return true;
}
[DllImport("user32.dll")]
public static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags);

[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

[DllImport("kernel32.dll", ExactSpelling = true)]
private static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
#endregion

#region Methods
public static void Main(string args)
{
SetConsoleCtrlHandler(Handler, true);
Console.Title = GlobalConfig.Title;
Console.Clear();
DeleteMenu(GetSystemMenu(GetConsoleWindow(), false), 0xF060, 0x00000000);
ShowWindow(GetConsoleWindow(), 5);

//AppDomain.CurrentDomain.ProcessExit += new System.EventHandler(CleanBeforeExit);

init();
}

static void CleanBeforeExit(object sender, EventArgs e) { ... }


If I use the ProcessExit way it won't crash, but it won't execute my CleanBeforeExit method either.



Does anybody know how to solve this? I don't think the client (a really important one) would accept an application in Build config (or isn't it really important?).







c# .net events crash event-handling






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 8 at 14:04









Sergi Mascaró

58110




58110












  • I have try some build config, and your example work fine. Juste I have removed the line init();. What is the method init?
    – Orwel
    Nov 8 at 14:43












  • @Orwel Have you tried only Debug build? As I said in the post, the issue is in the Release build only. In the former it works fine.
    – Sergi Mascaró
    Nov 8 at 18:52










  • I have try in debug, realease, x86, x64, with/without optimization... It's work fine. But I have replaced init(); by Thread.Sleep(10000); to simulate a work.
    – Orwel
    Nov 8 at 22:23










  • @Orwel oh sorry I understood that you had tried debug build (my bad). Anyways, init() configures log4net and then there is more code in Main method, which runs the application. Did you try using .NET 4.0 ?
    – Sergi Mascaró
    Nov 9 at 8:12










  • I have test only with .NET 4.0. Can you post a minimal example to reproduce the crash? Maybe the problem concern machine/OS (I use Windows 10 Pro). Have you try on other computer?
    – Orwel
    Nov 9 at 14:00




















  • I have try some build config, and your example work fine. Juste I have removed the line init();. What is the method init?
    – Orwel
    Nov 8 at 14:43












  • @Orwel Have you tried only Debug build? As I said in the post, the issue is in the Release build only. In the former it works fine.
    – Sergi Mascaró
    Nov 8 at 18:52










  • I have try in debug, realease, x86, x64, with/without optimization... It's work fine. But I have replaced init(); by Thread.Sleep(10000); to simulate a work.
    – Orwel
    Nov 8 at 22:23










  • @Orwel oh sorry I understood that you had tried debug build (my bad). Anyways, init() configures log4net and then there is more code in Main method, which runs the application. Did you try using .NET 4.0 ?
    – Sergi Mascaró
    Nov 9 at 8:12










  • I have test only with .NET 4.0. Can you post a minimal example to reproduce the crash? Maybe the problem concern machine/OS (I use Windows 10 Pro). Have you try on other computer?
    – Orwel
    Nov 9 at 14:00


















I have try some build config, and your example work fine. Juste I have removed the line init();. What is the method init?
– Orwel
Nov 8 at 14:43






I have try some build config, and your example work fine. Juste I have removed the line init();. What is the method init?
– Orwel
Nov 8 at 14:43














@Orwel Have you tried only Debug build? As I said in the post, the issue is in the Release build only. In the former it works fine.
– Sergi Mascaró
Nov 8 at 18:52




@Orwel Have you tried only Debug build? As I said in the post, the issue is in the Release build only. In the former it works fine.
– Sergi Mascaró
Nov 8 at 18:52












I have try in debug, realease, x86, x64, with/without optimization... It's work fine. But I have replaced init(); by Thread.Sleep(10000); to simulate a work.
– Orwel
Nov 8 at 22:23




I have try in debug, realease, x86, x64, with/without optimization... It's work fine. But I have replaced init(); by Thread.Sleep(10000); to simulate a work.
– Orwel
Nov 8 at 22:23












@Orwel oh sorry I understood that you had tried debug build (my bad). Anyways, init() configures log4net and then there is more code in Main method, which runs the application. Did you try using .NET 4.0 ?
– Sergi Mascaró
Nov 9 at 8:12




@Orwel oh sorry I understood that you had tried debug build (my bad). Anyways, init() configures log4net and then there is more code in Main method, which runs the application. Did you try using .NET 4.0 ?
– Sergi Mascaró
Nov 9 at 8:12












I have test only with .NET 4.0. Can you post a minimal example to reproduce the crash? Maybe the problem concern machine/OS (I use Windows 10 Pro). Have you try on other computer?
– Orwel
Nov 9 at 14:00






I have test only with .NET 4.0. Can you post a minimal example to reproduce the crash? Maybe the problem concern machine/OS (I use Windows 10 Pro). Have you try on other computer?
– Orwel
Nov 9 at 14:00














1 Answer
1






active

oldest

votes

















up vote
0
down vote













I ended up solving it by using an EventHandler variable




static EventHandler _handler;



and



_handler += new EventHandler(Handler);
SetConsoleCtrlHandler(_handler, true);


instead of



SetConsoleCtrlHandler(Handler, true);





share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53209361%2fnet-application-crashes-when-capturing-console-close-event-only-in-release-buil%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    0
    down vote













    I ended up solving it by using an EventHandler variable




    static EventHandler _handler;



    and



    _handler += new EventHandler(Handler);
    SetConsoleCtrlHandler(_handler, true);


    instead of



    SetConsoleCtrlHandler(Handler, true);





    share|improve this answer

























      up vote
      0
      down vote













      I ended up solving it by using an EventHandler variable




      static EventHandler _handler;



      and



      _handler += new EventHandler(Handler);
      SetConsoleCtrlHandler(_handler, true);


      instead of



      SetConsoleCtrlHandler(Handler, true);





      share|improve this answer























        up vote
        0
        down vote










        up vote
        0
        down vote









        I ended up solving it by using an EventHandler variable




        static EventHandler _handler;



        and



        _handler += new EventHandler(Handler);
        SetConsoleCtrlHandler(_handler, true);


        instead of



        SetConsoleCtrlHandler(Handler, true);





        share|improve this answer












        I ended up solving it by using an EventHandler variable




        static EventHandler _handler;



        and



        _handler += new EventHandler(Handler);
        SetConsoleCtrlHandler(_handler, true);


        instead of



        SetConsoleCtrlHandler(Handler, true);






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 13 at 8:10









        Sergi Mascaró

        58110




        58110






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53209361%2fnet-application-crashes-when-capturing-console-close-event-only-in-release-buil%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Hercules Kyvelos

            Tangent Lines Diagram Along Smooth Curve

            Yusuf al-Mu'taman ibn Hud